cmakecxxtest

How to force ctest only run unit tests in some subdirectories?


My cmake project has the following tree structure:

├── CMakeLists.txt
├── basis
├── build
├── deps
├── study

where /deps contains all 3rd-party dependencies, /basis and /study directories contain routines I wrote.

In my main CMakeLists.txt file, I have the following code to enable CxxTest

cmake_minimum_required(VERSION 3.14)
project(study_cmake)

set( CMAKE_BUILD_TYPE "Debug"  )
add_subdirectory(deps/eigen)

set(CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/deps/cxxtest/)
find_package(CxxTest REQUIRED)
if(CXXTEST_FOUND)
    include_directories(${CXXTEST_INCLUDE_DIR})
    message( 'CXXTEST_INCLUDE_DIR:' ${CXXTEST_INCLUDE_DIR} )
    enable_testing()
endif()

add_subdirectory(study) 
add_subdirectory(basis) 

In /basis/CMakeLists.txt, I have

project(basis)
add_library(
    basis
    include/bernstein.h
    src/bernstein.cpp
)

CXXTEST_ADD_TEST(test_bernstein test_bernstein.cc ${CMAKE_CURRENT_SOURCE_DIR}/test/test_bernstein.h

In /study/CMakeLists.txt, I have similar things as in /basis/CMakeLists.txt. After running cmake .. and make in the build directory, I can run ctest in build/basis/, build/study/to run unit tests defined in these two subdirectories separately. But I would like to have a way to run all unit tests defined in these two subdirectories, so I tried run ctest in /build/. Unfortunately, this command seems also to run all unit tests defined in 3d-party dependencies in /deps/. How can we force ctest only run all unit tests defined in build/basis/ and build/study/ by myself?


Solution

  • The first thing I'd try is ctest's regex selectors. From ctest --help

      -L <regex>, --label-regex <regex>
                                   = Run tests with labels matching regular
                                     expression.
      -R <regex>, --tests-regex <regex>
                                   = Run tests matching regular expression.
      -E <regex>, --exclude-regex <regex>
                                   = Exclude tests matching regular expression.
      -LE <regex>, --label-exclude <regex>
                                   = Exclude tests with labels matching regular
                                     expression.
    

    If you wanted to group a bunch of tests together you could set labels on them.

    CXXTEST_ADD_TEST(test_bernstein test_bernstein.cc ${CMAKE_CURRENT_SOURCE_DIR}/test/test_bernstein.h
    CXXTEST_ADD_TEST(test_scarry test_scarry.cc ${CMAKE_CURRENT_SOURCE_DIR}/test/test_scarry.h
    CXXTEST_ADD_TEST(test_mayer test_mayer.cc ${CMAKE_CURRENT_SOURCE_DIR}/test/test_mayer.h
    CXXTEST_ADD_TEST(test_king test_king.cc ${CMAKE_CURRENT_SOURCE_DIR}/test/test_king.h
    
    set_tests_properties(test_bernstein test_scarry test_mayer PROPERTIES LABELS "fun")
    set_tests_properties(test_king PROPERTIES LABELS "scary")
    

    Note that set_tests_properties() only defines properties on tests created with add_test() (which CXXTEST_ADD_TEST does behind the scenes.) Then you could run ctest -L fun to run only the "fun" tests.

    $ ctest -L fun
    Test project /home/me/myproject
         Start 1: test_bernstein
     1/3 Test #1: test_bernstein ..............   Passed    2.19 sec
         Start 2: test_scarry
     2/3 Test #2: test_scarry .................   Passed    2.19 sec
         Start 3: test_mayer
     3/3 Test #3: test_mayer ..................   Passed    2.19 sec
    100% tests passed out of 23
    
    Total Test time (real) =  6.57 sec
    
    $