Like most Californians, I am hopelessly pathetic when it comes to preparing for the rain:
- My windshield wipers are worn
- My tires are low on tread
- I never have an umbrella or raincoat handy
- I forget to take my canvas lawn furniture inside
But it all got me thinking about preparation, and wondering about how well I do at making my software ready for the rain. It's a metaphor of course, but there are lots of things that engineers can do to improve their own rainy day fund when it comes to their software:
- Go through your bug list (you do use a bug tracker, don't you?). Make sure each bug has a reproducible case, and is appropriately categorized and prioritized. Don't let your bugs linger. Try to fix them as fast as you can.
- Look at all the warning messages that your compiler issues. If the compiler allows you to configure the level of warnings (such as javac's -Xlint), turn it up to the max. Figure out why you are getting those warnings, and remove them.
- Find a good static analysis tool, and run it over your code. Figure out how to configure the level of warnings that it issues, and turn it up to the max. Figure out why you are getting those warnings, and remove them.
- Get somebody to review your code. Review bug fixes, review modules, review architecture. Everyone's busy and none will want to do this, so you'll have to bribe them. Pressure your boss to fund such bribery.
You can never have enough tests, and you never will. So you have to just steal bits of time and opportunities whenever possible to work on your tests:
- Whenever a bug report comes in, ask for a test. If the reporter can't easily provide a test, write one yourself.
- Whenever you report a bug yourself, always provide a test. It's the golden rule.
- If you've got nothing else to do (you do have those times, right?), write tests. Test your own code, test other people's code, it doesn't matter. More tests is good, and practicing writing tests will improve your testing abilities.
- Review your tests like you would review your code. Ensure that your tests are clear and simple, and that they describe what they intend to test, and (this is very important) ensure that when the test fails, that it's very clear what is wrong and why the test has failed.
- Test your tests.
- Reported issues always have repro scripts or test programs attached. If they don't, we keep trying to get one.
- Reviewers routinely review tests, and make comments or suggestions for improvements to make the test clearer, or simpler.
- When reviewing a patch and readying it for commit, reviewers routinely test the test, as well as examining the fix.
- We are extremely reluctant to accept a fix without a test, although we will often accept a test without a fix. That is, it's common practice in Derby-land to commit a new test to the trunk by itself. Sometimes, people will first check in a test, to make sure that the test itself is reliable and stable, then, later, they will check in the fix. The first version of the test that is checked in demonstrates the wrong behavior (with comments referencing the issue-tracking system); the later version of the test, which is submitted with the code change that resolves the problem, is adjusted to demonstrate the correct behavior.
Now, I'm off to find that umbrella in the garage...