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

时间:2019-02-04 23:42:13

标签: cmake

在CMake中,可以使用add_subdirectory(foo EXCLUDE_FROM_ALL)从默认情况下不构建foo下定义的目标。除非,某些其他目标需要它们,例如:< / p>

add_subdirectory(foo EXCLUDE_FROM_ALL)
add_custom_target(wanted_foo_targets ALL DEPENDS
  bar_tool  # only build bar_tool from foo
)

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

add_test(NAME test_foo_tool COMMAND foo_tool) 
add_test(NAME test_bar_tool COMMAND bar_tool) 

在构建整个项目时,foo_tool不会构建,因为它不是任何依赖关系,而bar_tool则会构建是因为它是wanted_foo_targets的依赖关系。

但是CTest仍然注册了test_foo_tool工具,该工具现在失败了,因为foo_tool不存在。

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

如果我可以在不修改foo内部测试设置的情况下从父目录执行此操作,则该奖励指向。就我而言,foo是由第三方提供的项目,在他们编写新测试时,我不想维护他们的代码补丁。

2 个答案:

答案 0 :(得分:1)

可以通过设置相关测试的DISABLED属性来禁用测试。 您还可以通过检查TESTS属性来获得在子目录中定义的测试的列表。

因此,您应该能够使用get_property来获取该特定目录的所有测试的列表,然后禁用所有测试。如果仅需要禁用测试的子集,则使用list(FILTER)筛选所有需要禁用的测试列表。仅在遵循命名约定的情况下,这才方便。

很遗憾,set_property只能在同一目录而不是子目录中修改测试的属性。这意味着将需要更新CMakeLists.txt文件。

或者,如果修改CMakeLists.txt太多了,那就不要运行这些测试。这可以通过使用ctest -E regex选项排除那些测试来完成。

答案 1 :(得分:1)

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

在源代码目录中,添加一个名为test_driver.sh的测试驱动程序脚本,其内容如下:

#!/bin/sh
if [ -x "$1" ] ; then exec "$1" ; else exit 127 ; fi

该脚本检查是否存在作为第一个参数传递的测试可执行文件,如果不存在则以错误代码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)

在缺少可执行文件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)