This weekend, I've been puzzling against some of the tensions in test driven development; I suspect that the idea that just unlocked is going to be useful for a long time.
The high level fog looks like this: TDD is several separable ideas in a matching trench coats.
The primary idea is that testing should be a first class concern in our design. We demonstrate that our design satisfies the testability requirement by... writing tests. Or, alternatively, by asserting that our design is so simple that there are obviously no deficiencies.
After that, we start opening paint cans with screw drivers.
A separate idea that gets added in is the idea that we should use tests to specify the behavior of the system. After all, the system is already easy to test, and executable documentation is cheap to verify.
Furthermore, this practice serves as real feedback on the design -- if we try to specify a behavior, and discover that we can not, in fact, check it, then we can reject the hypothesis that our selected design is in fact testable, and take appropriate action.
An unrelated idea: that we should determine our implementation by introducing the constraints of our specification one at a time, making small changes to the code each time to ensure that all of the introduced constraints are satisfied.
This last idea is further refined by the idea that the small changes fall into a particular pattern: take the implementation used to calibrate the test, remove the duplication, then apply refactoring as necessary to clean up the implementation.
As John Ousterhout once told me, TDD prevents errors of comission, not errors of omission. It also falls down when gluing together multiple systems.
ReplyDeleteThanks for writing such a good article, I stumbled onto your blog and read a few post. I like your style of writing... 5 Modded
ReplyDelete