我们有几个单元测试,我们希望作为构建过程的一部分运行。CMake - 运行测试作为构建过程的一部分,并将stdout输出捕获到文件中
为了达到这个目的,我有一个助手脚本,它创建一个运行测试的自定义命令,如果成功,创建一个文件"test_name.passed"
。
然后我添加一个自定义目标"test_name.run"
,这取决于"test_name.passed"
。
这个想法是,如果"test_name.passed"
不存在或者比"test_name"
旧,则将运行自定义命令。
构建将继续运行自定义命令,直到测试通过。一旦通过,后续构建将不会调用自定义命令,因此在不需要时将不会运行测试。正是
到目前为止,所有的作品中描述
下面是脚本:
# create command which runs the test and creates a sentinel file if it passes
add_custom_command(
OUTPUT ${TEST_NAME}.passed
COMMAND $<TARGET_FILE:${TEST_NAME}>
COMMAND ${CMAKE_COMMAND} -E touch ${TEST_NAME}.passed
DEPENDS ${TEST_NAME}
)
# create test.run module which depends on test.passed
add_custom_target(${TEST_NAME}.run
ALL
DEPENDS ${TEST_NAME}.passed
)
问题 - 对stdout
问题噪声是我们的测试中经常登录一吨的信息stdout
,它使一个非常嘈杂的建设。
我想现在将stdout
捕获到一个文件,并且只有在发生故障时才显示测试输出。
我的第一次尝试是尝试Bash shell脚本语法 - 将stdout
捕获到文件中,当退出状态为错误时,将该文件捕获。
add_custom_command(
OUTPUT ${TEST_NAME}.passed
COMMAND $<TARGET_FILE:${TEST_NAME}> > ${TEST_NAME}.output || cat ${TEST_NAME}.output
COMMAND ${CMAKE_COMMAND} -E touch ${TEST_NAME}.passed
DEPENDS ${TEST_NAME}
)
这不起作用,因为即使试验失败我正在创建的前哨"test_name.passed"
文件,这意味着下一次我尝试建立它认为通过测试。
可能的子标准修复
通过与ctest
积分,我可以通过CTEST运行每个测试和使用命令行选项--output-on-failure
add_custom_command(
OUTPUT ${TEST_NAME}.passed
COMMAND ctest --build-config $<CONFIGURATION> --tests-regex ${TEST_NAME} --output-on-failure
COMMAND ${CMAKE_COMMAND} -E touch ${TEST_NAME}.passed
DEPENDS ${TEST_NAME}
)
与此有两方面的问题。
- 它很大增加了构建时间。每个测试都必须通过一个单独的ctest过程来执行,所有注册的测试名称都是针对正则表达式进行解析的,等等。随着单个测试的数量的增加,我们有额外的时间大大增加。
- ctest默认输出很多噪音。指定
--quiet
标志抑制--output-on-failure
标志,因此您可以输出有噪声或无输出 - 无法仅获得失败。
问题
有没有一种方法可以达到我想要什么?
即:
- 手动运行测试(即:不通过CTEST)
- 捕获输出到文件
- 只有在指示失败的测试退出状态事件文件输出。
- 如果测试退出状态指示成功,触摸一个哨兵文件。
一个跨平台的方法的奖励点,但如果它必须只有Linux,那就这样吧。
为什么不使用ctest和cmake的集成? – fghj
@ user1034749 AFAIK ctest不会将测试作为构建的一部分运行。这是一个单独的目标'make test'。我以前使用ctest来运行每个测试('COMMAND ctest --build-config $ --tests-regex $ {TEST_NAME} --output-on-failure'),但通过ctest调用每个单元测试都会大大增加编译时间 –
@ user1034749更新了我与ctest有关的问题,以及为什么我要寻找替代方法 –