One of the essential features of Test-Driven Development (TDD) is that you write (failing) tests before you write production code.
Obviously, this confuses people. When I started out with TDD it confused me just like anyone else who first sets foot on this new territory. Does it matter when I write tests? Can’t I just write the tests right after writing the code? As it turns out, yes, it does.
The code design resulting from Test-Driven Development is radically different. You go about writing code with much more humility as far as your design skills are concerned: “Do I need this abstraction? I don’t need it to make the test pass. Let’s keep things simple and see what happens.” Over time, you will apply some refactorings where you see fit. Your design evolves, seemingly by magic.
Now try to explain this phenomenon to developers who never tried this. It feels like explaining object-oriented programming to your grandmother. Actually, I take that back – OO is much easier to explain. Communicating the purpose of TDD feels more like explaining role playing games to people who have never seen a role playing game.
Veteran TDDers coined the “TDD is a design technique” mantra
Since developers just did not see the benefit of writing tests before writing code, numerous well-meaning TDDers resorted to a little trick. They all started saying something along the lines of “Well, forget about the unit tests being tests, TDD is a design technique.”
Slowly, people started realizing that test-first produces different results than test-after, and that the tests written in the process are a means of evolving the system’s design. However, this started another movement of TDDers that would question the value of the tests as such – as if the regression test suite falling out of a TDD process were completely worthless! “Hey, I don’t care about checking tight boundary definitions for this accounting function – I want my unit test to demo my shiny new API design. It’s a design test dude, not a test-as-such”.
Time to back up
In my opinion, the “TDD-is-a-design-technique” mantra is starting to harm people – the less you care about the effectiveness of your tests (from a black box testing point of view), the less value they yield.
Writing good tests is a skill that is crucial no matter whether you test-first or test-after. However, the designs coming out of TDD sessions have been shown to have fewer bugs in various studies (with Nagappan et al. being quoted most often), so test-first contributes to quality, just like unit-testing-as-such does. Practicing Test-driven development and valuing old-school black box testing techniques at the same time is nothing to be ashamed of.