Getting useful GCov results for header-only libraries
Apart from the usual flags to GCC controlling inlining;
--coverage -fno-inline -fno-inline-small-functions -fno-default-inline
You can instantiate your template classes at the top of your unit test files;
template class std::map<std::string, std::string>;
This will generate code for every method in that template class making the coverage tools work perfectly.
Also, make sure that you initialise your *.gcno files (so for lcov)
lcov -c -i -b ${ROOT} -d . -o Coverage.baseline
<run your tests here>
lcov -c -d . -b ${ROOT} -o Coverage.out
lcov -a Coverage.baseline -a Coverage.out -o Coverage.combined
genhtml Coverage.combined -o HTML
gcov reporting wrong result for header only class
As it seems the problem wasn't the fact that my class is header only but that I called gcov with
gcov unittest_myclass.cpp -o .obj/
if I instead run it with
gcov *.cpp -o .obj/
it reports
File '../include/myclass.h'
Lines executed:95.56% of 248
Creating 'myclass.h.gcov'
and the resulting myclass.h.gcov
file looks a lot more than what I expected.
How to get correct code coverage for member functions in header files
The methods with 0% coverage were inline methods in a header.
I did compile the library I was testing with gcc --coverage
which instruments the machine code to collect coverage. However, I did not instrument the test executable since I am not interested in the coverage of the tests themselves. So the test executable contained code for the inline methods without instrumenting them.
As a result, the methods were known to gcov but no coverage was collected (only the non-instrumented inline version was executed).
The solution:
- also instrument the tests by using the
--coverage
compiler flag - filter out the unwanted coverage data of the tests with the
-e
/--exclude
gcovr option
How to get gcov results for included C/CPP files
If I compile test with --coverage
instead of -lgcov
it does generate a test.gcda
. I thought at first this was not what I wanted since I'm looking for coverage in lib.c
But if I run both testlib
and test
and then use gcov on all the files together, it combines the coverage data properly:
gcov lib.gcda lib.gcno test.gcda test.gcno
And this yields lib.c.gcov
with code coverage from both test runs.
How can I get more accurate results from gcov?
As suggested in the comment by Mat, the option -fno-elide-constructors
fixes this problem.
This answer was posted to get this already ancient question closed. If Mat posts an answer, I'll delete this and switch the accept to that.
Generating test coverage of C++ static library as called by separate test classes
From the ld manual
--whole-archive
For each archive mentioned on the command line after the--whole-archive
option, include every object file in the archive
in the link, rather than searching the archive for the required object
files.
So link your static-library into your test using --whole-archive
, which will result in your test binary having the entire static-library, and give gcov
visibility of the entire code
Related Topics
How to Use Lambda Auto Parameters in C++11
Properties File Library for C (Or C++)
PDF Specifications for Coders: Adobe or Iso
What Is the Purpose of C++20 Std::Common_Reference
Which MACro to Wrap MAC Os X Specific Code in C/C++
C++11 Lambdas: Member Variable Capture Gotcha
Shift Image Content with Opencv
Sfinae and Partial Class Template Specializations
Lvalue to Rvalue Reference Binding
Const Unsigned Char * to Std::String
What's the Best Technique for Exiting from a Constructor on an Error Condition in C++
How Does Qt Delete Objects? and How to Store Qobjects
Reshaping a 1-D Array to a Multidimensional Array
VS 2012 - Project Failed to Build Because of Missing Toolset
What Is Difference Between Const and Non Const Key
How to Determine Programmatically If an Expression Is Rvalue or Lvalue in C++
Why Do Type Aliases in C++ Use 'Using' Instead of 'Typedef' in Their Syntax