ctest: по умолчанию отключить набор помеченных тестов, но запускать их при явном назначении - PullRequest
2 голосов
/ 03 мая 2020

Я бы хотел отключить набор тестов по умолчанию, но иметь возможность запускать их при явном назначении.

Например, предположим, у меня есть проект с большим количеством быстродействующих модульных тестов, которые были добавлены с помощью команды add_test(NAME SomeNameHere COMMAND SomeCommandHere). И предположим далее, что есть также куча длительных интеграционных тестов, которые должны быть исключены из запуска по умолчанию ctest, но должна быть возможность запускать все интеграционные тесты с помощью одной команды, когда требуется расширение.

В качестве конкретного примера:

  • TestThatShouldAlwaysRun - я бы хотел, чтобы это запускалось, когда пользователь запускает $ ctest
  • FooIntegrationTest - я бы хотел, чтобы это выполнялось только , когда пользователь запускает $ ctest --some-option-here integration
  • BarIntegrationTest - я бы хотел, чтобы он запускал только , когда пользователь запускает $ ctest --some-option-here integration

Вот моя попытка достичь этого.

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!!!

Есть ли способ запустить отключенные тесты при явном нацеливании?

Я исследовал другие способы, такие как

  • Не отключать целое число Активные тесты. Затем, когда пользователь хочет запустить быстрые тесты, ему нужно указать ctest --label-exclude my_integration_tests. Что не здорово. Это мешает каждому помнить это. Мне бы хотелось, чтобы наиболее часто используемые опции (запускающие только быстродействующие тесты) были запущены через ctest.
  • Не отключая интеграционные тесты, а предоставив аргумент CONFIGURATIONS my_integration_tests для add_test вызов. Но я думаю, что таким образом я семантически злоупотребляю CONFIGURATIONS. Кроме того, это не позволяет мне запускать интегральный тест only , если намечен.
  • Добавить интеграционные тесты через add_custom_target. Также здесь я думаю, что я неправильно использую API. add_custom_target предназначен для пользовательских целей, а не для запуска теста, верно?

1 Ответ

2 голосов
/ 03 мая 2020

Я полагаю, что более простой способ сделать это - просто с помощью опции конфигурации 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()

Это просто и более гибко, ie. позволяет добавлять тест-зависимые цели для сборки (и настройки (и использования тестовых устройств ctest)) для этих тестов. (Обычно в проектах я вижу переменные с именами, например SOMETHING_BUILD_TESTING, поэтому она похожа на BUILD_TESTING переменную cmake.)

Еще одна идея, которая у меня есть, - использовать переменную окружения и обернуть тест в сценарии с помощью 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
...
...