Cover - Test-Driven Development by Example

Author: Kent Beck
Publisher: Addison Wesley

I expected this book would be a good choice to follow The Art of Unit Testing, which I read and reviewed recently. I was not wrong! The previous book established a foundation in unit testing, and this book makes use of that knowledge to write tests which drive code development.

When I first saw the book, it was suspiciously slim. However, Test-Driven Development (hereafter referred to as TDD) does not seem to be a huge subject, and therefore does not need a huge tome to get you started. And besides, this is a starter book on the subject. Reader reviews have been very positive for this book, and I decided to pick it up and start reading it. I am glad I did.

Broadly speaking, the book is divided in four portions: three sections and the appendices. The first portion, the largest one, spends time on the classic money example. It involves TDD of a money class, and related classes, to provide functionality in adding and subtracting money amounts, as well as converting from one currency to another. The example seems trivial at first, however it does go into enough depth to start the mental wheels moving and get the reader started on TDD. This running example shows code samples in Java.

Something that stood out for me was that the end of each chapter has a list of tests that were written during the chapter, and also lists new/changed tests that have been thought of along the way. I like this idea – I think I may need to stock up on post-it notes!

The second section is a shorter one, but centres on a more involved subject: xunit, a unit test framework. The reader is walked through implementing basic functionality in a test framework; this is an interesting read, and I think I will have to give it a try myself as a coding exercise. Curiously, this section breaks from the previous in that code samples are shown in Python instead of Java, but this was not a problem for me. The samples were still quite readable, even though I do not know Python. This section covers a few scenarios for the subject – xunit – but I wish it went further.

The third section is essentially a grab bag of tips and reflections on the technique and benefits of TDD. Refactoring, design patterns, and test patterns all get attention here. It seems like a collection of information related to discussions in the two running examples.

One thing that keeps getting mentioned throughout the book is red, green, refactor. The meaning is that you shouldn’t write real code until there is a failing test in place to anticipate that code. Then, you can write the code however you want, committing whatver coding sins are necessary to get the test to pass. When the test passes, you can then review the code you just wrote and do any refactoring or other cleanup that is needed. You already have a test in place, so you’ll find out quickly if anything broke as a result of the changes.

There are two appendices; one describes influence diagrams, which is a useful subject but tangential to the main focus of the book. The other appendix briefly outlines the fibonacci algorithm, and suggests how to implement it in TDD fashion. I actually did this exercise before reading the appendix, and the process revealed to me the utility of TDD. I think this would have been more useful as a first example at the start of the book, rather than being tucked away in an appendix.

Reading this book, and trying to test-drive code, has been an eye-opening experience for me. Previously, I did unit tests after writing code to verify the same. Having gone through this book, I begin to appreciate the feeling of control you get when you let your tests drive the design of the code. By writing the tests first, you are designing your target code. Seeing the green bar is very satisfying.

A big takeaway is that TDD is not about the tests, it is about the design. The tests provide a way to establish the design. And, as a nice side effect, when you have finished writing your code, you will have a nice suite of unit tests to match.

Except for very basic “spike” code, I don’t think I shall ever again write code without having written the tests first!

This book is probably not for someone who has no experience in unit testing. It makes use of unit testing, of course, but does not spend time explaining the purpose of such. That is a subject for another whole book. This book is focused on TDD, of which unit testing is a part. Also, TDD is not covered in huge depth – this is a starter book, after all. The two running examples – money and xunit – show how to get started with TDD, but do not go into much depth.

The bottom line: this is a good book for getting started with TDD. It starts with the very basics, explaining the reasoning behind the process, shows how to do it, and describes the benefits of the technique. Yet the book’s slim size does not overwhelm the reader, and, indeed, gets the reader doing TDD in short fashion.