关于依赖项:CMake和CTest:make测试未构建测试

CMake & CTest : make test doesn't build tests

我正在CMake中尝试CTest,以便使用make test目标自动运行某些测试。 问题在于CMake不能"理解"我愿意运行的测试,因为它是项目的一部分,因此必须进行构建。

因此,我正在寻找一种明确指定此依赖性的方法。


可以说这是CMake的一个错误(以前在这里跟踪),它无法立即使用。解决方法是执行以下操作:

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

然后,您可以运行make check,它将编译并运行测试。如果您有多个测试,则必须在上一行中使用DEPENDS exe1 exe2 exe3 ...


实际上,有一种使用make test的方法。您需要将测试可执行文件的构建定义为测试之一,然后在测试之间添加依赖项。那是:

1
2
3
4
5
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)


我使用richq的答案的变体。在顶级CMakeLists.txt中,我添加了一个自定义目标build_and_test,用于构建和运行所有测试:

1
2
3
4
5
6
find_package(GTest)
if (GTEST_FOUND)
    enable_testing()
    add_custom_target(build_and_test ${CMAKE_CTEST_COMMAND} -V)
    add_subdirectory(test)
endif()

test/下的各个子项目CMakeLists.txt文件中,我将每个测试可执行文件添加为build_and_test的依赖项:

1
2
3
4
5
6
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)

使用这种方法,我只需要make build_and_test而不是make test(或make all test),它的好处是仅构建测试代码(及其依赖项)。可惜我不能使用目标名称test。就我而言,这还不错,因为我有一个顶级脚本,该脚本先通过调用cmake然后是make进行树外调试和发布(以及交叉编译)构建,然后转换为test进入build_and_test

显然,不需要GTest东西。我只是碰巧使用/喜欢Google Test,并想与CMake / CTest共享使用它的完整示例。恕我直言,这种方法还有一个好处,就是允许我使用ctest -V,它在测试运行时显示了Google Test的输出:

1
2
3
4
5
6
7
8
9
10
11
12
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


如果您尝试模拟make check,则可能会发现此Wiki条目很有用:

http://www.cmake.org/Wiki/CMakeEmulateMakeCheck

我刚刚检查了它是否成功说明了问题(CMake 2.8.10)。


避免头痛:

1
make all test

对于我来说,它是开箱即用的,并且会在运行测试之前建立依赖关系。考虑到这很简单,它几乎使本机make test功能变得很方便,因为即使您的代码已损坏,它也使您可以选择运行最后的编译测试。


如果您使用的是CMake> = 3.7,则建议的方法是使用灯具:

1
2
3
4
5
6
7
8
9
10
add_executable(test test.cpp)
add_test(test_build
 "${CMAKE_COMMAND}"
  --build"${CMAKE_BINARY_DIR}"
  --config"$<CONFIG>"
  --target test
)
add_test(test test)
set_tests_properties(test       PROPERTIES FIXTURES_REQUIRED test_fixture)
set_tests_properties(test_build PROPERTIES FIXTURES_SETUP    test_fixture)


这是我锤击并一直使用的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
set(${PROJECT_NAME}_TESTS a b c)

enable_testing()
add_custom_target(all_tests)
foreach(test ${${PROJECT_NAME}_TESTS})
        add_executable(${test} EXCLUDE_FROM_ALL ${test}.cc)
        add_test(NAME ${test} COMMAND $<TARGET_FILE:${test}>)
        add_dependencies(all_tests ${test})
endforeach(test)

build_command(CTEST_CUSTOM_PRE_TEST TARGET all_tests)
string(CONFIGURE "@CTEST_CUSTOM_PRE_TEST@" CTEST_CUSTOM_PRE_TEST_QUOTED ESCAPE_QUOTES)
file(WRITE"${CMAKE_BINARY_DIR}/CTestCustom.cmake""set(CTEST_CUSTOM_PRE_TEST ${CTEST_CUSTOM_PRE_TEST_QUOTED})""
"
)

青年汽车


以上所有答案都是完美的。但是实际上CMake使用CTest作为其测试工具,因此执行任务的标准方法(我认为是)是:

1
2
3
enable_testing ()
add_test (TestName TestCommand)
add_test (TestName2 AnotherTestCommand)

然后运行cmake并建立目标。之后,您可以运行make test,也可以只运行

1
ctest

您将得到结果。这是在CMake 2.8下测试的。

在以下位置检查详细信息:http://cmake.org/Wiki/CMake/Testing_With_CTest#Simple_Testing


所有答案都是好的,但是它们暗示违反了通过命令make test进行测试的传统。我已经完成了这个技巧:

1
2
3
add_test(NAME <mytest>
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND sh -c"make <mytarget>; $<TARGET_FILE:<mytarget>>")

这意味着测试由构建(可选)和运行可执行目标组成。