Pay It Forward

What to test in unit testing

Unit testing became popular with Kent Beck’s introduction of the JUnit testing framework for Java. But because the notion of “unit” isn’t precisely defined, it’s easy to test every blessed thing in one’s code, especially when engineering managers start to see bugs in code and start demanding that tests offer “complete code coverage”.

There are two big problems with writing tests for code coverage. First, there isn’t a useful definition of “code coverage”. One popular definition–touching every line of code in a file–is next to useless; the most rigorous definition–following every possible code path–is patently infeasible. Second, it provides no sense of proportion, no sense of what is and isn’t important in an application. So it’s not surprising that engineers have largely produced massive amounts of practically worthless lines of code in the service of code coverage.

This was the background against which James Coplien wrote his justly famous notorious essay, “Why Most Unit Testing Is Waste”. It’s worth a close read, but the main thing worth taking away is that unit tests are useful mainly for testing algorithmic logic, that is, for testing stateless functions that determine specific outputs from specific inputs. Everything else worth testing should probably go into an integration test.