By this time you probably have your program written and containing a lot of sanity checks, some permanent and some temporary. Now it is time to test it. Let’s go bug hunting, one bug at a time. Our testing algorithm is very simple:
Run your code with sanity checks on, trying to cover all possible cases.
If any sanity check fails, fix the code and return to step 1.
If you’ve made it to step 3, you can be reasonably sure your code works correctly. Well done!
In my personal experience, this strategy makes testing a much faster, more efficient, and more enjoyable procedure than it would otherwise be, when your code does strange things and does not provide any explanation for its behavior. All you have to do to make this process effective is to insert enough sanity checks in your code while writing it and to make them as informative as possible. In short, the more sanity checks you have in your code, the more you can guarantee that it works correctly after it has passed all the checks.
Let’s consider how the SCPP_TEST_ASSERT
macro
can be switched on. Take a closer look in the file
scpp_assert.hpp, where it is defined:
#ifdef _DEBUG # define SCPP_TEST_ASSERT_ON #endif #ifdef SCPP_TEST_ASSERT_ON # define SCPP_TEST_ASSERT(condition,msg) SCPP_ASSERT(condition, msg) #else # define SCPP_TEST_ASSERT(condition,msg) // do nothing #endif
If you compile your project in debug mode, a symbol named _DEBUG
is defined during compilation (this might be compiler-dependent, but it is
definitely true for Microsoft Visual Studio). In this case, your sanity checks (e.g., the
SCPP_TEST_ASSERT
macro) are on. Our option for running the
code are summarized in Table 15-1.
Table 15-1. Testing modes
Level | Purpose | Compilation mode | Test sanity checks |
---|---|---|---|
1 | Testing with debugging on error | Debug | On |
2 | Fast testing | Release | On |
3 | Production | Release | Off |
Options 1 and 3 are obvious enough: most of the time you will want to test your code while it is compiled in debug mode, and probably running it inside a debugger. However, if your program does a lot of number crunching, and if switching sanity checks on and compiling in the debug mode slow it down too much, you have option 2: testing the code compiled in release mode with sanity checks on. Not having the luxury of exploring the code in the debugger makes it especially important that your error messages contain enough information to allow you to fix the bug.
If your program is fast enough to run with sanity checks in debug mode, the easiest way to
catch a bug is to open the scpp_assert.cpp file, find the
comment “This is a good place to put your debug breakpoint:”, and put a debug breakpoint on the
next line (which can be the line starting with either throw
or cerr
, depending on how the code was compiled):
void SCPP_AssertErrorHandler(const char* file_name, unsigned line_number, const char* message) { // This is a good place to put your debug breakpoint: // You can also add writing of the same info into a log file if appropriate. #ifdef SCPP_THROW_EXCEPTION_ON_BUG throw scpp::ScppAssertFailedException(file_name, line_number, message); #else cerr << message << " in file " << file_name << " #" << line_number << endl << flush; // Terminate application exit(1); #endif
This is the reason I created this error handler function. Simply knowing the filename and line number where the error occurred might not help you much. But if you put your debugger breakpoint there, the debugger will stop on it during every execution of this line, even if the bug occurs on only the 10th or even the 10,000th iteration. By putting the breakpoint inside the error handler function, you are guaranteed that your program will run to the first error and stop in the debugger, as shown in Figure 15-1.
If the text of the error message is not enough to figure out why the error happened, you can go up the call stack into the function where the error occurred and examine the variables to figure out what happened and why. On the other hand, if your debugger doesn’t stop on this breakpoint, you should not be too disappointed—your program passed all sanity checks!
18.118.226.240