I was trained as a scientist and I've always thought that programs were similar to experiments. Like experiments, programs test theories of how things are supposed to work, and like experiments, programs have (sometimes unpredictable) results that can be analyzed. In very simple experimental terms, we can ask "does this program do what I intended it to do?"
One way to figure this out is to add code to your program that tells you what it is doing. Since writing my first programs, I would add code like this to my code to tell me what is was doing:
cout << "The value of x_coord inside the polar_converter function is: " << x_coord << end;
My code would be littered with sometimes dozens of text output statements like this, each designed to show me that some specific piece of code was doing what I thought it was doing. Some outputted the value of a variable. Sometimes they would just mention that a portion of code was executed without any error occurring. "File Loaded..." But each line of code like this was meant to function as a small window that showed what was going on in a program at a given step. But as all of these windows piled up text on the command line, I would have to add empty text lines or long strings of "-----" just to group the output into "paragraphs" that could be more easily read.
When the program was complete, I would then go about commenting out all the extra cout (or print) statements. Manually. To me it was like pulling off the tape that covered the wooden trim in a room you just painted. The end product was clean and sharp and smelled good too.
And then my mind was blown... In a class lecture, Eric Van Wyk went over some code examples and introduced the notion of a DEBUG flag. What a great idea! The DEBUG flag is a global variable that is set to 1 or 0 (TRUE or FALSE) and acts as a switch to turn off and on all of the little output statements you put into your code to see what it does. Therefore, a programmer doesn't have to go back and comment out (or uncomment back in) code that serves a debugging function.
Brilliant! What a timesaver! I wonder who invented that. If there's one thing I take away from this class, and it's this idea, then I consider this whole class was worth taking.
The DEBUG flag is a global variable that turns statements or code sections on and off globally. But sometimes we want to test portions of code individually. We call these portions of code "units" and apply the term "unit testing" to testing these portions. Usually a unit is an individual function, but it can also be defined as a functional unit containing multiple functions or programs. While testing one variable may consist of writing a simple output statement (as above), testing a function (or unit) can be a more complex task. But like variable testing, it involves inputting a know value and evaluating the output.
In class we were introduced to a C++ unit testing framework called CxxTest. Getting started with CxxTest was a little confusing. After downloading and setting up the CxxTest library, we compiled and ran an example provided by our class instructors. After getting it to run, I took a closer look at the code and saw how functions in my program were being called systematically from a "test.h" header file which had a corresponding "test.cpp" file. At first glance, this seemed really complicated and it looked like a lot of extra work to write the that "test.cpp" file. Wasn't this framework suppose to reduce tedious and repetitive work? As soon as I realized that the CxxTest suite wrote that .cpp file on its own, I really started to see the benefits it could provide. CxxTest organizes tests into "Test Suites" that are written into the header files and then then the "test runner" C++ files are generated automatically.
I'm starting to see a pattern in the way I deal with new software and new programming tools. Both with CxxTest and with Subversion, I seriously underestimated what the programs were doing. In the case of Subversion, I thought I had to re-check out and re-check in files each time I booted up my computer. But I didn't need to because Subversion keeps track of that (magically). With CxxTest, it took some time for it to actually register that this system was automatically writing code for me.