Use gcov and lcov to know your test coverage

As we all know, unit test has been a crucial part of software development. I feel I was walking on ice if I was coding without writing tests. But even if we have unit tests, things may still go wrong if the tests have bad coverage. Fortunately, there are many tools today to help us analyze our code and give us every detail of the quality of our unit tests. GNU gcov is such a tool for code compiled with GCC.

gcov is very easy to use. If you’re developing a C/C++ project, all you have to do is to compile your project with “-g -O0 –coverage”. “–coverage” is a synonym for-fprofile-arcs, -ftest-coverage(compiling) and-lgcov(linking). This tells the compiler to generate additional information and code needed by gcov.

OK, let’s run our tests. GCC will generate a bunch of files(profiles) that will be used later. These files know how your tests was executed and record many information such as arc transition counts and some summary information. Now we’re ready to view our test coverage now with gcov.  But gcov doesn’t give us a report that is easy to read and it’s not convenient. Here comes the tool called “LCOV”.

LCOV test coverage report for libbash

LCOV is a graphical front-end for gcov. It collects gcov data for multiple source files and creates HTML pages containing the source code annotated with coverage information. It also adds overview pages for easy navigation within the file structure. LCOV supports statement, function and branch coverage measurement. The above picture is a test coverage report generated by LCOV.

LCOV is quite easy to use too so you can refer to its man page for its usage. In our libbash project, I wrote a script to generate test coverage report. It creates a completely new environment based on “make dist” so you don’t have to change any GCC flag at all. Note that libtool doesn’t work well with gcov so you have to use static linking for all your libraries(–disable-shared).  The reason is libtool uses -nostdlib to compile the libraries. I’ve already reported this issue to libtool mail list but haven’t got anything helpful yet.

Feel free to modify to fit your needs.

#!/bin/sh

which lcov 1>/dev/null 2>&1
if [ $? != 0 ]
then
    echo "You need to have lcov installed in order to generate the test coverage report"
    exit 1
fi

if [ ! $DIST_ARCHIVES ]
then
    echo "You need to provide the archive name by running DIST_ARCHIVES=\"ARCHIVE_NAME\" $0"
    exit 1
fi

tar zxf $DIST_ARCHIVES
srcdir=${DIST_ARCHIVES/.tar.gz}
cd $srcdir

# Reconfigure with gcov support
CXXFLAGS="-g -O0 --coverage" CFLAGS="-g -O0 --coverage" ./autogen.sh --disable-shared

# Generate gcov output
${MAKE}

# Generate html report
lcov --base-directory . --directory . --zerocounters -q
${MAKE} check
lcov --base-directory . --directory . -c -o libbash_test.info
lcov --remove libbash_test.info "/usr*" -o libbash_test.info # remove output for external libraries
rm -rf ../test_coverage
genhtml -o ../test_coverage -t "libbash test coverage" --num-spaces 4 libbash_test.info

# Clean work space
cd .. && rm -rf $srcdir
Advertisements

, , ,

  1. #1 by Delmar on December 7, 2013 - 9:36 pm

    Thanks for finally talking about >Use gciv and lcov to know your test coverage | Another Gentoo Dev <Loved it!

  2. #2 by Pure Logic Web Design on February 28, 2014 - 2:38 pm

    Marvelous! Keep writing. 😀

  3. #3 by testing on July 8, 2014 - 6:04 am

    Oh my goodness! Impressive article dude! Thank you
    so much, However I am encountering troubles with your RSS. I don’t know the reason why
    I am unable to join it. Is there anybody else having identical RSS problems?
    Anybody who knows the answer can you kindly respond? Thanks!!

  4. #4 by Sarath S on November 3, 2014 - 2:59 pm

    when trying to remove files, facing the below error.

    Writing data to removed.info
    Summary coverage rate:
    lines……: 33.0% (7005 of 21200 lines)
    functions..: 43.5% (660 of 1516 functions)
    branches…: no data found
    Reading data file coverage_files/removed.info
    genhtml: ERROR: cannot read file coverage_files/removed.info!

  5. #5 by Armada on April 7, 2016 - 8:47 am

    Hey, can anyone help me out in this gcov branch conundrum. How many branches should be there for the following condition?

    if( at(column,i) == EMPTY && inBounds(column,i) ) { //logic }

    I am getting totally 6 branches which is as follows

    call 0 returned 100%
    branch 1 taken 56% (fallthrough)
    branch 2 taken 44%
    call 3 returned 100%
    branch 4 taken 100% (fallthrough)
    branch 5 taken 0%
    branch 6 taken 56% (fallthrough)
    branch 7 taken 44%

    Please can anyone detail me what is the branch 4 & 5 for?

  6. #6 by Autotractari on April 17, 2016 - 6:23 pm

    Hei, multumim pt impartasirea acestor informatii utile.

  7. #7 by agen sabung ayam on May 14, 2017 - 2:35 am

    The very next time I read a blog, I hope that it does not fail me as much as this particular one. After all, I know it was my choice to read through, however I genuinely believed you would have something useful to talk about. All I hear is a bunch of moaning about something you can fix if you were not too busy looking for attention.

  8. #8 by özel web yazılımı on July 16, 2017 - 4:16 pm

    Harika paylaşımlarda bulunuyorsunuz sağolun

  1. libbash weekly report #2 « Another Gentoo Dev
  2. Code Coverage for Embedded Target with Eclipse, gcc and gcov | MCU on Eclipse
  3. GCC and Code Coverage – Gilson in Life

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: