Search code examples
c++unit-testingcmakecatch2

How do you add separate test files with Catch2 and CMake?


In the documentation, they only compile a single file test.cpp which presumably contains all the tests. I want to separate my individual tests from the file that contains #define CATCH_CONFIG_MAIN, like so.

If I have a file test.cpp which contains #define CATCH_CONFIG_MAIN and a separate test file simple_test.cpp, I've managed to produce an executable that contains the test in simple_test.cpp this way:

find_package(Catch2 REQUIRED)

add_executable(tests test.cpp simple_test.cpp)
target_link_libraries(tests Catch2::Catch2)

include(CTest)
include(Catch)
catch_discover_tests(tests)

However, is this an acceptable way of producing the executable? From different tutorials, if I had more tests, I should be able to make a library of test sources and link them to test.cpp to produce the executable:

find_package(Catch2 REQUIRED)

add_library(test_sources simple_test.cpp another_test.cpp)
target_link_libraries(test_sources Catch2::Catch2)

add_executable(tests test.cpp)
target_link_libraries(tests test_sources)
target_link_libraries(tests Catch2::Catch2)

include(CTest)
include(Catch)
catch_discover_tests(tests)

But when I tried this, I got a CMake Warning Test executable ... contains no tests!.

To summarize, should I be making a library of tests? If so, how can I make it contain my tests. Otherwise, is it correct to be adding my new test.cpp files to the add_executable function?


Solution

  • How do you add separate test files with Catch2 and CMake?

    Use object libraries or use --Wl,--whole-archive. Linker removes unreferenced symbols from static libraries when linking, so the tests are not in the final executable.

    Could you give an example CMakeLists.txt?

    Like

    find_package(Catch2 REQUIRED)
    
    add_library(test_sources OBJECT simple_test.cpp another_test.cpp)
    target_link_libraries(test_sources Catch2::Catch2)
    
    add_executable(tests test.cpp)
    target_link_libraries(tests test_sources)
    target_link_libraries(tests Catch2::Catch2)
    
    include(CTest)
    include(Catch)
    catch_discover_tests(tests)
    

    or

    find_package(Catch2 REQUIRED)
    
    add_library(test_sources simple_test.cpp another_test.cpp)
    target_link_libraries(test_sources Catch2::Catch2)
    
    add_executable(tests test.cpp)
    target_link_libraries(tests -Wl,--whole-archive test_sources -Wl,--no-whole-archive)
    target_link_libraries(tests Catch2::Catch2)
    
    include(CTest)
    include(Catch)
    catch_discover_tests(tests)