Stop Monkeying Around with Debugging
Debugging should be approached as a mystery which will be interesting to crack. Solving that mystery should be done systematically by using every tool at our disposal, like debuggers.
Debugging is not just a good idea; it’s a necessary step in the software testing process. Using the Debugging Tool in Test Automation IDEs allows you to verify that your test automation code is working, and to pinpoint bugs, as indicated by error messages, that you need to locate and resolve. Also, it’s much faster to pinpoint bugs when you can examine the program’s state at any particular point in time. The most common kind of debugging is called “print debugging” and involves outputting messages to console, log files, etc., that the programmer then analyzes after running their code.
While each debugger works differently, there are some general steps that should be taken.
1. Peruse the Stack Traces to find a particular action. Stack Traces indicate the path of the code. From a stack trace, you can figure out where the issue(s) started occurring, and know where to focus your search.
It is important to note that not all errors will cause a stack trace to be generated, especially when utilizing languages that do not have support for exception handling. In that case, you can use print debugging to pinpoint where actual values do not match expected. By determining the location that has the incorrect code output, you can use breakpoints to narrow down your search.
2. Utilize Break Points to stop the code. Breakpoints are indications to the code that the program should stop running so that you can direct your attention to a certain area of code.
Some debugging tools allow the usage of conditional breakpoints, which allows you to stop the program at a certain point under a specific condition. This is useful if the code only fails for some input values and saves the coder from trudging through code that does usually work.
3. Examine your variables. After the breakpoint has been sprung and the code has stopped, you need to examine the code around that breakpoint to examine your variables and try to understand what went wrong. Diagnosing what went wrong is dependent on you understanding your code and variables. It depends on error messages, understanding the logic flow, and understanding the expected results. This is important because some bugs may not produce an error message, but you still get incorrect results.
More generally, you are examining objects that exist at runtime. These may or may not be variables you created, but could be code from a third party.
4. In addition to breakpoints, you can create watch expressions which observe a certain variable or object over time. A common practice is to set the watch expression to be triggered when the variable contains an incorrect value.
- If you know that code will fail, sometimes a good practice is to force the code to read a “good value” so that you can leave this issue until later, and proceed with testing other areas. A good rule is to limit yourself to a 45-minute time limit for each issue; sometimes, you just need to return to the problem later with a fresh set of eyes.
- Also in terms of time management, if it takes a long time to execute the code, you don’t want to necessarily rerun the code over and over again due to an unrelated issue to what you are testing.
5. Communicate the found issue and the subsequent resolution with your team. The chances are pretty high that other people could be running into the same issue!