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 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
#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 by Pure Logic Web Design on February 28, 2014 - 2:38 pm
Marvelous! Keep writing. 😀
#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 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 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 by Autotractari on April 17, 2016 - 6:23 pm
Hei, multumim pt impartasirea acestor informatii utile.
#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 by özel web yazılımı on July 16, 2017 - 4:16 pm
Harika paylaşımlarda bulunuyorsunuz sağolun
#9 by Gladis Pendexter on December 19, 2017 - 4:13 pm
Very nice, thank you!
#10 by Ambrose Tancer on April 15, 2019 - 6:32 pm
Having read this I believed iit was really informative.
I appreciate you spending some time and energy to put this
content together. I once again find myself personally spending a lot of time both reading and
commenting. But so what, it was still worth it!
#11 by sumiya on September 18, 2020 - 2:57 pm
Is LCOV tool works independently and Is it possible to integrated with any other tool.