Growing Object-Oriented Software, Guided by Tests (Addison-Wesley Signature Series (Beck))
Nat Pryceamazon.com
Growing Object-Oriented Software, Guided by Tests (Addison-Wesley Signature Series (Beck))
Never write new functionality without a failing test.
As John Gall wrote in [Gall03], “A complex system that works is invariably found to have evolved from a simple system that works.”
The fewer methods there are on an interface, the more obvious is its role in the calling object.
Wherever possible, an acceptance test should exercise the system end-to-end without directly calling its internal code. An end-to-end test interacts with the system only from the outside: through its user interface, by sending messages as if from third-party systems, by invoking its web services, by parsing reports, and so on.
We should be taught not to wait for inspiration to start a thing. Action always generates inspiration. Inspiration seldom generates action. —Frank Tibolt
When we notice that a group of values are always used together, we take that as a suggestion that there’s a missing construct.
We value code that is easy to maintain over code that is easy to write.1 Implementing a feature in the most direct way can damage the maintainability of the system, for example by making the code difficult to understand or by introducing hidden dependencies between components.
Loosely speaking, we use the message-passing style we’ve just described between objects, but we tend to use a more functional style within an object, building up behavior from methods and values that have no side effects.
Break up an object if it becomes too large to test easily, or if its test failures become difficult to interpret. Then unit-test the new parts separately.