Have you written a book, a dissertation, or a report? If you prepare well, everything should be almost perfect until you need to submit it to the editor, the professor, or the supervisor. In fact, almost likely you will read the manuscript again and again, just to ensure that there is no silly mistake, from typos to missing figures, which can be spotted easily in the draft. Before the document is going through another stage of proof-reading, you want to know as early as possible if something needs some fixes.

Fortunately, the same “multiple layers of defense” strategy applies to modern software development. For example, even though the compiler will scream at you if your code does not make sense, there is no reason to skip fixing it, if you happen to see it on your editor. Many complex application requires a rigorous testing procedure, yet it does not harm anyone to run the application through a fast smoke testing first. In fact, by the use of git pre-commit hook, you can run the smoke test before the defective code gets landed in the repository.

The principles are summarized as:

  • If you screw up, you want to know earlier than later
  • The first layer should have the lowest cost and effort

For client-side web development, this approach can be a time-saving. When you are in the coding stage, ideally the editor or the IDE which you use would give an instant feedback whenever there is something suspicious. It does not need to catch all possible cases, it has to be just good enough to filter the most common mistakes. If you leak a variable and it pollutes the global, there is no need to launch the unit tests before it gets caught.

Using CoffeeScript/Dart/TypeScript? Verify the compiled JavaScript with a syntax validator (because those code generators sometime have bugs, too). If you don’t use strict mode properly, there is no reason to wait for the full-blown QA workflow which involve a dozen web browsers (possibly even cloud-based) to kick in and then tell you that something is wrong. If your template handling does not produce the right DOM element, there is no use of running the functional tests on a whole set of mobile devices.

Just like a bodyguard, your layers of protection can be very subjective. Newbies may want more aggressiveness so that they can reduce the mistake probability. A typical configuration of those layers may look like the following:

This also demonstrates that an overlapping functionality does not always mean a substitution. Many tools complement each other quite well. Just because you have 100% code coverage does not mean you can’t benefit from a blazing-fast syntax error checking. Even if you aim to support legacy browsers, it does not mean you exclude yourself from doing headless testing.

Everyone makes mistakes. Fix them quickly and move on.

  • Dan Sutton

    As Dijkstra said, the best defence against bugs is not to introduce them in the first place. Bugs involving syntax, compilation problems and so on are trivial: real bugs are more subjective, involving at a simple level things like getting the wrong results from a program; at a more fundamental and complex level, bugs include concepts such as inefficient algorithms which take too long to execute: these are the hardest to find, because they’re also the hardest to recognize: they’re bugs in the programmer’s thinking, not really in the programs.

    This sort of bug is harder to find: a program may work perfectly and produce the correct results every time… but be much slower than expected. The rule here is that if a program seems difficult to write, or becomes overly complex in one’s head to a level disproportionate to the simplicity of what’s trying to be done, then you’re probably doing it wrong: there’s almost definitely a simpler, more elegant solution to your problem. Trying to teach this is almost impossible: it requires the inculcation of proper lateral thinking into a person — and you can’t teach someone to be smart.

    As an example, go and write something (without looking it up on the internet first) to find the greatest common divisor of two numbers (for example, in the case of 111 and 239, the greatest common divisor is 37; in the case of 12 and 15, the greatest common divisor is 3). Try to make it as efficient as possible. Then, when you think you’ve got it as good as you can get it, go and look up Euclid’s algorithm. Then be amazed. I was.