I have a CMake project in which I am trying to enable code coverage (Using Gcov, Lcov, and Geninfo). In order to do this, I am using a module CodeCoverage.cmake to set this up for my target. Here is the code that sets this up.
if (ENABLE_COVERAGE AND NOT CMAKE_CONFIGURATION_TYPES)
if (NOT BUILD_TESTS)
set(BUILD_TESTS On CACHE STRING "" FORCE)
endif (NOT BUILD_TESTS)
include(CodeCoverage)
include_directories(include ${PROJECT_BINARY_DIR})
add_subdirectory(src) # <--
# Defines target Project-Name-lib, which is a
# library consisting of all sources files except main.cpp
# Also defines Project-Name, which is the executable
target_compile_options(Project-Name-lib PRIVATE "--coverage")
# Only add coverage flags to the library, _NOTHING_ else
SETUP_TARGET_FOR_COVERAGE(NAME coverage
EXECUTABLE tests
DEPENDENCIES coverage)
# Function from the module to enable coverage
else (ENABLE_COVERAGE AND NOT CMAKE_CONFIGURATION_TYPES)
# ... Normal build ...
endif (ENABLE_COVERAGE AND NOT CMAKE_CONFIGURATION_TYPES)
if (BUILD_TESTS)
include(CTest)
enable_testing()
add_subdirectory(tests)
endif (BUILD_TESTS)
This approach works really well, and when I use make coverage
to run my program, then the reports successfully generate and can be viewed in the browser. However, there is one problem. This approach only enables coverage for the library, not any of the local header files I am using. For example, if I had a header like the following:
class HelloWorld
{
public:
HelloWorld();
std::string hello() const; // <-- Implementation in header.cpp
std::string world() const; // <-- Implementation in header.cpp
int generateRandomNumber() const; // <-- Implementation in header.cpp
int headerFunction(int test) const
{
if (test == 45)
return 45;
else
return 4;
}
private:
std::string hello_;
std::string world_;
};
And a corresponding test case (Using Catch 2.2.1):
SECTION("function headerFunction()")
{
REQUIRE(helloWorld.headerFunction(33) == 4);
// All branches are NOT covered
}
Then all test cases pass (as expected), but the function in the header file does not show up in index.html
for the coverage. Only the functions that are defined in header.cpp
do. Because of this, my code coverage incorrectly shows up as 100%. How should I change my CMake code so that the functions that are defined in a header file are also included as part of the coverage report?