Learning Test Driven Development With Kent Beck
With Barbaric Book Reviews I bring you interesting reviews and useful insights from awesome books that I have read. I also bring myself the magic of everlasting memory so that I don’t forget these tidbits of knowledge as I grow old and wither.
I have been doing TDD (Test Driven Development) for the past 4 years and yet I didn’t know that Kent Beck had written a book expressly devoted to teaching TDD. So image my surprise as I was browsing the interwebs for my next book-ish victim and I stumbled upon Test Driven Development By Example.
This is one of the most pedagogic and hilarious programming books that I have read. Imagine that you had the chance to learn TDD sitting beside Kent Beck in a pair programming session. Cool right? Well that’s how the book feels like. You and Kent will program side by side and test drive a multicurrency system in Java, and a testing framework in python (and yes, you will test drive the testing framework while using it to run your tests #inception #ftw xDDDD). And to wrap it all up, Kent summarizes and reflects about useful test patterns, refactoring heuristics and useful design patterns for both testing and refactoring.
I leave you with a quote that describes who TDD is for:
(...)TDD rests on a charmingly naive geekoid assumption that if you write better code, you'll be more successful. TDD helps you to pay attention to the right issues at the right time so you can make your designs cleaner, you can refine your designs as you learn.(…) TDD is also good for geeks who form emotional attachments to code. One of the great frustrations of my young engineer’s life was starting a project with great excitement, then watching the code base decay over time.
(…) TDD enables you to gain confidence in the code over time. As tests accumulate (and your testing improves), you gain confidence in the behavior of the system. As you refine the design, more and more changes become possible. My goal is to feel better about a project after a year than I did in the starry-eyed beginning, and TDD helps me achieve this.
Update 22th January 2015: So I was having a shower and my mind started wandering towards some of the interesting and surprising things that I had learned from this book that I hadn’t thought of or read about before. And I thought it would be nice to share them with you:
Start writing tests from the assert.
I have always followed the AAA (Arrange Act Assert) and I don’t know, it feels super natural to start from the beginning, so this was a super interesting proposition, to start from the end instead. Kent assures us that it has a simplifying effect, that it will help you focus on one problem at a time. He uses the example of communicating with a system over a socket. When we want to test that, what we want to achieve is to have obtained some data, and to verify that the socket is closed, so we write:
TestCompleteTransaction(){
...
// Assert
Assert.That(socket.IsClosed());
Assert.That(reply.Contents, Is.EqualTo("abc"));
}
And then we ask ourselves, where does the reply come from? and answer A socket of course, so we write:
TestCompleteTransaction(){
...
// Act
var reply = socket.read();
// Assert
Assert.That(socket.IsClosed());
Assert.That(reply.Contents, Is.EqualTo("abc"));
}
And we continue asking questions until we have our test. I have tried it a couple of times and I have mixed feelings about it. But perhaps the problem is the lack of familiarity XD.
Using TDD and Unit Testing To Learn New Libraries Or Frameworks
Another interesting concept was the use of TDD to teach yourself to use new libraries. The idea is to go get a new library that you want to learn, Install-Package LibraryXYZ
and you start writing tests against its API and exploring how it works.
Alternatively you could reuse those tests that you’ve written to learn the library to make sure that future updates play well with your own codebase (no unexpected breaking changes).
Red Green Ref… Remove Duplication
It is very remarkable that when Kent defines TDD he starts not by talking about the famous Red/Green/Refactor but about the two rules of TDD:
- Write new code only if an automated test has failed
- Eliminate duplication
(which then derives into the TDD Mantra of Red/Green/Refactor). And what it is very interesting about it, is that it is not only the duplication that you refactor out of your design in your production code, but oftentimes the duplication between your tests and your code. As you go through the TDD workflow you go removing this duplication: start writing a test, write the production code that provides the easiest/fastest solution to pass the test, which will probably be a hardcoded value and thus the duplication between test code and production code. So you remove the duplication to continue the TDD workflow until the arrival to the desired solution with no duplication, unicorns and rainbows. Another cool point of view that I hadn’t reflected about.
And that’s it! Have a nice day!
Written by Jaime González García , dad, husband, software engineer, ux designer, amateur pixel artist, tinkerer and master of the arcane arts. You can also find him on Twitter jabbering about random stuff.