One of my favorite quotes about programming is from Kent Beck: "I'm not a great programmer, I'm a pretty good programmer with great habits." And one of the best habits I know is to build your software using unit testing and test-driven development. I've found test-driven development with frameworks like JUnit and NUnit so useful over the years that I sometimes forget that someone had to convince me to give it a shot before I tried it for the first time.
Tomorrow at the Agile 2009 conference, Abby Fichtner and Nate Oster are doing a workshop called Where Does Developer Testing End and Tester Testing Begin?. Jenny and I hope you can make it, because they'll be doing a giveaway of autographed copies of our latest book, Beautiful Teams: Inspiring and Cautionary Tales from Veteran Team Leaders. It's a collection of essays by and interviews with some of the industry's biggest thinkers. There's one interview that I think is definitely relevant here, and I want to share a bit of it with you.
In our interview with Scott Ambler, he neatly encapsulates the sort of resistance that a lot of good programmers have to new, untested (to them) practices. In this case he's talking about pair programming, but what he said really rings true for me with respect to unit testing and test-driven development as well. Basically, Scott talks about how he's gotten improvement by talking it out with his team and making a deal to try pair programming for a month:
Andrew:... [T]hat begs the question for me: why is it so damn hard to get programmers to do it? Of all the practices, agile or otherwise, that I've had my own teams work with and talked to other people about, pair programming is the one practice that I've had an almost impossible time getting teams to adopt. It's even harder to get them to do that than to start doing automated unit tests and test-driven development.
Jenny: I think there's sort of this intuitive notion that having two people on the same thing is just inherently wasteful, and people just don't want to do it.
Scott: There's a lot of that. Also, people just aren't comfortable with it. There's something to be said for being at your desk by yourself, doing your own thing. It's interesting; pair programming's tiring. You do it for five or six hours, and you're exhausted, because you're actually working.
One of the things I do, and it's a bit harsh, is to really force the issue. My technique is that I'll bring the idea up with the team: here's what it's all about, here's how you do it. But it's hard. We'll talk it through, and talk about why it's hard. And what I'll get the team to agree to is to try it out for a month. We'll swap pairs on a regular basis--every day, you should work with someone new, not whoever you worked with yesterday. We're going to talk it out. We're not going to tolerate solo programming for that entire month. And at the end of the month, then we'll make the decision about whether or not we want to keep doing it. And what I've found is that by forcing the issue, and by really keeping people's noses to the grindstone, is that by the end of the month very few people want to go back to solo programming. But it takes a while. It's a "no pain, no gain" kind of deal--I'm sure there's other rhetoric, but sometimes you've just got to suck it up and do it. And pair programming is one of those things where you just have to force the issue for a while. Because it is uncomfortable at first. It feels strange, and for many people it's outside their comfort zone. So you've just got to do it. What I've found is that on the teams that choose to do it, very few--maybe 5%--of the people go back to solo programming. But it takes a month.
-- From our interview with Scott Ambler (Beautiful Teams, chapter 26)
I added emphasis to highlight what Scott said about how pair programming feels strange and is outside of the comfort zone for a lot of programmers, because I think that really underscores exactly why good developers resist great habits like pair programming and test-driven development. It doesn't matter how many books we read about them, how many success stories we hear, how many of our friends who we respect tell us to give it a shot. If we don't see for ourselves that it works for our own projects, we remain unconvinced.
If you don't already know the reasons that test-driven development is a good idea, a little Google searching will turn up plenty of good articles and blog posts reiterating them. And if you're not yet doing it but work with someone who does, you've probably already gotten an earful about it.
If, like me, and you're convinced that these practices make a lot of sense, then I think it's really important to take a step back and think about why we see this kind resistance, because it's natural -- and, in fact, it's a Good Thing™. There are a several good reasons that some great practices are out of a developers' "comfort zone." One of the most important is that these practices take extra time and effort. In pair programming, two developers are working on one computer, so it seems like you're spending twice the effort to write the same code. And building unit tests involves writing extra code that won't be delivered as part of the software.
Those are real, valid issues to bring up. As it happens, there are very good answers to both of them. As it turns out, in many (if not most) cases, those practices are "effort-neutral," meaning every hour spent recoups at least an hour later on in the project. And since they help programmers improve the quality of the final software, it means you get extra quality for free just by doing them. (I wrote a post on our Building Better Software blog a few years ago called Quality Really IS Free that talks a little more about this idea.)
But while it can be frustrating if you're the person trying to introduce the change, that resistance to change can actually be helpful in the long run. I've spent a lot of time talking and writing about change over the years: changing habits, changing teams, changing companies and organizations. And one thing that is always true is, like Tom DeMarco and Tim Lister wrote in Peopleware, that people really hate change. And it's absolutely natural for them to do so. So I try to put myself in the position of someone being asked to change how I build software at work. Today, I know I can do my job well. I know what's expected of me, and I know how to do the things I'm asked to do. But start changing things on me, and suddenly I'm not so sure. You promise that it'll be better after the change. But you're asking me to trade certainty for uncertainty. If that change fails, it's not just a threat to my project. It's a threat to my paycheck, and anything that potentially keeps you from being able to put food on the table threatens something really basic and human.
Now, I don't think anyone actually says to themselves, "I do not want to do test-driven development because it can interfere with my ability to feed my family." But any change that could potentially keep someone from being able to do his or her job is threatening on a gut level. And in a case like that, it's absolutely natural and normal to want to come up with a reason not to do it. And that's actually, not a bad first reaction to have, because while agile practices are generally really good, many of us have lived through all sorts of bad programming and management fads that we were right to resist.
Luckily, developers tend to be very practical people. When something works, we use it, and once we see evidence that a practice is useful many of the more emotional arguments fade away. Because these practices are so useful, it's really easy to convince someone: just get them to give it a shot, like Scott did. That's exactly what my friend, Chris, did for me years ago, and it completely changed the way I develop. At the time I had a set of very well-thought-out arguments about why test-driven development might work for him, but it simply didn't make sense for me. Once I started doing it, those well-thought-out arguments melted away. And since then, I've heard many of those same arguments many times over the years, and I have a pretty good feeling that each one of those people can become just as convinced as me. Because a funny thing happens when you see something for yourself: you become convinced, and you stay convinced.
You can read more of Andrew's posts at Building Better Software.