After all the code has been written, the next step is to write a simple test driver or a few unit cases that provide a way to start debugging the new code. In the book “Writing Solid Code” by Steve Maguire, he suggests in Chapter 4 Step Through Your Code on page 76:
“The best way to write bug free code is to actively step through all new or modified code to watch it execute, and to verify that every instruction does exactly what you intended it to do.”
But, why should software developers bother testing their code at all? Why not let the testers do this mundane chore? Again, Maguire’s book provides an answer in the forward on page iv:
“But as the testing group got bigger, the development groups got more and more dependent on the testing group to find bugs. The development groups soon adopted the attitude that the testing group was responsible for finding all bugs. This led to such serious problems – slipped schedules, buggy features, incomplete features, even canceled products – that something had to be done. Many developers felt no shame if bugs were found in their code after the product had shipped. They’d ask indignantly, ‘Why didn’t Testing find that bug before we shipped?’ Testing should have responded, ‘Why did you put that bug in the product in the first place?’
Eventually, the developers began to realize that Testing can never find all of the bugs in a piece of software. The bugs might be in the design, or in the specifications, or in the analysis of the customer’s needs. And testers can’t do complete code coverage or path coverage in their tests. Bugs might be hidden in obscure and rarely tested code. Bugs can be temporarily masked by the operations of other parts of the program – or by the testing environment. These are the kinds of bugs that testers have a hard time finding. Because of these factors, a testing group will usually find only 60 percent of the bugs in a product.
The developers can bring more knowledge and tools to reviewing and testing the code. When the developers set their minds and their tools to it, they can find over 90 percent of the bugs in the code. If the developers give the responsibility for finding the bugs to the testers, the users of the product will find 40 percent of the bugs. If Development and Testing both work to find the bugs, the users will end up finding less than 4 percent of the bugs. And that 4 percent could be found by the users during the beta test of the product.”
I find that stepping though the code not only helps find bugs, but provides a chance to rethink how the code was written. If some code was written in the late afternoon into the early evening, then that code tends to be at least a little inferior to code written in the morning or early afternoon. Why? Because developers are human and get hungry, thirsty, tired, bleary-eyed, etc. Debugging the code the next morning line by line provides a chance to rethink that code and do some of the following:
1. Consolidate 2 or more patches of similar code into a method.
2. Refactor code out of a class that really belongs in another class.
3. Rethink and redesign how the code works to make it more efficient, elegant, and easier to maintain.
It is important to step through all of the code. The Microsoft Visual Studio debugger makes this easy to do because it provides a feature that allows a developer to specify the next statement to be executed. This can be done within the debugger by right clicking the line to be executed next and then selecting the menu item “Set Next Statement.” Of course the next statement set to be executed should be within the same function that is currently being executed. So, what this provides is the capability to step through one path of an if statement and then after that completes use the “Set Next Statement” to set the next line to be executed to the alternate path of that if statement.
Once a block of code has been stepped through once successfully, it usually should not be stepped through again. For example, once code through a loop has been stepped through, then breakpoints should be set at interesting points within that loop and the first statement outside the loop. After the code exits the loop and hits the breakpoint, then the developer should check various variables to make sure the loop correctly performed its task.
Sometimes it is somewhat problematical to test out error handling code. If the error path is initiated with an if statement, then it can be easily stepped through by using the “Set Next Statement.” Unfortunately, the debugger does not allow the “Set Next Statement” to a line within an exception handler catch block. So, to test exception handling code, some throw statements can be inserted within the function and a breakpoint set at the top of each catch exception handler. After the catch exception handlers have been tested, then the throw statements can be removed.
Some developers object to stepping through the code line by line. I don’t really understand why. When I first started out as a programmer, it was absolutely invaluable to me. Some developers object to the amount of time it takes to step through the code. But, with practice as Steve Maguire points out and I can confirm, it goes very quickly if there are no bugs. If there are bugs, then stepping through the code with a debugger is the most efficient and fastest way to find and correct them. When I hear developers complaining about the time it takes to step through the code, it makes me think that they have yet to develop the experience and skills necessary to debug their code quickly and efficiently.
A good practice is for the manager or group lead is to sit down with each of his developers and watch them step through the code to make sure they are doing it properly and efficiently. Some developers with many years of experience have never used the “Set Next Statement.” and thus are unaware of how to efficiently go about stepping through their code.