There is, of course, only one real hazard – to fix a bug or make an enhancement and, in so doing, to introduce a new problem. The problem usually manifests itself in an area far away from where the changes have been made and so are easily overlooked. A disaster that will damage reputations!
So what to do to avoid a disaster?
Impact analysis – what else could be affected? Are the possible consequences worth the advantages of the change?
Test the system before you do anything – make sure that you completely know the behaviour of the current system before you do anything. That way you avoid chasing your tail looking for a problem that you think you’ve introduced but is in fact a feature of the system.
Source control – make sure you have everything saved that will enable you to return to the current build should a disaster occur.
Review the proposed changes – walk through the changes before doing anything. Two heads are better than one, especially one that been bashed against a wall of old, poorly documented code!
Change carefully – make sure that you are not overwriting data areas, mark all changes, check uniqueness of new variable names, understand inputs and outputs.
Test the change thoroughly – make sure the change is robust and provides the required functionality.
Regression test – make sure that the old functionality still works correctly. This is tedious and may have been done a number of times over the lifetime of the system. Automation will help (see Zircon’s ARTIST tool).
Document – you’re not writing an essay, just some notes to help the next person that will have to change things. It may well be you! Write down what you were trying to do, what you actually did, was the existing documentation any good and what you managed to find out. Eventually these notes will be better than the original document.
This advice has been learnt from bitter experience. I expect that I may be teaching my grandmother to suck eggs, but I hope that it helps someone.