For whatever reason, the web seems to periodically erupt in a debate over whether automated tests are useful. Bob Martin kicked off the most recent one with his post on how a lack of testing gets startups in trouble. There were rebuttals and discussions. Lots of opinions were expressed about testing in general and TDD in particular, ranging from “testing is the best thing since sliced bread” to “sliced bread is one of the leading causes of obesity in the United States” (I’m paraphrasing of course).
As is my custom, I will now chime in with my two cents. Enjoy!
tl; dr: Tests help safely refactor your code base in order to prevent inevitable code rot.
Fact of Life 1: All Code Will Eventually Turn to Crap
Most code bases rot. Over time they become more brittle and less maintainable. The cost of change goes up.
Back in the mid 1800’s, German Field Marshal Helmuth Von Moltke astutely observed: “no plan survives contact with the enemy”. Just replace “plan” with “code base” and “the enemy” with “changing business needs” and you’ll have a pithy quote describing what happens with code bases over time.
Now, there are surely exceptions which arise under specific circumstances. A colleague told me of one such code base. It actually improved with time and it happened because 1) the business domain was remarkably stable and 2) customers where technology companies who valued a clean code base and were willing to pay for it.
So yes, you may end up working on such a code base and that’s great. Most of us though are much more likely to deal with constantly changing business needs and clients who aren’t even aware of code quality, much less willing to pay for it.
On a separate note, code rot isn’t necessarily a reflection of the quality of devs involved. In other words, no matter how good the devs are, the code will eventually rot (though it will rot faster and more violently if your devs suck).
Fact of Life 2: The Only Way to Fight Rot is With Ongoing Refactoring
Ok, let’s play a game of good news/bad news:
- Bad news: all code bases rot
- Good news: there is an antidote
- Bad news: that antidote isn’t safe
- Good news: however, it can be made safe
- Bad news: but this requires an upfront investment
(I could go on like this, but I won’t)
Yes, unless computer scientists come up with some sort of breakthrough, the best way we know of today to fight code rot is with ongoing refactoring. Refactoring can take many forms: simplifying and consolidating previously laid patterns, removing duplication, clarifying logic, and so on.
Indeed, refactoring can be a powerful antidote to code rot. However, if not administered properly, it can have terrible side effects. Which leads me to tests…
Fact of Life 3: Automated Tests Make Refactoring Safer
Tests codify assumptions inherent in your code. That’s their primary value. If a change you make breaks those assumptions, tests should go off like an early warning system, letting you know about an impending crap storm heading your way.
Now, of course there are situations where tests cause pain. Pain like when changing a single line of code suddenly breaks two hundred tests and fixing them requires touching each one.
Such problems are a smell of a larger issue. Maybe your tests are too granular, or your code is too coupled, or you’re testing the wrong thing, or I don’t know what.
That said, complaining about how inconvenient it is to maintain tests is a lot like complaining about how inconvenient it is to brush your teeth. While you may be right, consider the alternative.
You don’t need tests if you don’t need to live with the code you wrote. This may well be the case for startups searching for a business model.
However, the second you decide to commit, it’s time to codify your assumptions with tests. Let’s just hope that it’s not too late.
You may also like:
Did you love / hate / were unmoved by this post?
Then show your support / disgust / indifference by following me on Twitter!