I got an email from one of my teammates yesterday asking me for some book recommendations on testing.  I’m glad that he didn’t just ask for books on unit testing, hopefully that means I’ve done a good job at emphasizing that it’s not all about unit testing.  Anyway, here’s my list of required reading on testing:

The Art of Unit Testing, Roy Osherove - At the time this was the only book to talk about the structure of unit tests and what made good tests versus bad tests.  To my knowledge this is still true and it’s #1 on my required reading list for developers.  The author sought to fill the gap between starting from scratch and the various works on Test-Driven development that were already out there.  This book doesn’t focus on TDD, it focuses on unit testing.  What makes a unit test, what makes one good or bad, and how to build suites of good ones.

Agile Testing: A Practical Guide for Testers and Agile Teams, Lisa Crispin - I’m a strong believer in breaking down the silos between the “development team” and the “testing team”, to the point where I hate hearing those designations.  For any team to be successful the entire team must be involved with everything from the beginning and this includes testing.  Nothing is done until it is tested.  This book shows that no matter what your designation is on the team that you have value to add to testing, and that testing early and often is necessary for long term success.

Growing Object-Oriented Software, Guided by Tests, Steve Freeman and Nat Pryce – This is the best book on Test-Driven Development I have read to date.  The examples and explanations of the whys and hows of test-first development, as well as the authors’ wisdom to focus on test-first at all levels (i.e. Acceptance Test-Driven Development combined with Unit Test-Driven Development) make a fantastic book to learn how to apply the test-first approach.  The authors focus on showing you that incrementally building your test suite while you add the functionality doesn’t have to be difficult or overwhelming.  It’s about repeating simple cycles of developing an acceptance test at the outer loop, watching it fail, then moving to the inner loop and developing a set of unit tests while implementing the actual functionality while working towards passing that acceptance test (and all the unit tests of course).

xUnit Test Patterns: Refactoring Test Code, Gerard Meszaros – I’ve gone through a great deal of this book, and while it has a wealth of information I honestly had a hard time finding places where some of the patterns could be applied to my test code.  That doesn’t make it a bad book by any stretch, however, and if you’re the kind of person that patterns speak to, this will help you find structure in what can sometimes feel like a daunting learning curve.  I find this as more of a helpful reference than required reading, but it’s still nice to have around.

Advanced Software Testing – Vol. 1: Guide to the ISTQB Advanced Certification as an Advanced Test Analyst, Rex Black – Despite the fact that this is a certification book, there is a lot of useful information in here about test analysis techniques.  Understanding these techniques and both where and how to apply them is necessary to be able to develop test suites that are “lean” in that they cover the necessary parts of your system without wasting effort through duplication or ineffective test cases.  The layout is a little chaotic, but if you can cut through the noise you’ll find the techniques indispensable.

Practice – Seriously.  This is the best way to learn the ins and outs, limitations and strengths of various tools in various language, as well as how to generally unit test various situations.  CUnit or Unity?  CppUnit or gtest?  NUnit or MBUnit?  CMock or mock-by-hand?  GMock or mock-by-hand?  RhinoMocks or Moq?  You can’t know to what situation each of these tools is best suited unless you’ve tried them (ideally on a real project).  But don’t try to master the tools, try to master the practice.  It will make you more valuable if you understand the foundations since you’ll be able to move between environments quickly with little ramp-up time.

There are no shortcuts to mastery, and as much as one would like to believe they’re special in the beginning (I’m sure I’ve been guilty of this), the 10000 hours can’t be faked.  Practice and you’ll get better at it, you’ll find the patterns, and you’ll be able to pick up most any tool like this and use it effectively.  But you need to develop the foundation to understand why you’re unit testing before it can evolve from just another mundane task to perform before something is “done” to being engrained in the very way you do your work.