Recently I've been reading Growing Object-oriented software, guided by tests (Freeman & Pryce) and I thoroughly enjoyed it. I've been getting into unit testing and test driven development (TDD) lately and as such I am convinced TDD works and unit tests are vital to your application.
The only problem is, there is a lot of text on writing unit tests and there usefulness, but I haven't seen much fully worked out examples of a TDD cycle. This book provided exactly that!
First of all, the book uses Java for its extensive examples. If you've written anything in Java (even a reasonably sized school assignment works) you should be perfectly able to understand all code (heck I could and I haven't written Java in ages and never outside of school). If you've never written Java I assume you might have to look up some structures but if you're proficient in another language you should be able to understand the meaning of the code as well. In short, Java is not a reason for stopping to read this post or not buying this book!
It may seem strange but I'd like to start out with giving my opinion on this book: It is brilliant! If you don't like reading my post you at least know what you should do next: buy the friggin' book. The book offers some theory concerning agile development, (unit-)testing and code quality but its killer feature is the almost 200 page long example of developing an application the TDD way! In the rest of this post I will shortly highlight different parts of the books and stuff I enjoyed or learned from it.
Part I - Introduction
The book starts out with an expected introduction. It is not large though, the book is written for "the informed reader" by which the authors mean professional developers, so don't expect a lot of background information on the basics. This part offers two chapters which mostly help us establish the same vocabulary. A third chapter that shortly introduces the tools used while writing tests (JUnit, Hamcrest and jMock) concludes this part.
Part II - The process of test driven development
In this part Freeman and Pryce describe their take at test driven development. How do you start with a test driven development cycle if there is no existing system to add a unit test and then a feature to? What will you test first, where will you begin? Freeman and Pryce propose starting with an end-to-end test. This means building, deploying and testing a walking skeleton. With walking skeleton the authors mean the thinnest possible real slice of functionality that can be tested end-to-end.
What the end's are in such a test may differ. Sometimes you have no control outside of a defined scope (imagine creating a new feature in a huge legacy project), the scope in that case is the boundary of the end-to-end test. See it as one huge integration test if you will.
The authors stress the importance of not starting with testing and writing some model you are already sure you will need. It is important to know if your application will be able to interact with the outside world. You don't want to end up with a perfectly well unit-tested package that is not able to do anything because of wrong assumptions on the outside world.
My first real lesson
Ending up with such a tested package actually happened to me not so long ago. A customer wanted Form fields on a relations relation-card to be set to read-only based on the values of other fields in the same form. Our CRM package has a plug-in structure that allows other packages to manipulate these Forms and Forms are abstracted away in objects so I could set this up quite nicely. I decoupled the software entirely from the rest of the system and gave each well-tested class in the package a single responsibility. All in all it was a great experiment, until I needed the software to actually work inside the plug-in.
Apparently the Form manipulation plug-ins only fire before the data is set... Had I started with an end-to-end test, I would have started at collecting input from the plug-in first. I would have immediately discovered the fatal assumption I made was incorrect. I had no data available inside the plug-in so all my efforts where for nothing.
Luckily for me there was a work-around. This took me some time, but I hugely profited from the fact that I had decoupled the Form parsing and processing from the rest of the system. At least I hadn't done everything wrong :)
Part III - A worked example
As I stated before, this part is the unique selling point of the book. This is such an exhaustive example that completely covers all questions that you might have left after reading part II. I found part II informative and understandable, but the ideas in it only started "living" for me while I was reading trough part III.
The example deals with writing an auction sniper that tries to buy items at an on-line auction until a maximum price is reached or the auction is won. The example is well chosen and complicated enough to resemble an actual task you might have to work on while remaining understandable at the same time.
I can write all I want about this, but you'll simply have to read it to understand why I liked it so much.
Part IV and V - Sustainable test driven development / advanced topic
The last parts are a series of best practices and tips & tricks concerning the writing of unit tests. Consider it a parting-gift. Part IV deals with common situations like testing for complex data structures, naming inside tests and more. Part V deals with testing multi-threaded code, testing asynchronous code and the testing of persistence. These parts are certainly worth your time as well!
If you're convinced of the necessity of automated testing but you're unsure on how to start with actual test driven development, this is a very interesting book. If you're already actively developing using the test driven methodology, you still might like this book. It offers great value for money and is definitely worth your money.
I like your review of this great book. I feel pretty much the same about its content what you felt.
If you (developers) are on stage when you realized that testing is one of developer tools that you are missing and it makes a huge difference - this book is perfect for you.
Go - buy it, read it and enjoy it. :)