CMake - 作为构建过程的一部分运行测试并将标准输出捕获到文件

2024-05-12

我们有几个单元测试,我们希望将其作为构建过程的一部分运行。

为了实现这一目标,我有一个帮助程序脚本,它创建一个运行测试的自定义命令,如果成功,则创建一个文件"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 脚本语法 - capturestdout到一个文件中,当退出状态为错误时,cat 该文件。

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}
    )

这样做的问题有两个。

  1. It vastly增加构建时间。每个测试都必须通过单独的 ctest 进程执行,所有注册的测试名称都根据正则表达式进行解析,等等。随着单独测试的数量增加,我们的额外时间会增加很多。
  2. ctest 默认输出大量噪声。指定--quiet标志抑制--output-on-failure标志,因此您可以有嘈杂的输出或没有输出 - 没有办法只得到失败。

Question

有办法实现我想要的吗?

ie:

  • 手动运行测试(即:不通过 ctest)
  • 将输出捕获到文件中
  • 仅在测试退出状态指示失败时输出该文件。
  • 如果测试退出状态指示成功,请触摸哨兵文件。

跨平台方法的优点是,但如果它只能是 Linux,那就这样吧。


问题是没有标准方法来重定向通过调用的命令的输出add_custom_command到一个文件。 CMake 命令execute_process但确实有这个能力。

因此,一个可能的解决方案是从配置的 CMake 脚本运行测试可执行文件,该脚本本身作为 CMake 自定义命令运行。以下代码概述了必要的步骤:

In your CMakeLists.txt添加测试,配置 CMake 脚本模板:

configure_file("test_runner.cmake.in" "test_runner_${TEST_NAME}.cmake" @ONLY)

然后添加自定义命令以在构建时调用脚本:

add_custom_command(
    OUTPUT  ${TEST_NAME}.passed
    COMMAND ${CMAKE_COMMAND} -P "test_runner_${TEST_NAME}.cmake" $<TARGET_FILE:${TEST_NAME}>
    DEPENDS ${TEST_NAME}
    WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")

测试可执行文件的实际路径通过生成器表达式作为参数传递给脚本。

模板测试运行脚本test_runner.cmake.in运行测试可执行文件execute_process并将错误输出重定向到日志文件:

set (_testExecutable "${CMAKE_ARGV3}")
execute_process(COMMAND ${_testExecutable} ERROR_FILE "@[email protected] /cdn-cgi/l/email-protection" RESULT_VARIABLE _testResult)
if (_testResult)
    file(REMOVE "@[email protected] /cdn-cgi/l/email-protection")
    file(READ "@[email protected] /cdn-cgi/l/email-protection" _contents)
    message (STATUS "${_contents}")
else()
    file(WRITE "@[email protected] /cdn-cgi/l/email-protection" "")
endif()

如果测试失败,脚本将删除哨兵文件并输出错误日志。 如果测试成功,脚本将创建哨兵文件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMake - 作为构建过程的一部分运行测试并将标准输出捕获到文件 的相关文章

  • 正确的单元测试技术

    在使用 TDD 时 我发现自己需要测试一个包含查找值的常量 最终 哈希图 请查看更新中出现这种情况的原因 见下文 private static final Map
  • 我应该更改单元测试的命名约定吗?

    我目前对单元测试使用一个简单的约定 如果我有一个名为 EmployeeReader 的类 我将创建一个名为 EmployeeReader Tests 的测试类 然后 我在测试类中为该类创建所有测试 名称如下 Reading Valid Em
  • 是否有可能改变整个恐慌消息?

    NUnit 是一个 C 单元测试框架 允许您编写如下代码 Assert That someInt Is EqualTo 42 Assert That someList Has Member someMember 我喜欢这种代码 因为它看起来
  • Python 的最佳实践:assert command() == False [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何将 ZF2 单元/应用程序模块测试合并到单个调用中?

    我遵循将测试存储在模块中的 ZF2 约定 并且当从每个模块内运行测试时一切正常 我想做的是有一个根级别的 phpunit xml 来调用各个模块测试并将它们合并以生成代码覆盖率数据和其他指标 问题是每个单独的测试套件都是在模块化 phpun
  • 在 Ubuntu 16.04 上编译 PCL 1.7,CMake 生成的 Makefile 中出现错误

    我正在尝试让 PCL 1 7 点云库 而不是其他 pcl 在 Ubuntu 16 04 上运行 我最终希望用于 C 的东西 但现在我只是想让这些例子工作 我使用的是 Ubuntu GNU 5 3 1 附带的默认编译器和 Cmake 版本 3
  • 模拟 ScheduledExecutorService.scheduleWithFixedDelay(...) 返回 null

    在我的单元测试中 我注入了一个模拟实例ScheduledExecutoryService类进入我正在尝试测试的类 以便当scheduleAtFixedRate 方法被调用 它返回一个模拟的Future 但出于某种原因 它总是会回来null
  • 在 MAC OSX 上使用 CMake 生成 .bundle 文件

    我想生成一个可执行文件 bundle文件于Mac OSX 10 6 8 using CMake 我的 CMakeLists txt 文件如下所示 cmake minimum required VERSION 2 8 PROJECT TEST
  • 在cmake中设置PKG_CONFIG_PATH

    我已经在本地构建了 opencv 并将其安装到本地目录 不是系统默认目录 opencv pc存在于该本地文件夹中的 pkgconfig 文件夹下 我怎样才能找到这个opencv pc来自 cmake 因为我想从我的程序链接并包含 openc
  • HttpContext 中需要什么才能允许 FormsAuthentication.SignOut() 执行?

    我正在尝试为我们的注销方法编写一个单元测试 除其他外 它FormsAuthentication SignOut 然而 它抛出一个System NullReferenceException 我创建了一个模拟 HttpContext 使用起订量
  • Autofixture 和 WebApi 控制器

    我正在使用 AutoFixture 尝试测试 WebApi 站点的控制器 我正在将 AutoData 功能与 Moq 一起使用 如上所述普洛的博客 http blog ploeh dk 2010 10 08 AutoDataTheories
  • 在 CMake 中,CHECK_INCLUDE_FILE_CXX 如何工作?

    以下代码不打印任何内容 CHECK INCLUDE FILE CXX glog logging h GLOG INCLUDE IF GLOG INCLUDE MESSAGE YY ENDIF GLOG INCLUDE 但我设置了以下环境变量
  • 这可以用 Moq 来嘲笑吗?

    我正在努力模拟一些外部依赖项 并且在一个第三方类中遇到了麻烦 该类在其构造函数中接收另一个第三方类的实例 希望 SO 社区能给我一些指导 我想创建一个模拟实例SomeRelatedLibraryClass它的构造函数接受一个模拟实例Some
  • 如何将 gnatmake/gnatbind/gnatlink 集成到 C/Ada 代码的 CMake 文件中?

    我用几种语言 C C Fortran77 Fortran90 编写了代码 并且可以使用 CMake 编译它 没有任何问题 效果很完美 现在 我想在用 C 编写的 main 中添加一些 Ada 函数 并且我想通过 CMake 编译它 鉴于我无
  • 如何判断给定目标是库还是可执行文件?

    内置功能install TARGETS 将库目标安装到可执行目标之外的其他位置 我想做类似的事情 给定目标名称列表 我想将其中的所有库目标添加到列表变量中 并将所有运行时目标添加到另一个变量中 我找不到 CMake 的默认目标属性列表 但我
  • 如何使用 CMake 安装文件层次结构?

    我使用以下方法创建了文件列表 file GLOB RECURSE DEPLOY FILES PROJECT SOURCE DIR install 我想将所有这些文件安装在 usr myproject 但我想维护已安装文件夹上的文件树 ins
  • 模拟 DBSet,EF 模型优先

    正如标题所说 我遵循模型优先方法 所以我的模型类是自动生成的 如果我想嘲笑DBContext衍生的MyModelContainer其中包含DBSets实体类 阅读一些内容 为了进行单元测试 您需要将其更改为IDBSet 是否可以做到这一点
  • 对 Java Servlet 进行单元测试

    我想知道对 servlet 进行单元测试的最佳方法是什么 只要内部方法不引用 servlet 上下文 测试内部方法就不是问题 但是测试 doGet doPost 方法以及引用上下文或使用会话参数的内部方法呢 有没有办法简单地使用经典工具 例
  • Clang 与 CLion:无法获取编译器信息

    我尝试通过更改在 CLion 中从 gcc 切换到 clang工具链偏爱 但现在 cmake 失败并显示以下内容 Cannot get compiler information Compiler exited with error code
  • 如何在android sdk上使用PowerMock

    我想为我的 android 项目编写一些单元测试和仪器测试 然而 我遇到了一个困扰我一段时间的问题 我需要模拟静态方法并伪造返回值来测试项目 经过一些论坛的调查 唯一的方法是使用PowerMock来模拟静态方法 这是我的 gradle 的一

随机推荐