Let’s drive straight in.
The name has two parts.
Test-driven emphasises writing tests before the implementation code. The tests can be anything. On occasion the tests aren’t even code (e.g. configs for health checks).
Development captures the idea that we’re introducing new behaviors into an existing or new system, or changing its structure to ease with maintenance and data flow.
It’s easy to forget the roots of TDD and the studies and flame wars surrounding software development. On the surface it looks like a tangled web of grit, hustle intertwined lucky habits and “it just works”-level genius. Nonsense!
Why first?
“We write tests first to have refactoring capability within the first iteration. This allows us to design and create features in two separate steps.“
—No-nonsense TDD Booklet, 2025 Edition
These two separate steps being:
make it work, get feedback (if important)
refactor, to make reaction to feedback cheaper (it depends, feedback can also prompt removal)
Why test?
Testing has a long-standing history of being split between capability and regression focus.
Capability Testing: tests are a codified acceptance criteria to verify that a feature story is implemented and behaving correctly
Regression Testing: captures behaviors that the devs did not expect, but users ended up replicating, capturing their intended resolution so as to not repeat old mistakes
TDD focuses on the Capability side. This side rubs shoulders with Smoke Testing, Component Testing, Unit Testing, Developer Testing, Performance Testing.
However, it is unrelated or orthogonal at best to Snapshot Testing, End-2-end regression testing (what one considers “simple QA”), Characterisation testing and Monitoring (self-correcting architectures).
Adoption pains
TDD requires a engineers to wear a business hat, or at least a product engineering one. A mode of thinking where we focus on the flow of serving customers / creating value. Not merely of technical precision and detail of writing code.
Ultimately this gradually increases the level of responsibility for their work that engineers willingly take upon themselves.
Adoption isn’t made plain and easy by doing more TDD workshops. That merely treats symptoms and in my experience makes adoption more costly long-term.
What makes devs take on the mantel of TDD usage is a mindset shift towards higher quality delivery and development, even when nobody is watching.
Such a transition requires them to accept the belief that self-testing, autonomously tested code is better than human inspection for matters of code design and correctness of behavior. But not aesthetics and overall architecture.