On the Psychology of Test Driven Development
Recently I’ve been doing my best to do Test Driven Development (TDD) with varying levels of success. I’ve made some observations, not about the methodology or the tools, but about it’s psychological effects on me and how I think about development, my motivation, my attention, and my boredom threshold.
There are lots of places you can learn about TDD from people who are far more expert than me so I won’t repeat it all here. All you need to know is that with TDD you first write the test, then you write the code, a reversal of the traditional model in which developers write the code then never quite seem to find the time or inclination to write the tests unless forced to by a QA department.
These are purely personal observations about me, YMMV.
Writing tests doesn’t feel like wasted effort
Writing tests normally feels like a waste of time. You’ve written the code, it works (you think), and writing the tests doesn’t make that code work any better. You might feel a bit virtuous, but it rarely feels truly productive.
Describing in unambiguous terms what the code has to do is great for clarifying the problem. By the time I write application code I have a clearer idea of the problem I’m trying to solve and how I’m going to solve it. While I’ve been consciously writing the test code my subconscious has been working on the application code behind my back.
It reigns in my natural tendency to complexity
“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you’re as clever as you can be when you write it, how will you ever debug it?” – Brian Kernighan
TDD encourages you to write code in small, simple, easily understandable chunks. Writing large and complex tests is hard, so I tend to write small test for small and simple changes. This acts as a break on the natural tendency many of us have to make things more complex than they need to be, trying to solve every problem in one go, and then spending three dispiriting days hacking away at some labyrinthine mess that even we don’t understand anymore.
The result is that when I screw something up it’s a heck of a lot easier to fix. The amount of new code is smaller, the scope of the error is well defined by which tests fail, and the information provided by those tests will give you a good indication of what’s wrong. All-in-all debugging has become a heck of a lot easier, and more enjoyable.
It gives me continuous positive feedback throughout the day.
Maintaining motivation, especially a dull project, can be pretty tough. My attention span can go to hell, and my boredom threshold drops.
Because I break my problems into chunks small enough to do quickly, often within five or ten minutes, I get repeated positive feedback as each small problem is solved. This gives a sense of momentum, especially on projects that have become a hard slog. It’s like the feeling you get from ticking off items on a to-do list, or clearing out your mailbox.
The tests themselves also give a boost by providing a finite end point for a piece of development: the change is finished when the test passes. At each step I’m building a small hurdle, and then get the satisfaction of jumping over it before moving on to the next thing, rather than focusing on a final end that might be months away.
Done right, it’s like walking on a high-wire with a safety harness and net
If you do TDD right (especially if you use continuous automated testing) you can code with abandon in the knowledge that you’ll be informed if you break something (most of the time). I can refractor at will, tinker with algorithms, and potentially replace entire sub-systems and implementations without fear of screwing up too badly. My regression tests will indicate if I’ve screwed up, most of the time. Of course nothing is perfect. But if you have good regression tests that run automatically and continuously you will find yourself a heck of a lot less stressed.
TDD isn’t a miraculous cure-all for all your development woes. Anyone who claims that their pet methodology/language/tool/framework/chair/diet/coffee-machine/alternative medicine is the answer to all your problems is almost certainly talking bollocks. But it definitely has it’s advantages.