Skip to content

Instantly share code, notes, and snippets.

@sytsereitsma
Created June 8, 2023 11:47
Show Gist options
  • Save sytsereitsma/e088ae21b2e36ebabfc0170e4ad873bd to your computer and use it in GitHub Desktop.
Save sytsereitsma/e088ae21b2e36ebabfc0170e4ad873bd to your computer and use it in GitHub Desktop.
Code coverage with CMake/CTest

Code coverage analysis with ctest

The following script creates a library with a function int add(int a, int b) and a test application that links to the library and calls add

CMakeLists.txt

cmake_minimum_required(VERSION 3.25)
project(CoverageTest)

file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib.cpp" "int add(int a, int b) { return a + b; }")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test.cpp" "extern int add(int, int); int main() { return add(1, 2) == 3 ? 0 : 1; }")

add_library(mylib STATIC ${CMAKE_CURRENT_BINARY_DIR}/lib.cpp)
add_executable(testapp ${CMAKE_CURRENT_BINARY_DIR}/test.cpp)

# All targets requireing coverage analysis need the following compile options
target_compile_options(testapp PRIVATE -g -fprofile-arcs -ftest-coverage)
target_compile_options(mylib PRIVATE -g -fprofile-arcs -ftest-coverage)

# And we need to link to libgcov.a
target_link_libraries(testapp mylib gcov)

# Tell ctest what the test application is
add_test(NAME testLib
    COMMAND testapp
)

# This include is needed to avoid the `Binary directory is not set. No coverage checking will be performed.` error when running ctest
include(CTest)
enable_testing()

Configure build and run:

cmake -B build
cmake --build build
ctest --test-dir build -T Test -T Coverage

This will output:

[~/projects/experiments/coverage]$ cmake -B build
-- The C compiler identification is GNU 11.1.0
-- The CXX compiler identification is GNU 11.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: ~/projects/experiments/coverage/build
[~/projects/experiments/coverage]$ cmake --build build
[ 25%] Building CXX object CMakeFiles/mylib.dir/lib.cpp.o
[ 50%] Linking CXX static library libmylib.a
[ 50%] Built target mylib
[ 75%] Building CXX object CMakeFiles/testapp.dir/test.cpp.o
[100%] Linking CXX executable testapp
[100%] Built target testapp
[~/projects/experiments/coverage]$ ctest --test-dir build -T Test -T Coverage
Internal ctest changing into directory: ~/projects/experiments/coverage/build
   Site: THS-LT-12
   Build name: Linux-c++
Create new tag: 20230608-1145 - Experimental
Test project ~/projects/experiments/coverage/build
    Start 1: testLib
1/1 Test #1: testLib ..........................   Passed    0.02 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   0.06 sec
Performing coverage
   Processing coverage (each . represents one file):
    ..
   Accumulating results (each . represents one file):
    ..
        Covered LOC:         2
        Not covered LOC:     0
        Total LOC:           2
        Percentage Coverage: 100.00%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment