by Chris Douce
by Kent Beck
Addison Wesley, 2001
Test Driven Development by Example is one of those books that I've been threatening to read for a while. From time to time I'm faced with writing code of a kind that I have never written before. I can usually come up with a solution (with varying amount of API reading and head scratching) but sometimes I'm not as confident in the solution as I would like to be.
To get over the feeling of uncertainty and following one of the ideas of Extreme Programming I have occasionally used two 'xUnit' modules - Junit to unit test some elements of Java programming, and nUnit to test some of my .NET code (apparently there's also something called HTTPUnit too!).
The idea of test driven development is that you write a test before writing the code. Here are some of the key phases: add tests (after learning about the requirements), run the test to see them fail, write the program code, run the tests again to see them succeed, then refactor to remove duplication. Sounds easy! But not all only types of system software can be written this way – you'll what I mean in a later paragraph.
My adoption of unit testing has always been based on pragmatics – the need to ensure that a series of functions are as correct as they can be. Plus, writing the tests within the code itself gives one great advantage: you write a form of test specification that also incidentally can be checked programmagically against your code. It must be said that my practice has always been of the 'test last' variety.
TDD by Example is divided into three parts, 'the money example', 'the xunit example' and 'patterns for test driven development'. My favorite part of the book is the third section: the part about patterns (the money example doesn't inspire, but I can see how it shows the ideas behind the tests very clearly).
The 'pattern' section is explicitly related to the idea of software design patterns in one section, but it would have been better called 'idioms' or 'tips' instead. These 'tips' encapsulate development heuristics or tactics that can be used to obtain a greater understanding of a code base. I can see the motivation for many of the 'red and green bar' patterns (ways to use the testing tools), but being an empiricist, I would have liked to have seen them grounded in firmer study.
TDD is clearly related to the idea of cognitive dimensions – particularly to viscosity. By adding tests you construct a parallel representation of your existing codebase. In doing so you increase its viscosity – you ensure that elements of the system are more reluctant to change. If you make a minor feature enhancement, the 'red bar' may indicate that you have violated the rules of the existing test cases allowing the compiler and codebase to protect you from yourself.
I have a favorite testing pattern and one that is clearly related to the notion of a 'secondary notation'. With the Broken Test pattern, Beck writes, 'how do you leave a programming session when you're programming alone? Leave the test broken.' His motivation is simple. Get the codebase to tell you what you were doing before you had to 'break off' to do something else. 'A broken test doesn't make the program any less finished, it just makes the status of the program manifest. The ability to pick up a thread of development quickly after weeks of hiatus is worth that little twinge of walking away from a red bar'.
The use of xUnit-based testing is essentially a simple and pragmatic idea. Whilst reading it there were some nagging questions that the author clearly acknowledges towards the end of the book: you can't test GUIs, distributed objects or database schema, for example. You certainly can't test the essential validity of your requirements – are you building the right product, for example (although you may be led to construct some tests that may help you to question them).
You can't currently use a 'test first' approach to determine how your software sits within a larger ecosystem of software products. Final pre-release or beta testing might be dependent on devices, operating system, web servers and virtual machine frameworks.
Beck throws down the gauntlet to us. Does TDD create software with reduced defects? 'Where do I get off claiming such a thing?', he writes. 'Do I have scientific proof? No. No studies have categorically demonstrated the difference between TDD and any of the many alternatives in quality, productivity or fun.'
One interesting thing about Beck's writing is that the book is filled with emotion. The preface refers to courage. Testing can reduce programmer stress and tests should be written 'until fear is transformed into boredom'. Another quote: 'having a green bar [on the test program] feels completely different from having a red bar… you can refactor from there with confidence'. Testing seems to be as much about the programmer as it is the resulting software artifacts.
I can't help but notice a growth in the number of studies that explore the phenomena that is Extreme Programming. I hope that as researchers tease apart elements of the XP ideals, they will also look into TDD, how it is being used and whether programmer's views change as they gain more practice.
Will I give the idea of TDD a try? Perhaps, but only on parts of a system that lend themselves to it. I think the idea of TDD is worth a look.
Do you know of a journal that may be of interest to fellow PPIG members? If so, please tell us about it. Interested in writing a review, or perhaps you are an editor and would like to introduce your journal to us? Please feel free to send them to us.