TDD Isn’t a Rule, It’s a Tool
You’ve maybe heard the advice: “Write your tests first.” This approach, called Test-Driven Development (TDD), and was talked about a lot more several years ago. It can be summed up simply: write a failing test → make it pass → refactor.
The idea is that your tests guide the design of your feature. Instead of writing code and then trying to cover it with tests afterward, you let the tests pull the code into existence. Done well, it can create cleaner architecture, and prevent bugs from slipping in because the tests you wrote are not actually testing what you think they are.
And it works well. Until it doesn’t.
When TDD Works Really Well
In my experience, TDD works really well when the feature is already clearly defined and you know how the feature should behave. For example:
- creating a user
- adding new API endpoints
- adding a filter to search results
When the logic is predictable, writing tests first forces you to think about the behaviour before touching the code. In these cases, TDD speeds development up because the failing tests guide development and once passing allow you to refactor and quickly test again to make sure the refactor did not break anything.
When TDD Can Actually Slow You Down
Not all features are easy to build and require several iterations before they feel right.
In those cases, strict TDD can feel like trying to write the instruction manual before you’ve figured out how the machine works.
While you of course can attempt TDD, you often will end up rewriting the tests over and over because the design keeps shifting. And once you’ve rewritten tests enough times, you might begin to question whether the tests were guiding your development—or just slowing it down.
What I’ve Found Works Best
For features that are still conceptually fuzzy, here’s a workflow that I thin works well:
- Build a quick concept first. Something minimal. Just enough to show the team.
- Get feedback early. Let others react to it and give their input.
- Refine the design based on that feedback.
- Once the feature feels solid, then write the tests.
I don't think that when you build features this way that you are loosing value of TDD. Your tests will still shape the final implementation; you’re simply giving the feature room to change before trying to lock in the behaviour.
Final Thoughts
TDD Is a tool and not a law. TDD has shaped the way I write software. But the more projects I’ve worked on, the more I’ve realized that it’s okay (and sometimes better) to delay writing tests until the feature has taken shape. There’s value in exploring, iterating, and understanding a feature before formalizing its behaviour in tests.
