Thoughts on testing and simplicity


Something that Sean said when were talking about code review in New Jersey has come into my head a few times recently, so this is my recapitulation and expansion of that point.

Whenever we change code, we take a risk that those changes don’t work the way expected, or worse, break stuff.

In order to control these risks we test our software.

Testing software means employing a variety of tools to validate our changes. Automated testing is one very powerful tool in our toolkit. But we should also never forget to do the most basic form of testing there is: check it works. Yes, “by hand.”

Keep in mind that automated tests, particularly unit tests, do an excellent job of verifying that the code you wrote conforms with your mental model of the problem. Unfortunately, they are very poor at verifying that your mental model of the problem is correct.

So, when reviewing code, and particularly when submitting code for review: be creative about how you test your changes. Actively try and invalidate your assumptions about the code. Poke it in ways it shouldn’t be poked. And above all: check it works.


I’m sure we would all agree that simple solutions are better than complicated ones. Of course, simple solutions are often harder to find, especially when requirements are (or seem) complicated.

Sometimes we’re “just” fixing a small edge case, or “just” adding one more branch to an already complicated piece of code. How are we to know when it’s time to take a step back and try to simplify things?

Of course, there is no answer to that question. It’s a trade-off between the value that the feature will provide and the costs associated with the code you wrote.

But always remember that most of the cost associated with the code is deferred — i.e. you didn’t pay it when writing the code, but you (or your colleagues) will pay it in the future.

Various attempts to analyse the costs of software estimate that maintenance accounts for between 50% and 90% of the total cost of ownership of software. That means that the right question to ask yourself is not “is the value of this feature greater than the cost I incurred writing this code”, but rather “is the value of this feature greater than 2× to 10× the cost I incurred writing this code”?

If the answer is “no,” then perhaps it’s time to take a step back and see if you can’t solve the same problem (perhaps in a different way!) by deleting some code, instead.