Writing code is hard, and it’s never right the first time. It’s best to find the problems in our code before the GTA/boss/customers find them. That’s why we write test cases. However, the question arises: Did we test all of our code? People have a natural tendency to test only the parts of the code that they’re confident about, and shy away from the questionable parts.
If only there were some way to know if we’d tested it all!
gcov is a code coverage tool. It tells you how many times each line
in your code has been executed. This tells you:
Granted, #2 is only an approximation, since it only tells you how many times the line is being executed. Not all lines of code take the same amount of time—consider the assignment of an integer, as opposed to calculating a cosine. However, it’s often a good-enough approximation.
In this lab, we will use
~cs253/Labs/Coverageto a convenient location in your home directory.
code.cc. Take a minute or two to look at the code, including the test cases in
#####for never executed, or
-for a non-executable line), a line number, and the source code for that line.
#####. Those lines weren’t tested.
main()for those untested lines.
make), rerun (
./code), and recreate the coverage data (
code.cc.gcov, and find the lines that start with the largest number. It should be the routine
days_per_month(). Resist the urge to optimize that code. Instead, find out who’s calling it tens of millions of times. The culprit should be line 112 or so.
#if 0. Try making that code active, recompile, rerun, recreate coverage data, and see if it helped.
leap(). Observe how it almost always calculates the modulus (
%) three times for each year. Since most years are not leap years, this is silly. Make this code more efficient, without sacrificing clarity, and prove it using
gcovdata. Before you do that, however, run
codeand save the output. After you make your improvements to
diffthe output, so you’ll know if you broke it or not.
gcov code.cc, run
gcov -b code.cc, for branch flow analysis.
Makefileto compile with
-DNDEBUG, which turns off assertions. Recompile, rerun, and see what
gcov -b code.ccgives you.
leap()and see if it makes sense.
operator>>. Note that some branches are taken 0% of the time. Why? What still isn’t being tested?