首页 > 解决方案 > ctest:默认禁用一组标记测试 - 但在明确定位时运行它们

问题描述

我想默认禁用一组测试,但能够在明确定位时运行它们。

例如,假设我有一个项目,其中包含许多通过add_test(NAME SomeNameHere COMMAND SomeCommandHere)命令添加的快速运行的单元测试。并且进一步假设还有一堆长时间运行的集成测试应该从默认ctest运行中排除,但是当明确定位时应该可以使用单个命令运行所有集成测试。

作为一个具体的例子:

这是我实现这一目标的尝试。

cmake_minimum_required (VERSION 3.1)
project (HOW_TO_RUN_DISABLED_TESTS NONE)
enable_testing()

# Add a fast running test
# This test should be run when a user runs: 'ctest'
add_test(NAME TestThatShouldAlwaysRun COMMAND echo 'I am always enabled')

# Add a long-running integration test
# This test should be run when a user runs: 'ctest --label-regex my_integration_tests'
add_test(NAME FooIntegrationTest COMMAND echo 'Foo integration test')
set_tests_properties(FooIntegrationTest PROPERTIES DISABLED True)
set_tests_properties(FooIntegrationTest PROPERTIES LABELS my_integration_tests)

# Add another long-running integration test
# This test should be run when a user runs: 'ctest --label-regex my_integration_tests'
add_test(NAME BarIntegrationTest COMMAND echo 'Bar integration test')
set_tests_properties(BarIntegrationTest PROPERTIES DISABLED True)
set_tests_properties(BarIntegrationTest PROPERTIES LABELS my_integration_tests)

现在,让我们通过

$ mkdir build
$ cd build/
$ cmake ..
$ ctest -V

正如我们在输出(下面发布)中看到的那样,ctest确实排除了集成测试(太棒了!)。

1: Test command: /bin/echo "'I" "am" "always" "enabled'"
1: Test timeout computed to be: 10000000
1: 'I am always enabled'
1/3 Test #1: TestThatShouldAlwaysRun ..........   Passed    0.00 sec
test 2
    Start 2: FooIntegrationTest
2/3 Test #2: FooIntegrationTest ...............***Not Run (Disabled)   0.00 sec
test 3
    Start 3: BarIntegrationTest
3/3 Test #3: BarIntegrationTest ...............***Not Run (Disabled)   0.00 sec

100% tests passed, 0 tests failed out of 1

Label Time Summary:
my_integration_tests    =   0.00 sec*proc (2 tests)

Total Test time (real) =   0.05 sec

The following tests did not run:
      2 - FooIntegrationTest (Disabled)
      3 - BarIntegrationTest (Disabled)

但是,我无法弄清楚我现在如何通过ctest运行标记为 的测试my_integration_tests

ctest --label-regex my_integration_tests
Test project /path/to/code/example_repo/build
    Start 2: FooIntegrationTest
1/2 Test #2: FooIntegrationTest ...............***Not Run (Disabled)   0.00 sec
    Start 3: BarIntegrationTest
2/2 Test #3: BarIntegrationTest ...............***Not Run (Disabled)   0.00 sec
No tests were found!!!

有没有办法在明确定位时运行禁用的测试?

我探索了其他方法,例如

标签: cmakectest

解决方案


我相信更简单的方法是通过 cmake 配置选项。

# cat CMakeLists.txt 
cmake_minimum_required (VERSION 3.1)
project (HOW_TO_RUN_DISABLED_TESTS NONE)
enable_testing()
add_test(NAME TestThatShouldAlwaysRun COMMAND echo 'I am always enabled')
if(BUILD_INTEGRATION_TESTING)
   add_test(NAME FooIntegrationTest COMMAND echo 'Foo integration test')
   add_test(NAME BarIntegrationTest COMMAND echo 'Bar integration test')
endif()

这很简单,也更灵活,即。允许为这些测试添加依赖于测试的目标(和设置(以及要使用的 ctest 固定装置))。(我通常在项目中看到像这样命名SOMETHING_BUILD_TESTING的变量,所以它类似于BUILD_TESTINGcmake 变量。)

我的另一个想法是使用环境变量并将测试包装在一个脚本中SKIP_RETURN_CODE(或者甚至没有SKIP_RETURN_CODE,如果不应该运行集成测试,则返回成功):

add_test(NAME FooIntegrationTest 
        COMMAND sh -c "if [ \"\${RUN_INTEGRATION:-}\" ]; then echo 'Foo integration test'; else exit 127; fi"
        VERBATIM)
set_tests_properties(FooIntegrationTest PROPERTIES 
        SKIP_RETURN_CODE 127)

然后:

$ ctest -V
....
2: Test command: /usr/bin/sh "-c" "if [ "${RUN_INTEGRATION:-}" ]; then echo 'Foo integration test'; else exit 127; fi" "VERBATIM"
2: Test timeout computed to be: 10000000
2/3 Test #2: FooIntegrationTest ...............***Skipped   0.01 sec
....
The following tests did not run:
      2 - FooIntegrationTest (Skipped)

但:

$ RUN_INTEGRATION=TRUE ctest -V
...
2: Test command: /usr/bin/sh "-c" "if [ "${RUN_INTEGRATION:-}" ]; then echo 'Foo integration test'; else exit 127; fi" "VERBATIM"
2: Test timeout computed to be: 10000000
2: Foo integration test
2/3 Test #2: FooIntegrationTest ...............   Passed    0.01 sec
...

推荐阅读