You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This was written against commit 1fcf7f4 in June 2024. The latest at the time of writing.
I am putting this here as a tutorial only. In my example, I use doctest bootstrapped by ctest but you can use Catch2 or something else instead. ctest will still be required though.
My project contains multiple shared libraries with separate tests. I want to be able to run lcov over the entire project and aggregate the results rather than deal with separate reports.
Some attempts were made previously by people in #8 with ctest and catkin. I have adapted and summarised some of this below.
Whether or not you separate your include/ or src/ folders is irrelevant. What is relevant, is that you have an overarching test/ folder in the project root and separate test/ folders for each of your libraries/executables.
Code
project_root/CMakeLists.txt:
cmake_minimum_required(VERSION 3.27)
project(my_project LANGUAGES C CXX)
# bla bla bla, regular project root setup# important parts belowenable_testing()
add_subdirectory(my_first_lib)
add_subdirectory(my_second_lib)
add_subdirectory(test)
project_root/my_first_lib/CMakeLists.txt:
# just your regular library setup belowadd_library(my_first_lib SHARED)
target_sources(
my_first_lib PRIVATE# include all of your library source files as you normally would
src/library.cpp
)
target_include_directories(
my_first_lib PUBLIC"${CMAKE_CURRENT_SOURCE_DIR}/include"
)
target_include_directories(
my_first_lib PRIVATE"${CMAKE_CURRENT_SOURCE_DIR}/src"
)
# important part for testingadd_executable(my_first_lib_test)
target_sources(
my_first_lib_test PRIVATE# I use an identical main() file for all tests, you can customise as required"${CMAKE_SOURCE_DIR}/test/main.cpp"# now put each of the test sources below
test/my_first_lib_test_foobar.cpp
test/my_first_lib_test_simple.cpp
test/my_first_lib_test_very_hard.cpp
)
target_link_libraries(
my_first_lib_test PRIVATE# I use doctest for testing, you may use something else
doctest::doctest
# the test executable links to the library
my_first_lib
)
target_include_directories(
my_first_lib_test PRIVATE"${CMAKE_SOURCE_DIR}/test"
)
add_test(NAME my_first_lib_ctest COMMAND my_first_lib_test)
append_coverage_compiler_flags_to_target(my_first_lib)
append_coverage_compiler_flags_to_target(my_first_lib_test)
project_root/my_second_lib/CMakeLists.txt:
Exactly the same as project_root/my_first_lib/CMakeLists.txt except everything targets my_second_lib_xxx rather than my_first_lib_xxx.
project_root/test/CMakeLists.txt:
setup_target_for_coverage_lcov(
NAME"my_coverage"
EXECUTABLE "${CMAKE_CTEST_COMMAND}""--verbose"
DEPENDENCIES
# place all add_test targets below"my_first_lib_test""my_second_lib_test"# exclusions must contain "test" to avoid including the main.cpp file# (your mileage may vary if you write your main() functions differently)EXCLUDE"/usr/*""*/_deps/*""test"
)
This results in a target my_coverage which will execute ctest which will execute all of your separate test executables.
I am using doctest and my tests will call into library code. In the same vein, you can adapt this to run an executable instead of a library by using a custom main() that calls all doctest test-cases if CMake is building in non-release mode.
Once lcov runs and generates the final report, all aggregated results will be listed from both libraries.
Further adaptation
If you don't use doctest or you don't care for a shared main() function, then you can simplify this by removing the project_root/test/ folder entirely and moving the setup_target_for_coverage_lcov call straight into project_root/CMakeLists.txt.
The text was updated successfully, but these errors were encountered:
Tutorial
This was written against commit 1fcf7f4 in June 2024. The latest at the time of writing.
I am putting this here as a tutorial only. In my example, I use
doctest
bootstrapped byctest
but you can useCatch2
or something else instead.ctest
will still be required though.My project contains multiple shared libraries with separate tests. I want to be able to run lcov over the entire project and aggregate the results rather than deal with separate reports.
Some attempts were made previously by people in #8 with
ctest
andcatkin
. I have adapted and summarised some of this below.Structure
My general project structure is as follows:
Whether or not you separate your
include/
orsrc/
folders is irrelevant. What is relevant, is that you have an overarchingtest/
folder in the project root and separatetest/
folders for each of your libraries/executables.Code
project_root/CMakeLists.txt
:project_root/my_first_lib/CMakeLists.txt
:project_root/my_second_lib/CMakeLists.txt
:Exactly the same as
project_root/my_first_lib/CMakeLists.txt
except everything targetsmy_second_lib_xxx
rather thanmy_first_lib_xxx
.project_root/test/CMakeLists.txt
:project_root/test/main.cpp
:Result
This results in a target
my_coverage
which will executectest
which will execute all of your separate test executables.I am using
doctest
and my tests will call into library code. In the same vein, you can adapt this to run an executable instead of a library by using a custommain()
that calls alldoctest
test-cases if CMake is building in non-release mode.Once
lcov
runs and generates the final report, all aggregated results will be listed from both libraries.Further adaptation
If you don't use
doctest
or you don't care for a sharedmain()
function, then you can simplify this by removing theproject_root/test/
folder entirely and moving thesetup_target_for_coverage_lcov
call straight intoproject_root/CMakeLists.txt
.The text was updated successfully, but these errors were encountered: