CTest add tests in subdirectories
Asked Answered
K

1

15

I have a CMake-based project that consists of several sub-components, which can all be independently compiled and tested. The directory layout looks like this:

.
├── CMakeLists.txt
├── comp1
│   ├── CMakeLists.txt
│   ├── src
│   │   ├── foo.cc
│   │   └── foo.h
│   └── tests
│       ├── CMakeLists.txt
│       └── test_comp1.cc
└── comp2
    ├── CMakeLists.txt
    ├── src
    │   ├── bar.cc
    │   └── bar.h
    └── tests
        ├── CMakeLists.txt
        └── test_comp2.cc

I want to enable ctest, therefore in the root CMakeLists.txt I have include(CTest) and in the component-specific CMakeLists.txt files I have

if(BUILD_TESTING)
  add_subdirectory(tests)
endif()

In compX/tests/CMakeLists.txt I have the code to compile the test and the add_test()command. The tests get successfully compiled and I can manually run them. However, if I call ctest, it returns

No tests were found!!!

After playing a bit with this, it turned out that if I move the add_subdirectory(tests) call to the root CMakeLists.txt like this:

if(BUILD_TESTING)
  add_subdirectory(comp1/tests)
endif()

it works. But I find this quite ugly and messy, to put component-specific stuff into the root file.

Conversely, I tried to move the include(CTest) command one level down into the component-specific CMakeLists.txt. But ctest complains with this:

*********************************
No test configuration file found!
*********************************

Is there seriously no way to use ctest with a directory structure like above?

Keramic answered 6/2, 2019 at 10:6 Comment(4)
It could be that comp1/CMakeLists.txt disables BUILD_TESTING option, or replace add_test command. Note, that if your call include(CTest) in the subdirectory, ctest should be executed in the subdirectory too; it won't work from the top-level directory.Gunnery
How do you mean "replace add_test"?Keramic
A standard CMake command can be replaced with user-provided function or macro with the same name. E.g. one may define function(add_test). Anywhere, we could only guess what is wrong with your tests/CMakeLists.txt - you didn't show it in the question post.Gunnery
Did you try to run them using cmake --build build --target test (UNIX) ?, otherwise ctest must be run from the binary directory where enable_testing() has been call (which is done internally by the macro include(CTest)) src: gitlab.kitware.com/cmake/cmake/blob/master/Modules/…Judoka
V
18

The CTest documentation isn't the clearest.

A project I'm working on has a similar directory structure composed of various units, and in each unit are src and tests subdirectories.

CMake documentation says to call "enable_testing()" at the top-level CMakeLists.txt file, and it further says this command will "enable CTest at the current directory and below." Which sounds recursive, right? Well it's not.

Every CMakeLists.txt must have enable_testing() called to enable automatic CTest discovery in that directory.

Thus, in your project, the toplevel CMakeLists.txt will need enable_testing(), then comp{1,2}/CMakeLists.txt will need it, and finally comp{1,2}/tests/CMakeLists.txt will need it.

Once you add those commands and rerun cmake, those directories will each contain a CTestTestfile.cmake file, which is what the ctest program will look for when it runs.

Valleau answered 24/4, 2019 at 17:40 Comment(1)
Actually it is recursive. You just have to make sure to call enable_testing() before add_subdirectory. enable_testing() documentation states that This command should be in the source directory root because ctest expects to find a test file in the build directory root. You just have to make sure this is done before any add_subdirectory calls.Redevelop

© 2022 - 2024 — McMap. All rights reserved.