Agile teams often find that the closer the unit test coverage of their code is to some optimal number (somewhere between 75% and 85%, many teams find), the more agile their code is. Which is to say, it is easier for them to keep the defects in the code to very low levels, and therefore easier for them to add features, make changes, and still deliver very low-defect code every iteration.

After experimenting with different ways to keep test coverage up at those optimal levels, agile teams hit upon the practice of Test-First programming. Test-First programming involves producing automated unit tests for production code, before you write that production code. Instead of writing tests afterward (or, more typically, not ever writing those tests), you always begin with a unit test. For every small chunk of functionality in production code, you first build and run a small (ideally very small), focused test that specifies and validates what the code will do. This test might not even compile, at first, because not all of the classes and methods it requires may exist. Nevertheless, it functions as a kind of executable specification. You then get it to compile with minimal production code, so that you can run it and watch it fail. (Sometimes you expect it to fail, and it passes, which is useful information.) You then produce exactly as much code as will enable that test to pass.

This technique feels odd, at first, to quite a few programmers who try it. It’s a bit like rock climbers inching up a rock wall, placing anchors in the wall as they go. Why go to all this trouble? Surely it slows you down considerably? The answer is that it only makes sense if you end up relying heavily and repeatedly on those unit tests later. Those who practice Test-First regularly claim that those unit tests more than pay back the effort required to write them.

For Test-First work, you will typically use one of the xUnit family of automated unit test frameworks (JUnit for Java, NUnit for C#, etc). These frameworks make it quite straightforward to create, run, organize, and manage large suites of unit tests. (In the Java world, at least, they are increasingly well integrated into the best IDEs.) This is good, because as you work test-first, you accumulate many, many unit tests.