I rarely see much discussion of unit tests that acknowledges that they may not be appropriate in some contexts. But the cost/benefit function for unit tests is by no means trivial:
- For many kinds of code, building worthwhile unit tests is
extremely difficult. In my experience, the sophistication of the unit
test code matches the sophistication of the code it tests. For code
with a simple synchronous interface, and where the outputs are a
simple deterministic function of the inputs, unit testing will be
easy. When these conditions don't apply (that is, for code that is
hard to get right), unit testing can become much more difficult.
Even for "hard" code, unit testing is still possible, but the design must respect unit-testability. This can greatly increase the amount of work involved over the non-unit-tested case. If this level of difficulty is underestimated, the tests may end up ensuring very little, or being fragile, or creating an obstacle to maintainance and further development of the code covered by the tests.
- In a large OO program, much of the behaviour arises from the interactions between objects. Unit testing strives to test individual classes, and so does not help to find problems in these interactions. At best, it can ensure that the objects implement their sides of the relevant contracts correctly. But that may not mean very much in a design where groups of objects achieve more than the sum of there parts.
Because of issues such as these, unit testing might best be understood as a way of catching some bugs earlier, rather than as a way to reduce overall defect rates. Thus it can make the development process more predictable.
But comprehensive unit testing has high costs, and other forms of testing may be more appropriate for some projects, or some parts of some projects. It would be nice if there was less cheerleading of unit testing, and more analyis of the pros and the cons.