Code Coverage using gcov

Date Arrow  July 23, 2007

I’ve just uploaded a code coverage test project, using the gcov GNU tool. The idea was to create a small application (simulating an ATM), and injecting into the CppUnit unit tests executable code coverage information, using the gcov utility. And the results just speak by themselves:

       32:  301:    const bool Date::isLeapYear() const
        -:  302:    {
       32:  303:        if ( _year % 4 != 0 )
        -:  304:        {
       19:  305:            return false;
        -:  306:        }
        -:  307:        else
        -:  308:        {
       13:  309:            if ( _year % 100 != 0 )
        -:  310:            {
    #####:  311:                return true;
        -:  312:            }
        -:  313:            else
        -:  314:            {
       13:  315:                if ( _year % 400 != 0 )
        -:  316:                {
        2:  317:                    return false;
        -:  318:                }
        -:  319:                else
        -:  320:                {
       11:  321:                    return true;
        -:  322:                }
        -:  323:            }
        -:  324:        }
        -:  325:    }


The above code sample from the date.cpp.gcov file (in the project zip file) show that the unit tests run called 32 times the Date::isLeapYear() method, of which 19 were not leap years, and the rest were. The interesting bit is in line 311, which was never called, as shown with the “#####” sign! This is extremely nice, since it shows that my tests are not 100% comprehensive, and some cases are not tested.

On the downside, I must say that the gcov tool is not really easy to use (it took me a while to figure out how to do things) but grosso modo it works in the following way:

  1. You must compile and link the unit test application (for example in “Debug” mode, or maybe other special ad hoc configuration) using the -fprofile-arcs -ftest-coverage GCC flags (in Xcode you can check the “Generate Test Coverage Files” and “Instrument Program Flow” option checkboxes) and the -lgcov linker flag. I also set Xcode to “ZeroLink”, told GCC to do optimization level “None [-O0]“, unchecked the option to generate position-dependent code, and disabled prebinding;
  2. You run the application: this will generate a folder with a bunch of files with “.gcda” and “.gcno” extensions, together where the “.o” files are output during the build (when using Xcode on a PPC Mac, these files are created in build/atm.build/Debug/tests.build/Objects-normal/ppc);
  3. Open a command line window and run the commands “gcov FILENAME.gcno” and “gcov FILENAME.gcda” and you will get, in the same folder, a file called “FILENAME.cpp.gcov” with the information shown in the snippet above. By the way, you get files for all the dependencies of that source code as well.

I hope this helps! Having this information can really help ensuring that test cases are comprehensive and complete. As always, if someone has a tip or a comment about gcov and wants to share it, I would be glad to read about it in the comments below.

Similar Posts:

Tagged   Code · Open Source · Quality

14 Comments

  • #1.   Jeff
    07.04.2008

    Sorry, I’m pretty new at this. I can’t get the project to compile and I’m having troubles with the code coverage in Xcode 3. I was hoping to use the project here as an example to figure out what’s going on but I get like 140 compile errors. It’s probably due to the fact that it can’t find many of the frameworks in the project. Any help would be greatly appreciated.
    Thanks, Jeff

  • #2.   Adrian
    07.04.2008

    Hi there! I’ve created this code with Xcode 2.5 on Tiger; I just tried to compile it on Leopard, it compiles but you have to install CppUnit first (at least for the “test” target, that is, since the other one requires wxWidgets). And even then, it crashes at the end of the execution. Anyway, I should take a look to upgrade the project to Xcode 3 but at the moment it’s impossible for me to do that!

    Installing CppUnit is fairly straightforward; the instructions are in the “ext/cppunit/mac.build.sh” shell script (it downloads the file from SourceForge using curl and builds everything for you; then you just have to “sudo make install” by yourself).

    If you want to work seriously with Xcode 3 and gcov, take a look to http://code.google.com/p/coverstory/ which I discovered the other day. They explain how to use gcov on Xcode 3 and by the way the tool is really well done. Hope this helps! Code coverage is really important. Don’t give up! :)

  • #3.   Jeff
    07.05.2008

    Thanks for the quick response. I have had a look at the link you mention, and downloaded the code. It compiles and executes fine but I still don’t see any code coverage files created (gcno or gcda). I’ll see if I can post to one of those guys and see if they know what’s going on. Thanks again for the help.

    -Jeff

  • #4.   Adrian
    07.05.2008

    The gcno / gcda files you will find them in the “build/[project].build/Debug/[Project].build/Objects-normal/[ppc|i386]/” folder inside your Xcode project. Of course, replace the values in brackets by those that apply to your case :) Good luck!

  • #5.   Jeff
    07.05.2008

    Thanks so much! Now I feel like a moron… I did a search and couldn’t find them (in finder). I’m so new to all of this (including Mac OS X), is there some setting that’s making finder not search “hidden files” or something? Well, anyway… now I just need to convert them into the gcov files, right? :)

    -Jeff

  • #6.   Jeff
    07.05.2008

    Thanks for the help… I got everything figured out now. I’m able to see my code coverage numbers now… thanks so much!!! :)

  • #7.   Adrian
    07.06.2008

    Glad to help! :)

  • #8.   Anupama Krishnan
    07.19.2008

    Hi,

    When trying to do “gcov FILENAME.gcda”, I keep getting the error “FILENAME.gcno Cannot open graph file”

    This is for every file – not just any particular one.

    Any ideas/suggestions would be very halpful.

    THanks.

  • #9.   Anupama Krishnan
    07.19.2008

    Folowup question: where exactly must the gcov command be run? Does it have to be run in the directory where the source file exists?

  • #10.   Adrian
    07.20.2008

    Hi Anupama,
    You answered your first question with the second comment :) “cd” to the directory where the gcda files are, and replace “FILENAME” by any of the gcda files inside, done! Hope this helps!

  • #11.   b.l.o.g. » Blog Archive » Bookmarks for October 10th
    10.10.2008

    [...] Code Coverage using gcov – This is a short article describing how to use gcov with cppunit in general. [...]

  • #12.   fahimeh
    01.09.2009

    Hello,

    When trying to do “gcov ”, I keep getting the error “FILENAME.gcno Cannot open graph file”

    This is for every file – not just any particular one.

    Would you please guide me?

    Thanks.

  • #13.   dregehr
    12.15.2009

    Thanks, that was just the information I was looking for!

  • #14.   Sreejith
    03.11.2010

    Thanks, I guess i was pretty much late in grabbing this piece of information.
    i could do it on my code and got the #### portions identified.
    But this could have been better if i get a report of how many functions doent have enough coverage. This is particularly helpful when the code has so many functions and the unit test code is also a big one.

    Could you please tell me whether gcov supports generation of any graphical report kind of document.