Pragmatic Unit Testing in Java with JUnit
Learn how to improve your Java coding skills using unit testing. Despite it's name, unit testing is really a coding technique, not a testing technique. This book shows how to write tests, but more importantly, goes where other books fear to tread and gives you concrete advice and examples of what to test. Discover the tricky hiding places where bugs breed, and how to catch them using the freely available Junit framework. It's easy to learn how to think of all the things in your code that are likely to break. But the best part is that you don't need to adopt Extreme Programming, or Test-Driven Development, or change your whole development process in order to reap the proven benefits of unit testing, the pragmatic way.
Review By: Harmon Avera, Jr.
10/31/2005"Pragmatic Unit Testing (in Java with JUnit)," one of three volumes in the "Pragmatic Starter Kit" series, contains nine chapters and several appendices that provide a concise introduction to developing unit tests for Java-based systems.
Geared toward developers, the book starts with a chapter defining unit testing and why it should be done, and follows with a quick example that lets the reader consider and develop unit tests on a sample Java method. Once we've had a chance to use the tool, Hunt and Thomas take a step back and describe the pieces that make up the JUnit framework--such as "assert" methods, naming conventions, and per-test/per-run setup and cleanup. Then the authors present two chapters of specific suggestions on what to test and things to look for when testing boundary conditions.
Sometimes the unit under test requires a significant infrastructure or has non-deterministic inputs (e.g., database operations, Web servlets), so the authors devote a full chapter to explaining and using mock objects to solve this problem.
The final chapters cover some practical aspects of unit testing. They discuss the properties of good unit tests, where unit tests fit into a real development project (code location options, testing frequency, working with legacy code, etc.), and how testability can drive the design or re-factoring of the production code itself.
The appendices cover JUnit installation for both Windows and Unix-like operating systems, provide code for a JUnit test skeleton, discuss some issues and problems that often pop up with unit testing, and give an extensive list of Web and non-Web resources.
After the standard lecture about the "whys" of unit testing, they jump right into designing and writing tests for a simple but non-trivial Java method. It's easy to learn development tools this way: try an example, fiddle with it to learn what questions to ask an expert, and then use the answers to understand the framework and nuances of the tool. It's like having a mentor work with you on your first project using the JUnit test framework, constantly reminding you to think about what could go wrong and to test for it. At first, this can be an exercise in frustration because there's so much that could potentially be tested. Being pragmatic mentors, they point out that you can't test everything. The authors use this limitation to present some clever and useful mnemonic guides about what to test and to help us remember the properties of good tests.
I particularly appreciated the chapter on design issues. As the authors point out, one of the best ways improve system design is to answer, "How am I going to test this?" Designing for testability often leads to improvements such as less coupling between components, simple, well-defined interfaces, and localization of validation responsibilities.
I've read numerous books that discuss theories and ideas for testing. This book, however, provided me with succinct, useful advice for the real world. I would recommend this book to all Java developers, especially those getting started with unit tests. There is a companion volume that uses NUnit for C# developers.