[Dependencies] CMake & CTest : make test doesn't build tests


Answers

There is actually a way to use make test. You need to define the build of the test executable as one of the tests and then add dependencies between the tests. That is:

ADD_TEST(ctest_build_test_code "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target test_code)
ADD_TEST(ctest_run_test_code test_code)
SET_TESTS_PROPERTIES ( ctest_run_test_code PROPERTIES DEPENDS ctest_build_test_code)
Question

I'm trying CTest in CMake in order to automatically run some of my tests using make test target. The problem is CMake does not "understand" that the test I'm willing to run has to be built since it is part of the project.

So I'm looking for a way to explicitly specify this dependency.




There is actually a way to use make test. You need to define the build of the test executable as one of the tests and then add dependencies between the tests. That is:

ADD_TEST(ctest_build_test_code "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target test_code)
ADD_TEST(ctest_run_test_code test_code)
SET_TESTS_PROPERTIES ( ctest_run_test_code PROPERTIES DEPENDS ctest_build_test_code)






cmake generate test data

Yes it is possible at all. CMake can add dependencies between targets and files and those files needs not to be source files.

Your code steps looks good (I didn't build it) but I assume what is missing is the build of the test.

And I use add_custom_target instead of add_custom_command.

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.12)
add_library(mylib SHARED mylib.cpp)

# Create out.dat as an example 
add_custom_target(testfile_outdat COMMAND touch out.dat)

add_executable(mytest mytest.cpp)
target_link_libraries(mytest mylib)
add_dependencies(mytest testfile_outdat)
add_test(NAME mytest COMMAND mytest)

This example generates the code while make is executed. This solution fits in case the data are not modified by tests.

The test data creation depends on made of target mytest, but not of the declaration that mytest is to be used as test

Depending on the commands to create the test data file, some platform specific stuff could be possible. Thus you can create different custom_targets depending on the platform to support.

mylib.h

bool compare(int a, int b);

mylib.cpp

#include "mylib.h"
bool compare(int a, int b)
{
    return a == b;
}

mytest.cpp

#include <stdio.h>
#include "mylib.h"
int main(int arcc, char* argv[])
{
    bool actual = compare(1, 1);
    bool expected = true;
    printf("Testresult %s\n", (actual == expected) ? "OK" : "Failed");
    return 0;
}



I use a variant of richq's answer. In the top-level CMakeLists.txt, I add a custom target, build_and_test, for building and running all tests:

find_package(GTest)
if (GTEST_FOUND)
    enable_testing()
    add_custom_target(build_and_test ${CMAKE_CTEST_COMMAND} -V)
    add_subdirectory(test)
endif()

In the various sub-project CMakeLists.txt files under test/, I add each test executable as a dependency of build_and_test:

include_directories(${CMAKE_SOURCE_DIR}/src/proj1)
include_directories(${GTEST_INCLUDE_DIRS})
add_executable(proj1_test proj1_test.cpp)
target_link_libraries(proj1_test ${GTEST_BOTH_LIBRARIES} pthread)
add_test(proj1_test proj1_test)
add_dependencies(build_and_test proj1_test)

With this approach, I just need to make build_and_test instead of make test (or make all test), and it has the benefit of only building test code (and its dependencies). It's a shame I can't use the target name test. In my case, it's not so bad because I have a top-level script that does out-of-tree debug and release (and cross-compiled) builds by calling cmake and then make, and it translates test into build_and_test.

Obviously, the GTest stuff isn't required. I just happen to use/like Google Test, and wanted to share a complete example of using it with CMake/CTest. IMHO, this approach also has the benefit of allowing me to use ctest -V, which shows the Google Test output while the tests run:

1: Running main() from gtest_main.cc
1: [==========] Running 1 test from 1 test case.
1: [----------] Global test environment set-up.
1: [----------] 1 test from proj1
1: [ RUN      ] proj1.dummy
1: [       OK ] proj1.dummy (0 ms)
1: [----------] 1 test from proj1 (1 ms total)
1:
1: [----------] Global test environment tear-down
1: [==========] 1 test from 1 test case ran. (1 ms total)
1: [  PASSED  ] 1 test.
1/2 Test #1: proj1_test .......................   Passed    0.03 sec



CMake & CTest : make test doesn't build tests

It is arguably a bug in CMake (previously tracked here) that this doesn't work out of the box. A workaround is to do the following:

add_test(TestName ExeName)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
                  DEPENDS ExeName)

Then you can run make check and it will compile and run the test. If you have several tests, then you would have to use DEPENDS exe1 exe2 exe3 ... in the above line.