Experienced agilists talk about becoming “test infected.” For everyone, unit testing starts out as a chore that seems like it’s more work than it’s worth, but then you get over a certain hump and suddenly unit testing is a breeze. The benefits become manifold and profound, and you begin to wonder how you ever programmed without it.
One important milestone on the way to achieving test-infected enlightenment is the transition from test-after to test-first. All developers start out writing the production code first and then write unit tests around it. It’s the only way we learn. But, eventually, we begin to see the power of writing the tests first. This used to be called Test-Driven Development, but it’s more accurately referred to as just Test-First Development (although we still abbreviate it as TDD).
For me, the greatest thing about TDD is that it gets the subjective part of the problem out of the way early, leaving just the objective part to puzzle out. “Okay, now that we know what we need to accomplish, we just have to get it to work.” It’s a rather liberating feeling.
Programming is a creative endeavor, more art than science. A lot of design work still happens just-in-time during the coding phase. So, in the case of test-after development, the sequence is design-code-test, while with TDD it’s design-test-code. I would argue that such a mental shift promotes better abstract thinking during the design step, because the design occurs when thinking in terms of the testing needs rather than when thinking in terms of minutia of production code. The act of coming up with test cases is a much more generalized/abstract thought process than the act of writing executable production code.
Llewellyn Falco and Michael Kennedy are a couple of .Net developers who often team up to teach agile development techniques. They touch on this subject in their own way when they talk about writing units tests in “plain English” first (see their Pitfall #2 here: http://www.michaelckennedy.net/blog/2009/08/08/ArticleAvoiding5CommonPitfallsInUnitTesting.aspx). It’s the same thing — determining what to test in terms of conversational, high level concepts first. Be sure to keep reading, by the way. Their advice on avoiding other pitfalls of unit testing is sound.