CTest根本没有缺陷,但是您使用 CMake 和 CTest 的方式似乎“有缺陷”。命令行界面 (CLI) 工具ctest
的调用通常与 CMake 构建目标的调用无关(除了 target test
)。
在我看来,不应使用CMake Wikicheck
中描述的自定义目标解决方案,因为它会更改 CMake 的默认行为并且不可配置。
相反,应使用以下使用内置选项的BUILD_TESTING
方法:
include(CTest)
if(BUILD_TESTING)
find_package(GTest MODULE REQUIRED)
add_executable(example_test example_test.cpp)
target_link_libraries(
example_test
PRIVATE
GTest::GTest
GTest::Main
)
add_test(NAME example_test COMMAND example_test)
endif()
include(CTest)
在option BUILD_TESTING
中定义,允许控制是否构建项目的所有测试。
引用官方文档:
enable_testing()
只有当命令被调用时,CMake 才会生成测试。该模块在选项CTest
为时自动调用命令。BUILD_TESTING
ON
以上可以在 CLI 上使用,如下所示:
创建测试(默认):
cmake -Hexample-testing -B_builds/example-testing/release -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
cmake --build _builds/example-testing/release --config Release
在这种情况下,命令cd _builds/example-testing/release
和ctest
/cmake --build . --target test
构建并运行测试。
不要创建测试,设置-DBUILD_TESTING=OFF
:
cmake -Hexample-testing -B_builds/example-testing/release-no-tests -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF
cmake --build _builds/example-testing/release-no-tests --config Release
在这种情况下,命令cd _builds/example-testing/release-no-tests
并ctest
不会运行任何测试,因为没有构建任何测试。该命令cmake --build . --target test
失败,因为它尚未在 CMake 的配置阶段创建。
我们在这里只是触及表面。请参阅ctest --help
,例如,有很多--build-<...>
选项可以更好地控制测试/构建,尽管我对此没有任何经验。
我强烈建议阅读以下内容:
如果您真的想启用测试构建,但通过默认情况下不调用的单独目标并且不是通过 CTest 而是直接运行测试,您可以执行以下操作:
include(CTest)
if(BUILD_TESTING)
find_package(GTest MODULE REQUIRED)
option(
BUILD_TESTING_EXCLUDE_FROM_ALL
"Do not build the testing tree together with the default build target."
OFF
)
if(BUILD_TESTING_EXCLUDE_FROM_ALL)
set(add_executable_args_for_test EXCLUDE_FROM_ALL)
endif()
# The "build_test" target is used to build all test executables.
add_custom_target(
build_test
# Workaround for printing the COMMENT, it does not work without a NOOP
# COMMAND.
COMMAND ${CMAKE_COMMAND} -E echo
COMMENT "Building tests..."
VERBATIM
)
add_executable(example_test ${add_executable_args_for_test} example_test.cpp)
target_link_libraries(
example_test
PRIVATE
GTest::GTest
GTest::Main
)
add_test(NAME example_test COMMAND example_test)
add_dependencies(build_test example_test)
# The "check" target is used to build AND run all test executables.
add_custom_target(
check
# Either invoke the test(s) indirectly via "CTest" (commented) or directly.
# COMMAND ${CMAKE_CTEST_COMMAND}
COMMAND example_test
COMMENT "Building and running test..."
VERBATIM
)
# Alternative to the COMMAND in the add_custom_target. Leads to the same
# behavior as calling "CTest" directly.
# add_custom_command(
# TARGET check
# COMMAND ${CMAKE_COMMAND} ARGS --build ${CMAKE_BINARY_DIR} --target test
# VERBATIM
# )
add_dependencies(check build_test)
endif()
- 请注意,上面的代码不是
test
为了运行测试而调用 CTest 或目标,而是直接调用测试。
- 请阅读与问题中描述的方法类似的使用 CTest 的替代方法的注释和注释代码。
- 增强上述代码以支持多个测试可执行文件很容易。
恕我直言,Kitware 应该删除整个 CMake Wiki,因为 Wiki 几乎只包含 CMake 版本 < 3.0 的过时信息。其中的大多数信息都不能被视为Modern CMake。