How do you solve a software problem? How do they teach you to handle it in school? What’s the first thing you do? You think about how to solve it. You ask, “What code will I write to generate a solution?” But that’s backward. The first thing you should be doing— In fact, this is what they say in school, too, though in my experience it’s paid more lip-service than actual service— The first thing you ask is not “What code will I write?” The first thing you ask is “How will I know that I’ve solved the problem?”
I’ve written a lot of code. And recently, I’ve been trying this whole test-first thing out, and I’m really happy with the results. Everything they say in the article is true, and it makes a lot of sense, but I think the real benefit is far simpler:
Writing tests for code that doesn’t exist yet means that you come at the design from the point of view of a user with a specific problem, instead of the normal point of view of a coder trying to make his Brilliant New Solution™ that is both a dessert topping and a floor wax.
This plays into one of the other ideas XP expounds: Do the Simplest Thing That Could Possibly Work. Instead of trying to solve all the problems you might ever have, you tackle the problem at hand right now by writing a test that is the problem at hand right now, and deal with the rest later. Sometimes later is in a few minutes, sometimes it’s in a few days, and sometimes it’s never, but Test-First Programming lets you split those tasks down into more manageable chunks, and that’s huge.
Back when I worked at ParaSoft and was peddling Unit Test software, one of the biggest problems we found was this huge string of dependancies most code has built into it. In order to test class X, you need to create an instance of class Y to pass into the constructor. And Y, of course, needs a Z. But you can’t make a Z without an A and a B, which requires this environment property set just so. This seems insane because it is insane: no one sets out to write like this but every company I visited had code that looked exactly like this.
And it’s because they were trying to bolt unit tests on at the last minute. If they had tested first, they would have thought “This is insane. We didn’t set out to write like this” and they’d be right, and they’d fix it, and (key point) their architecture would benefit because they had to think it through before writing the code and “unit testing” with the compiler.
That’s the power of test-first: it makes you see the code from the vantage of the programming who’ll have to make use of it instead of the one creating it, and that’s the seat you’ll be occupying for most of the class’ lifetime, anyway.