Ah, the good old “Is TDD dead?” debate. Such fun.
I was listening to the same old arguments going round in circles, and I’ve heard them so often I was able to sit back and ponder, and had a couple of new thoughts.
(By the way, I should declare myself as a committed TDDer. I’ve seen the benefit and the pleasure.)
First, a lot of the benefits of TDD are actually the avoidance of bad practices. For example, TDD helps make code testable, because it leads you down a design path that has to be testable, because you’ve started with a test. However, once you’ve learned the sorts of things that make code testable or hard-to-test, and you’ve formed habits and instincts that avoid untestable code, is it necessary to write tests first in order to avoid untestable code? No.
That isn’t an argument against TDD. It’s an observation that the world of programming has moved on since the early days of TDD and maybe it’s time for the TDD books and tutorials and guides to stop presenting TDD as the solution to a problem but more as a mechanical means to solve a problem. An approach that, through practice, teaches you the skills you need to avoid that problem through insight rather than rule-following.
Second, rather than recommending that you should “write tests first”, I think there is a much bigger recommendation that speaks to a wider topic than the TDD debate: You should “put tests first”.
Put tests first in the sense of prioritising tests. Elevate tests to the most important level of significance. Care about tests more than anything else.
Write tests first. When you look at new code to try to understand how it works and what it does, start by reading the tests. When you do a code review or walk-through, start with the tests. When you begin a new feature, start by outlining the feature-level test scenarios. Make test quality the top priority for your team’s improvement process. Consider the tests to be the only reliable and meaningful specification of correct behaviour for your system. Give test code the same care and attention to clarity, expressiveness, robustness, precision as you would give to production code (though there are distinct differences in the range of important factors and the approach to satisfying them in tests versus code).
As one of my favourite Uncle Bob examples puts it, if all your production code was on one disk, and all your tests on the other, and the building is on fire and you can only save one disk, which one would you save?
Never mind the “should you write tests first” debate, the really important principle is that you should “put tests first”, above all else.
When you elevate tests to that priority, then you will lead and drive your entire development activity from tests at every level, in every aspect and in every stage.