One of Dr. Welborn's best pieces of advice to novice programmers. :) It takes real skill, no matter what testing method you use, to test (and by extension, debug) effectively!
Many of you have the wrong idea of what testing is. Many of you mistakenly believe testing is the process of proving your code is correct. If you approach testing with the mindset that you're going to prove your code is correct, you most likely will. No matter how many bugs you have. Testing is based on the Scientific Method. Forgotten the Scientific Method, here is a recap:
- Observe a System
- Build a theory or model that explains the System
- Use the theory/model to make predictions about the System
- Verify the theory/model is correct by comparing predicted results with actual results
- Here is where using boundary conditions come in. Test those elements of your theory/model that are most likely to fail not those most likely to succeed.
- Modify the theory/model if predicted results don't match actual results
So where is the disconnect in your testing. Too many of you are stuck in the "Observe a System" phase. You're running random tests without ever predicting what the results will before the test is run. This is neither science nor engineering; this is cross-your-fingers-and-hope-for-the-best. Not a good strategy to develop quality programs.
If you don't know before you run a test exactly what should happen then that is a random test and you're not verifying your program you're just observing it run.
This is interesting to follow up with Chris Koknat's The Interactive Debugger vs. Print Statements, where he states his experience of using debuggers versus print statements:
With either tool, the key insight appeared to be the method chosen for placing either a print statement or a breakpoint. The effective programmers strove to understand the code and form a hypothesis of what problem might cause the current symptom. That person would use this hypothesis to determine where a print statement or breakpoint could be used to prove or disprove the hypothesis.
Those people would usually make effective progress toward finding and squashing the bug. The ones that also had the most experience or understanding of the code were particularly effective in this technique. Their initial guesses tended to be much closer to the target.
The other group used either print statements or single-stepping to explore the code. They seemed to almost be on a voyage of discovery. This is admirable, and can be an effective way of learning the code. But, this approach does not lend itself to rapid bug fixing.