I've read a number of books about Test-Driven Development. There are a number of new ones, but most of them start with a clean slate where you're writing code from scratch.

Working Effectively with Legacy Code is different. It starts with the assumption that you already have a codebase that doesn't have tests and need to figure out how to start adding tests as you work on the existing codebase.

The book is organized into two sections. "The Mechanics of Change" are an introduction to TDD, tools, why you would want to do it, etc. The real meat of the book is the second section, "Changing Software". Each chapter in this section addresses a different question, such as:

  • I can't get this class into a test harness
  • This class is too big and I don't want it to get any bigger
  • We feel overwhelmed. It isn't going to get any better

And each chapter has a detailed discussion of the problem, the strategy or strategies you might use, and the tradeoffs involved. That last point is pretty important - the Agile community has more than its share of zealots, so there's a lot of dogmatic advice out there. This book is the opposite - the author has clearly spent a ton of time applying his techniques to real codebases, and there are lots of interesting discussions out there. Even if you aren't sold on the whole Test-Driven approach, there's a lot of content that will apply to general refactoring.

This is one of the best books I've read in the last few years. Highly recommended.