Testing
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.
Simplicity
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.