If you’ve encountered test-driven development (TDD), you may have encountered programmers who follow it with almost religious fervor. They will tell you that you must always write unit tests before you write code, no exceptions. If you don’t, your code will be condemned to everlasting brokenness, tortured by evil edge cases for all eternity.

This is an example of a common problem in programming: good advice by experts that gets turned into a counter-productive religion. Test-driven development is useful and worth doing… some of the time, but not always. And the experts who came up with it in the first place will be the first to tell you that.

Let’s see how expert advice turns into zealotry, and how you can prevent it from happening to you.

Expert advice becomes a religion

The problem with experts is that they suffer from Expert Blind Spot. Because experts understand the subject so well, they have trouble breaking it down into concepts and explaining it in ways that make sense to novices.

Thus the expert may say “always write unit tests before you write your code.” What they actually meant is this:

Write unit tests before you write your code. Unless it’s code that isn’t amenable to unit testing, e.g. because unit tests aren’t informative for this particular kind of code. Or unless it’s code that you’re going to throw away immediately. And technically you can write the test after the code, and then break your code and check the test is failing. But this is annoying and a bit more error prone so as an expert I’m not going to mention that at all.

A True Believer in TDD might start arguing with these claims. But consider that even Extreme Programming, where TDD originates, discusses types of coding where unit tests are unnecessary.

In particular a “spike” in Extreme Programming is an architectural prototype, used to figure out the structure of the code you’re going to write. Since it’s going to be thrown away you don’t need to write unit tests when you write a spike. You can see this visually in this overview of Extreme Programming; the Architectural Spike happens before Iterations, and unit tests are written as part of Iterations.

If you’re certain all code is amenable to unit testing, consider these two examples: unit tests aren’t very helpful in testing a cryptographically secure random number generator. And if the director of a movie has asked you write some code to 3D render a “really awesome-looking explosion” you won’t benefit much from unit tests either, unless you can write a unit test to determine awesomeness.

So if experts know unit-testing-before code isn’t always the right answer, why do they say “always write unit tests before you write your code”? Expert blind spot: they can’t imagine anyone would write unit tests when they shouldn’t.

To the expert, a prototype and code requiring tests are obviously very different things with different goals. But that isn’t so obvious to the novice listener.

The novice listener takes the expert at their literal word, and comes to believe that they must always write unit tests before writing code. The novice is now a True Believer. They tell everyone they know “always wrote tests before you write code,” and they try to do so under all circumstances.

Thus good advice turns into a counter-productive religion, with unit tests often being written when they needn’t or shouldn’t be.

Avoiding the trap

How can you keep this from happening to you?

If you’re an expert, make sure you explain the qualifications to your statements. Don’t say “always do X.” Instead say “you should do X, because Y, under circumstance A but not circumstance B.”

If you’re not an expert things get a bit harder. Consider that both the expert and the True Believer are making the same statement: “always write tests before you write code.” How can you tell whether the person telling you this is an expert or a True Believer?

You need to take every piece of advice and figure out when and where it does not apply. An expert’s assumptions will often be implicit in the topic they’re writing about, so that may give you some hints.

If you’re having a two-way conversation try to get them to qualify their statement: ask them to come up with the boundary cases, where this advice is no longer applicable. Bring up the cases you’ve found where their advice seemingly won’t work and see what they say.

An expert, given enough prodding, will be able to come up with cases where their advice isn’t applicable, and explain the reason why. But a True Believer won’t back down, won’t agree to any compromise: they know the The Truth, and it is absolute and unchanging.

Programming is a broad field, and what makes good software depends on your circumstances, goals and tools. There is almost never one answer that applies everywhere. Learn from the experts, but never become a True Believer.