如果目标未构建,则跳过 CTest

rgo*_*gov 2 cmake

在 CMake 中,可以使用默认情况下add_subdirectory(foo EXCLUDE_FROM_ALL)排除下面定义的目标,除非某些其他目标需要它们,如下所示:foo

add_subdirectory(foo EXCLUDE_FROM_ALL)
add_custom_target(wanted_foo_targets ALL DEPENDS
  bar_tool  # only build bar_tool from foo
)
Run Code Online (Sandbox Code Playgroud)

假设foo定义了两个目标bar_toolfoo_tool,并对每个目标进行测试:

add_test(NAME test_foo_tool COMMAND foo_tool) 
add_test(NAME test_bar_tool COMMAND bar_tool) 
Run Code Online (Sandbox Code Playgroud)

当您构建整个项目时,foo_tool不是构建,因为它不是任何东西的依赖项,而是bar_tool构建,因为它是wanted_foo_targets.

但 CTest 仍然注册该test_foo_tool工具,但现在由于foo_tool不存在而失败。

我可以删除/隐藏/跳过引用未构建的目标的测试吗?我知道我可以编写类似的测试命令,[ -f foo_tool ] && foo_tool但这会错误地表明测试已通过。

如果我可以从父目录执行此操作,而不修改内部测试的设置方式,那就加分了foo。就我而言,foo这是一个由第三方提供的项目,我不想在他们编写新测试时维护他们的代码补丁。

sak*_*kra 5

这可以通过将SKIP_RETURN_CODE测试属性与小型测试驱动程序脚本(您已经考虑使用)结合使用来完成。

在源代码目录中添加一个测试驱动脚本,命名test_driver.sh为以下内​​容:

#!/bin/sh
if [ -x "$1" ] ; then exec "$1" ; else exit 127 ; fi
Run Code Online (Sandbox Code Playgroud)

该脚本检查作为第一个参数传递的测试可执行文件是否存在,如果不存在则退出并显示错误代码 127(也称为“命令未找到”)。

在 CMakeLists.txt 中按以下方式添加测试:

add_test(NAME test_foo_tool COMMAND "${CMAKE_SOURCE_DIR}/test_driver.sh" $<TARGET_FILE:foo_tool>)
set_tests_properties(test_foo_tool PROPERTIES SKIP_RETURN_CODE 127)
Run Code Online (Sandbox Code Playgroud)

当您在缺少可执行文件的情况下运行测试时foo_tool,ctest 会将其报告test_foo_tool为跳过的测试,而不是失败的测试。

$ ctest 
...
    Start 1: test_foo_tool
1/2 Test #1: test_foo_tool ....................***Skipped   0.01 sec
    Start 2: test_bar_tool
2/2 Test #2: test_bar_tool ....................   Passed    0.01 sec

100% tests passed, 0 tests failed out of 2

Total Test time (real) =   0.03 sec

The following tests did not run:
      1 - test_foo_tool (Skipped)
Run Code Online (Sandbox Code Playgroud)