Code Coverage

For those that know I work for Crossroads Systems as an intern.  My job is mostly to write unit tests for their code.  Unit testing code is a very very useful thing to do.  I’ve primarily deal with code that was never designed to ever be tested.  So I am quite good at dealing with code with high complexities, calls to exit(), and system calls.  So I can really deal with just about any code.

So what I want to say about code coverage of unit tests is this.  It is useful in helping find holes in your unit tests where there is not a test case.  While code coverage tools are not perfect in finding all holes it does help to find the ones where you may not see them.

Unit tests should try to cover nearly all possibilities that a function can do.  When writing them, it is best to try to break the code and designing edge cases.  For example when you have  a function that tries to find the minimum element in the array and you are sure that it can never be 0, set it up so one of the elements is zero to see how the code deals with it.

But I digress.  I’m going to show you how to run GNU’s code coverage tool on C/C++ programs.  As an example I will be show how to do it with main.c++.

On the linux machines when you have all of the tests running and hopefully passing run these commands:

g++ -ansi -pedantic -fprofile-arcs -ftest-coverage -lcppunit -ldl -Wall -DTEST main.c++ -o main.app

main.app //to run it
gcov main.gcda   //This is the actual generation of code coverage.
emacs main.c++.gcov  //or whichever your favourite editor is.
Now there are many options you can pass to gcov. Such as branch percentage generation.  So it may be worth it to read up on it.
So in explaining what is generated:
<string>: linenumber: <actual code>
Now when I say <string> I mean the following.
The line starting with “-” means that it skipped that line, so it’s a comment or something.
The line with “#####” means that that Line was never executed.
The line with a number is a counter of the total number of times the line ran.
So this can help you to find dead areas in code, help debug code if you run a single test case as it will basically track the execution path.  So this technique is very useful.  Enjoy.

Leave a Reply