CMake 中预期的构建失败测试
Expected build-failure tests in 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 指令并不存在。)
您可以或多或少地按照您的描述进行操作。您可以添加一个编译失败的目标,然后添加一个调用 cmake --build
的测试来尝试构建目标。剩下的就是将测试 属性 WILL_FAIL
设置为 true.
因此,假设您在名为 "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)
如果你有很多这样的东西要写的话,你显然可以把所有这些都包装成一个函数或宏。
@Fraser 的回答是一个好方法,特别是 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 运行 的缓存变量来实现。查看 latest docs 最近 corrected/clarified 关于此领域的帮助。
有时检查某些东西是否构建失败是很好的,例如:
// 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 指令并不存在。)
您可以或多或少地按照您的描述进行操作。您可以添加一个编译失败的目标,然后添加一个调用 cmake --build
的测试来尝试构建目标。剩下的就是将测试 属性 WILL_FAIL
设置为 true.
因此,假设您在名为 "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)
如果你有很多这样的东西要写的话,你显然可以把所有这些都包装成一个函数或宏。
@Fraser 的回答是一个好方法,特别是 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 运行 的缓存变量来实现。查看 latest docs 最近 corrected/clarified 关于此领域的帮助。