Many developers feel no shame when a production bug is found in their code. They ask 'why testers didn't find it?'. Microsoft developers eventually found out some bugs are impossible to spot for the testers. By 1989 the bugs became the developers' responsibility. Developers had to deploy "zero defects" to the Testers.
By 1986 Microsoft had explicit monitoring code build into their production code that alerted programmers about bugs. The two critical questions to ask about every bug are:
- How could I have automatically detected this bug?
- How could I have prevented this bug?
A Hypothetical Compiler
Fortify your Subsystems
Step through your Code
We should step through our code line by line even before finding a bug. We should step through every branch of code. As you step through the code, focus on the data flow. The gut reaction that stepping through the code will take too much time, is wrong.
Make your interfaces as clear and as obvious as possible. We should consider programmers which will use our interfaces. We should make the interfaces super-understandable, so there can be no mistake in using them. We shouldn't hide any error conditions. We shouldn't burry them into cryptic return values. We should always look for and eliminate flaws in our interfaces. We shouldn't write multi-purpose functions, but a separate functions for each use-case. We should use type-safety to our advantage. If we can, we shouldn't fail in the functions, we should return a reasonable value instead. Avoid boolean arguments. Write comments that emphasize potential hazards.
Watch for variable overflowing. We should be as accurate as possible. Being only close means being buggy. Functions should do one thing and one thing only. We should avoid using nested ternary operators. We should handle special cases just once. Eliminate unnecessary if statements. Always ask yourself 'how could I have avoided this bug?'
Treacheries of the Trade
We shouldn't rely on data or logic we don't own. If I write a function, I cannot rely on other function internal working.
Write code for an 'average' programmer.
The Rest is Attitude
Bugs don't go away. Either the bug report was wrong, or somebody else fixed it or the bug is still there, just not apparent. We as professionals, should determine, which of the 3 options was it.
We shouldn't fix bugs later. We should fix them first, before writing new features. We should always fix bug causes, not just symptoms. Don't implement non-strategic features. No features are free. Unnecessary flexibility breeds bugs.
Don't "try" solutions. Use the correct solution. Don't event suggest trying something. You should either know what to do, or you are not understanding the system properly.
Programmer testing of features should have priority over schedule. We should implement and test code in small chunks. We shouldn't test the whole thing at the end, because we will have tendency to cut on testing because of schedule.
Don't rely on testing groups to find your bugs. Don't blame testers to find your bugs. Even minor bugs which don't need to be fixed at all are disturbing - their existence is disturbing. How to prevent similar bugs in the future? Never allow the same bug bite you twice.
We should establish our priorities, like maintainability, performance, etc. and stick to them.