Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CTest add tests in subdirectories

Tags:

cmake

ctest

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?

like image 468
Georg P. Avatar asked Feb 06 '19 10:02

Georg P.


1 Answers

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.

like image 109
BPB Avatar answered Sep 30 '22 11:09

BPB