TDD: Why is it so hard?
Mark Mzyk | January 10, 2008
In my previous post I told you I wasn’t going to write about TDD (Test Driven Development) in the near future. Well, as you can tell from the title of this post, I lied. I fully blame Chuck. If he had not blogged about it, it wouldn’t have festered in the back of my mind and been allowed to gestate into this post.
At work I can safely place TDD to the side for now, even though my boss would love me to practice it. At the moment I’m working in a large, ungainly legacy code base that does not lend itself to automated tests. This code base is about five years old but looks like it’s eighty. Code must age at about the same rate as dogs. Every one person year is at least seven code years.
But as soon as someone throws up an interesting blog post that applies to me I find I can’t stop thinking about it. It somehow infuses itself into my brain until I can cajole it out into useful thoughts or else it goes into hibernation, until I think of it at completely random times.
TDD and NADD (The Acronym Section)
So with TDD, I was wondering how it fit in with NADD (Nerd Attention Deficiency Disorder, another interesting blog post that has been sitting dormant in my head). TDD appears to me to both fit with NADD (which I admit to having) and to go against it. TDD fits with NADD in that it keeps me constantly shifting focus. Test, Code, Check, Repeat, with each cycle just slightly different enough to keep me interested, most of the time. Sometimes it does feel like drivel, but I suspect almost everything can feel like that at some point.
Yet TDD can also rip me out of the flow of coding, that small window of near euphoria where the code flies from the tips of my fingers and materializes on the screen as if miraculously incarnated from the ether. I’m a god, and my NADD has blessed me with an intense concentration I don’t want to be ripped from, sure as hell not for something as piddling as a unit test!
The Missing Piece
The trick is to make TDD feel so natural that it doesn’t interfere with the flow. I’m not there yet. I think I have a long way to go.
TDD was not something I learned in school. At least, that’s my opinion now. There was CSC 326, Software Engineering, which was somehow supposed to be the one class that taught me most of what I needed to know about the processes of creating software. I wrote unit tests for that class. I made the JUnit bar turn green. That’s about as much of TDD development as I got. I was sure I knew all there was and it wasn’t for me.
I know better now. I know enough to know that I know very little. Yeah, experience is a cruel mistress like that.
326 really taught me nothing about TDD. But, even had I been forced to write the tests first, to design off the tests, to follow the prescribed TDD method to the book, I don’t think I could have claimed I knew test driven development. Because there is still a piece missing:
Experience.
It’s a rather important piece. It’s the part that makes TDD work. With experience, as a developer, you can start to write a unit test and while you do that your mind uses it as a spring board. It leaps out into space, following all of the possibilities the test reveals:
Oh yeah, I remember doing something like this before…
Hey, this seems strikingly like …
This suggests a pattern I think …
What have I been smoking today …
Without experience, the pool is smaller. I lack the intuition to follow the best path, or the knowledge to quickly correct to it. So I end up writing a test which leads me down a path of coding and more tests, where I then have to fix the coding, then fix the tests, and the cycle repeats where I keep changing everything but progress nowhere because the way isn’t clear to me. TDD becomes a torture device and I pull the plug on it to end it all.
Those Who Came Before
Have you ever noticed that those who always seem to be pushing TDD are the developers who have all the experience? They wave their finger and in a stentorian voice admonish the junior developers around them, saying don’t make the same mistake I did. It is no accident that the experienced developers are the ones pushing TDD. They have the experience, so it works for them.
Sometimes you can’t learn from the mistakes of your elders. The lesson just won’t enter your brain until you’ve screwed it up for yourself. You might even have to repeatedly screw it up. And then screw it up some more before it starts to sink in. It takes learning by doing, not just by observing.
How to quickly accept TDD
I think there are two ways to come to quickly accept TDD.
The first way is have it forced upon you by your boss. This seems the quickest way to pick it up, because you don’t have a choice, or you appear not to. In reality, you’ll do as little as you possibly can to please your boss while slowly and painfully accruing the experience for the lesson to sink in.
The second way is to have an experienced mentor. But wait – I already hear your objections. Didn’t I just say that it takes experience to get TDD, and to just ignore all those thought leaders? Yeah, I did. If you want you can scroll up a bit, because it’s still there, in writing. This is a slightly different idea though, more in the paired programming vein. You do your work, and attempt to pick up TDD, but when you are royally fouling it up beyond belief, you’ve got your mentor there to step in and set you straight. You don’t have to fumble in the dark so much. You still have to fumble some, but at least you’ll learn how to find the correct path quicker.
Finding Heaven
What it ultimately comes down to is this: internalizing TDD. All the literature out there would have you believe that TDD is some process that all you have to do is adopt and it will lead you to the promised land. In reality, it isn’t. It’s more like a religion. You have to first find your faith and then perform the rituals before the promised land materializes. And unfortunately, there aren’t any good shortcuts to reaching Heaven.