Test driven development
May 1, 2007
I got to meet Dr Laurie Williams this evening at the Agile RTP group. I’m not sure I can get her slides, or link to them, but if I can, I will. She presented quite a lot of empirical evidence regarding the benefits of test driven development. Lots of good questions about some of the practical aspects of implementing TDD in a group. Tony from Mediclick was asking questions which brought up the differences between ‘acceptance’ tests (for the end user or client) and ‘unit’ tests (for the developers).
She presented a few studies which demonstrated higher ‘quality’ code resulting from the TDD/”test-first” approach over other approaches. “What defines higher quality?” was an instant question, and rightly so. Less cyclomatic complexity and higher test coverage were some of the quality metrics used in that particular study.
One of the themes she hammered home early is that TDD is largely a design practice, not a testing practice. Forcing you to test up front will have a marked impact on the design of the code. It’s something I’m certainly aware of, as I suspect most people are. Putting it in to practice is another matter, and one I’ve recently failed on. I’m in the middle of a decidedly short mini-project, and even now, only 2 weeks in to it, wish I’d started with a TDD approach. The bigger issue I’d have had with that is having test data which accurately reflects how the system is used. Extracting a small portion of the data is possible, and I’ve been meaning to do it for a while now, but other “more important” projects seem to get in the way.
The take away from Ms. Williams’ presentation is that TDD brings increased quality with no long-term productivity impact. What I didn’t hear addressed - and I don’t normally hear this addressed at TDD talks - is how to you ensure you’re writing correct tests. Writing “enough” tests can be measured with code coverage tools, in most cases, but whether the tests accurately reflect the usage of the system is another question. I suspect this is where “art” vs “science” comes in to play, and the quality of tests is largely a function of the experience of the developer(s).
If you’re doing TDD with Logo, I think you’re supposed to use mock turtles.
Did you like this post? Buy me a hot chocolate!
Posted in 




May 2nd, 2007 at 10:15 am
Writing correct tests is a matter of only writing code that satisfies a failing test. It’s summed up in fail, code, pass, refactor, repeat. Using this methodology, your tests will always be correct for the functionality that is implemented. For example, if
sum($a, $b)is supposed to add two numbers, but your unit test only checks forsum(2, 2), then your code should only implementreturn 4;. Of course, that isn’t very useful, so you would want to randomize the generation of the numbers so you can test real results.That’s TDD at it’s heart. By testing first, then writing just enough of code to make the test pass, you’re insuring that your tests cover all of the possible areas that you expect your code to go. A dynamic language such as PHP does present a unique challenge, however. What happens when floats or strings are passed in? PHP will attempt to convert them into something intelligent for the addition, but you’ll probably want to test for that too. So in a dynamic language, there is a bit of “art” to it as you have to know how your target language will behave on the fringes and whether you need to worry about them.
Having a good spec to work from when writing tests is also helpful. In the case of
sum(), if the spec said “takes two integers and adds them together”, then one of the first tests to write is exception handling when non-integer values are passed in.