Unit Tests and Creative Tensionby dws (Chancellor)
|on Sep 07, 2003 at 08:19 UTC||Need Help??|
Lately I've been doing a lot of Test-Driven Development (TDD), writing tests cases first as a way to explore APIs and document expectations, and then fleshing out the code behind the test case. Working this way, I avoid writing unused code. The tempation is still there ("hm... as long as I'm here, I should also write the mummble method, because I know I'll need that at some point..."), but taking things story by story, test by test keeps me honest. By staying honest, and working parsimoniously, I'm tending to notice more quickly when team members start to add unused code, but that's a different meditation.
The TDD cycle is to first write a test that expresses how you want a given thing (typically, a class or a module) to function. Since you haven't written anything behind the test, it will fail. Next, you write enough of a simple dummy implementation to get the test to pass. Finally, you replace the dummy implementation with real code. You're done when the tests pass. (I typically skip the second step, and go right to working code. TDD purists might shoot me, but it works for me.)
My habit in years past has been to only walk away from a development session once everything works. That's not always possible, but it's been the ideal. It's the "I'll sleep better knowing that I solved it" approach. With TDD, I'm trying something different. Instead of stopping once tests pass, I'll end a session once I have a test in place with no code to back it up. That is, I'll walk away with a failing test. And it's working.
The reason it works goes back to the idea of "dramatic tension". Writers have known for some time that it's a bad idea to walk away from a writing session right after you've resolved all of the dramatic tension. You might feel good, but chances are you'll stall out when facing a blank page the next morning, because your subconcious has had a chance to relax. If instead you stop in the middle of a crisis, say, when the protagonist is facing down a bear but has just realized that his revolver isn't loaded (or that he's not wearing any pants), your subconcious is going to thrash the problem over all night, looking for a way to resolve the tension. When you pick up the story the next day, your mind will have throw out fresh ideas, and you're quickly into it without stalling.
I've found that coding is like that, too. Unless there's unresolved tension, facing a blank screen in the morning--trying to decide what do do and how to get started--is really hard. I'm easily distracted. While trying to figure out what do to, I'll check email. Then, two hours later, I'll wonder what the heck happened. But if I leave myself one new failing test case, my mind will have kept cranking overnight, and I'll start the morning with focus. I'll write the code to get the test case running, which gives me momentum that carries on into the next problem. Leaving the tension unresolved overnight so that my mind keeps generating ideas and options helps provide instant focus, quickly overcome morning starting friction. And I'm not sleeping any worse than normal.
Kent Beck recommends something like this in the back of one of the XP books. He warns that this trick works well when you're working on a solo project, but doesn't as well when you're pairing or on a team project. My experience supports the former claim, but the book is still open on the latter.
Do you do anything like this? How does it work for you?