You shouldn't unit test (but you have to)

At my work, I’m tasked with being the unit testing advocate: I promote unit testing across the development department, I help solve unit testing problems and I mentor developers who are new to unit testing. This puts me in a funny position because–if I had a choice–I’d tell people not to write unit tests at all.

If I had to sum up why, I’d paraphrase Winston Churchill’s quote about democracy:

“Unit testing is the worst form of software QA, except for all those other forms that have been tried from time to time.”

The primary purpose of unit testing is to give us confidence that the programs we write match the specification of the system being built. If you’re a TDD practitioner, then you do this by writing your specifications in executable form as unit tests. The problem is that when we’re writing a program, we’re already writing an executable description of the system. Writing unit tests will inevitably either involve repeating yourself, or splitting that description across the code and the tests.

We wouldn’t do this if we could prove the code was correct. If we could do that, we wouldn’t write unit tests at all. A lot of my “unit testing time” is spent thinking about how to avoid writing unit tests using the static verification tools we do have at our disposal.