Ожидаемые тесты сбоя сборки в CMake

Иногда полезно проверить, что определенные вещи не могут быть построены, например:

// Next line should fail to compile: can't convert const iterator to iterator.
my_new_container_type::iterator it = my_new_container_type::const_iterator();

Можно ли включить эти типы вещей в CMake / CTest? Я ищу что-то подобное в CMakeLists.txt:

add_build_failure_executable(
test_iterator_conversion_build_failure
iterator_conversion_build_failure.cpp)
add_build_failure_test(
test_iterator_conversion_build_failure
test_iterator_conversion_build_failure)

(Конечно, насколько мне известно, эти конкретные директивы CMake не существуют.)

23

Решение

Вы можете сделать это более или менее, как вы описали. Вы можете добавить цель, которая не скомпилируется, а затем добавить тест, который вызывает cmake --build попытаться построить цель. Осталось только установить свойство test WILL_FAIL к истине.

Итак, допустим, у вас есть свои тесты в файле с именем will_fail.cpp, который содержит:

#if defined TEST1
non-compiling code for test 1
#elif defined TEST2
non-compiling code for test 2
#endif

Тогда у вас может быть что-то вроде следующего в вашем CMakeLists.txt:

cmake_minimum_required(VERSION 3.0)
project(Example)

include(CTest)

# Add a couple of failing-to-compile targets
add_executable(will_fail will_fail.cpp)
add_executable(will_fail_again will_fail.cpp)
# Avoid building these targets normally
set_target_properties(will_fail will_fail_again PROPERTIES
EXCLUDE_FROM_ALL TRUE
EXCLUDE_FROM_DEFAULT_BUILD TRUE)
# Provide a PP definition to target the appropriate part of
# "will_fail.cpp", or provide separate files per test.
target_compile_definitions(will_fail PRIVATE TEST1)
target_compile_definitions(will_fail_again PRIVATE TEST2)

# Add the tests.  These invoke "cmake --build ..." which is a
# cross-platform way of building the given target.
add_test(NAME Test1
COMMAND ${CMAKE_COMMAND} --build . --target will_fail --config $<CONFIGURATION>
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_test(NAME Test2
COMMAND ${CMAKE_COMMAND} --build . --target will_fail_again --config $<CONFIGURATION>
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
# Expect these tests to fail (i.e. cmake --build should return
# a non-zero value)
set_tests_properties(Test1 Test2 PROPERTIES WILL_FAIL TRUE)

Очевидно, что вы можете обернуть все это в функцию или макрос, если вам нужно написать много.

27

Другие решения

Ответ @ Фрейзера — хороший подход, особенно WILL_FAIL собственность хороший совет. Однако есть альтернатива превращению неудачной целевой части в основной проект. Вариант использования в вопросе в значительной степени то, что ctest --build-and-test Режим предназначен для. Вместо того, чтобы делать целевую часть с ожидаемым сбоем основной сборкой, вы можете поместить ее в отдельный отдельный мини-проект, который затем создается как часть теста. Пример того, как это может выглядеть в основном проекте, выглядит примерно так:

add_test(NAME iter_conversion
COMMAND ${CMAKE_CTEST_COMMAND}
--build-and-test
${CMAKE_CURRENT_LIST_DIR}/test_iter
${CMAKE_CURRENT_BINARY_DIR}/test_iter
--build-generator ${CMAKE_GENERATOR}
--test-command ${CMAKE_CTEST_COMMAND}
)
set_tests_properties(iter_conversion PROPERTIES WILL_FAIL TRUE)

Преимуществом этого является то, что он будет частью результатов тестирования проекта и, следовательно, с большей вероятностью будет выполняться регулярно в рамках обычных процессов тестирования. В приведенном выше примере test_iter Каталог по сути это отдельный проект. Если вам нужно передать информацию из основной сборки, вы можете сделать это, добавив --build-options определить переменные кэша для передачи в его запуск CMake. Проверить последние документы за недавно исправленную / уточненную помощь в этой области.

3

По вопросам рекламы [email protected]