Search code examples
visual-studiocmakectestcatch2

How do I run tests built using VisualStudio, via CMake/CTest/Catch2 from the CLI?


I'm trying to learn several things at once (arguably my first problem...), namely: unit testing with Catch2 and building with CMake.

In the course of my investigations, CTest appeared on the radar as a pre-baked way of managing tests within CMake, and seems to 'support' Catch2.

While things seem to build okay, I can't run my tests as automatically as I'd hope.

Specifically, I have a source tree, which at some point contains the library I'm testing, and I'd like to be able to sit at the top of the tree and execute some sort of 'run my tests' command (and ideally run them as part of the full build, but that's for another day).

So here's my CMakeLists.txt file (L:\scratch\shared\testeroolib\CMakeLists.txt) for the library of interest:

cmake_minimum_required(VERSION 3.5)
project(testeroolib)

add_library(${PROJECT_NAME} STATIC src/testeroolib.cpp)
target_include_directories(${PROJECT_NAME} PUBLIC include)

set(PROJECT_TEST ${PROJECT_NAME}_test)

add_executable(${PROJECT_TEST} test/catch2_main.cpp)
target_link_libraries(${PROJECT_TEST} PRIVATE Catch)
target_link_libraries(${PROJECT_TEST} PRIVATE ${PROJECT_NAME})

enable_testing()
add_test(NAME TesterooLibTest COMMAND ${PROJECT_TEST})

If I do the naive thing and run ctest from the same location I run cmake, I get:

L:\scratch>ctest
*********************************
No test configuration file found!
*********************************
...

or

L:\scratch>ctest .
Test project L:/scratch
No tests were found!!!

From what I've read elsewhere, make test would do the trick with GCC and friends, but I'm using VS.

So here, the advice seems to be that I should use a build target of ALL_TESTS but that doesn't do the trick for me.

L:\scratch>cmake --build BUILD --target ALL_TESTS
...
MSBUILD : error MSB1009: Project file does not exist.
Switch: ALL_TESTS.vcxproj

Of course, I can just run the test:

L:\scratch>BUILD\shared\testeroolib\Debug\testeroolib_test.exe
===============================================================================
All tests passed (1 assertion in 1 test case)

I'm hoping I've made some tiny snafu, but there is every chance I've got completely the wrong end of the stick here!


Solution

  • I believe I've found the (two-part) answer.

    The first part is that it's no good running ctest from the top level, you need to run it from the build folder. With hindsight, that's pretty obvious :(

    cmake -S . -B BUILD
    cmake --build BUILD
    cd BUILD
    ctest
    

    The less obvious part I found in this answer: https://stackoverflow.com/a/13551858/11603085. Namely, the enable_testing() call needs to be in the top-level CMakeLists.txt, not the one further down that actually builds the library.