On learning practical TDD

by

If I had to sum up my last two years of experience as a developer, I would say using dependency injection to write code that can be easily tested would be the most important thing I've learned. And the single most important site that kicked it off for me would be the one from Misko Hevery, where he teaches how to write code that is easily testable. (If you haven't read all his articles and seen all his videos, please do so. It will change the way you look at code.)


The next logical step is to adopt Test Driven Development, or Test Driven Design. This is about letting the test cases drive the design of your software. The benefits of TDD are well documented, it's been proclaimed as the best way to build software. (Well, it isn't appropriate for all kinds of software, like implementing algorithms. Refer wikipedia for criticism of TDD.)

It is widely believed that the best way to learn TDD, is to pair with someone who already does it. But where does that leave people in non-agile companies? The whole point of this post is to share my experience on how I'm going about learning this agile technique.

Step 1 would be to go through the classic by Kent Beck, "Test Driven Development: By Example". This book teaches the absolute basic techniques that help a developer think in TDD terms. Kent goes step by step, refactoring at each step, even sharing with us his thoughts on why he thinks a particular refactoring is required. Please note that knowledge of refactoring techniques is another requirement for TDD. To put it simply, refactoring is the disciplined process of removing duplication from your code, and improving its structure.

But the problems that Kent solves in his book, is in the context of a maintenance project. If you were to start with a new project, trying to apply TDD, this wouldn't be enough, since, it seems that Kent is working with a project that is already covered with a test case harness.

Another book, Growing Object-Oriented Software, Guided by Tests, by Steve Freeman and Nat Pryce, takes us further and applies TDD in the real world. I'm still going through this book, but its already helping.. for instance we learn that a real TDD process begins with an acceptance test. This makes sense as it forces us to set up the infrastructure in the first iteration of the project, surprises if any will be encountered early on, giving more time to tackle them. More on this when I'm done with this book.

The book by Jimmy Nilsson, Applying Domain Driven Design And Patterns, looks at these techniques from the .NET perspective. The fun part is where he tries to mix up DDD with TDD. The way he goes about his sample problem, tells us that there is a lot of to and fro when using TDD. We take a step, another, and see a problem or sense a code smell, and then we start backing up from the steps we just took. Also, he, kind of, blasts the notion that there is no upfront design when applying TDD. There is some design, but we don't spend too much time thinking about it, so it isn't the big upfront design that was seen in the classic waterfall. The point is not to invest too much time in the design because surprises are inevitable.

For those who like live action, Brett Schuchert from Object Mentor, has posted videos that demonstrate TDD in both java and C#.

Learning the difference between mock objects and stubs, and practicing Mocking techniques with at least one good mocking framework ( The current favorite that is getting coverage in many blogs is Mockito but it still doesn't have a lot many users, the previous one was Easymock, and has better documentation and will be easier to use since many books show how to use it).

As of now, I'm hitting the stage where I can write some tests and the code, but the tests seem to be a burden because every time the code changes, making the tests confirm to the changed code become a nightmare. I know that brittle tests is a big problem, test code should actually be the easy part, and it probably implies that the code is not easy to use and has smells... the warning here is : don't go applying the test first approach in the workplace right away... spend some time practicing TDD before applying it at the place where you work, because it can take a lot of time, everytime you are stuck, it will be hard to get help in a non agile firm.