Source code comments vs. unit tests

By Abhijit Menon-Sen <ams@toroid.org>

2011-03-14

I've read many arguments about source code comments, from "comments are good, they help you understand code" to "comments are bad, they become obsolete and mislead you" and everything in between. I've seen enough good comments and bad comments to think that trying to draw a line in the sand is a waste of time. I write comments when I think they might be useful, curse them when they aren't, and find something else to occupy my attention the rest of the time.

Today, I happened across a blog post entitled Don't Waste Your Time Commenting Source Code. It's a fairly typical rehash of the usual arguments, written with much conviction and authority, but thankfully without the traditional "// Increment i" example. A couple of sentences caught my eye:

Contra: Automated unit tests explain what the program does just as well, and they never become obsolete.

I appreciate the argument that comments are unaffected by unintended code changes, while (sufficiently detailed) tests break immediately, but I have yet to see a good test suite that explained how a program worked just as well as good documentation. If the tests are a clear and straightforward explanation of how the program should work (which is not their function), they're not good enough at testing edge cases where the program breaks (which is their function); conversely, a thorough test suite has too much low-level detail to serve as a cogent exposition of the code's functioning. Not for a library, and certainly not for an application.

Besides, the "tests will break" argument is too simplistic. Test suites are also ultimately the product of fallible programmers. I've made many changes that were wrong but broke nothing. I've seen tests that blessed the entirely wrong behaviour. I've seen and made many changes that were not accompanied by enough tests, and others that came with lots of tests but were broken anyway. Every non-trivial test suite I've seen has been a complex maze of "historical reasons" and tests for long-forgotten (and always poorly-described) bugs rather than a clear explanation of anything at all.

Frankly, I would rather have developers spend time polishing their design skills than technical writing skills.

The way I see it, good design and good explanations go hand in hand. Neglecting one does no favours to the other.