By Michael Feathers, author of CppUnit. The book is very easy to follow, and there’re so many things he says that make me scream “that’s exactly the problem I’m facing!”
Part I. The Mechanics of Change
Legacy code is simply code without tests.
Change comes from adding feature, fixing bug, improving design (refactoring), and optimization.
To mitigate risk of change we need to know what changes we have to make, how we know we did it right, and how we know we didn’t break anything else.
Unit test traditionally is for individual function and class. A practical criteria is it runs fast (less than 0.1s), and localizes problem.
We need to sense internal values in code, and separate pieces of code into a test harness to run. We can use fake object in place of a real object for sensing. A more advanced type is mock object, which performs assertions internally.
A seam is a place where you can alter program behavior without direct editing. You instead change something somewhere else–an enabling point where you make the decision about behavior: use preprocessor, link different library, object seam (inherit/override).
Part II. Changing Software
- With little time, add tests without changing existing code.
Use sprout method and sprout class to encapsulate the changes. Use TDD to develop sprout.
Use wrap method and wrap class to wrap existing code. Existing method/class need to be renamed.
- Reduce average build time: use interface and package
- Add a feature: use TDD. Do not worry about duplicate code at first. Get it compiled and pass the test, then remove duplication.