首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >"ctest“与"make check":糟糕的构建时间与失败的选项传递

"ctest“与"make check":糟糕的构建时间与失败的选项传递
EN

Stack Overflow用户
提问于 2016-06-04 06:24:12
回答 2查看 2K关注 0票数 3

要在CMake下注册测试,我们需要

代码语言:javascript
运行
复制
enable_testing()

代码语言:javascript
运行
复制
include(CTest)

然后对每个单独的测试(名称fooTest,可执行foo)

代码语言:javascript
运行
复制
add_executable(foo <foo_sources>)
add_test(fooTest foo)

然后可以使用命令ctest运行测试。

此外,我们可以使用命令make check运行测试,只要我们添加一次

代码语言:javascript
运行
复制
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})

对于每个测试,我们都通过关键字EXCLUDE_FROM_ALL和命令add_dependencies扩展上面的内容。

代码语言:javascript
运行
复制
add_executable(foo EXCLUDE_FROM_ALL <foo_sources>)
add_test(fooTest foo)
add_dependencies(check foo)

理想情况下,这将使make check成为ctest的别名。它不这样做至少有两个原因:

(1) make check存在缺陷,因为它没有将选项传递给ctest 2。特别是,ctest -j4将并行运行4个测试,而make -j4 check将在目标check上运行一个线程,而其他三个线程将保持空闲状态。

(2) ctest存在缺陷3,4,因为所有测试都是在all目标下构建的,即与主要应用程序一起构建。在某些情况下,这可能是期望的行为,但在其他情况下,应该可以将构建推迟到测试运行。

这是否正确地概括了目前的状况?

有没有办法(吃蛋糕,吃蛋糕)?

1 2 3. 4.

EN

回答 2

Stack Overflow用户

发布于 2016-06-06 08:44:10

首先,让我指出,对于简单的测试任务,ctestmake test只是简单的命令行工具。如果您想要一个用于严肃测试的工具,请使用CDash、Buildbot、Jenkins或其他任何工具。

关于CTest的缺陷:对CTest的调用没有构建测试,这是有意的。在几种情况下,这是个坏主意:

  • 编译测试需要更多的资源,然后运行测试本身。对于内存消耗、对硬盘的读/写或编译时间来说,这可能是正确的。因此,并行编译和链接可能是不好的,但是并行执行测试可能是有益的。
  • 如何处理编译或链接失败?报告失败了吗?报告是不编制的吗?继续编译其他测试还是立即中止?

汽车工具是以你想要的方式做的,人们也习惯了它。但是为什么它应该是一个单位呢?为什么不有两个命令呢?混合两个任务并使有特殊需求的项目更加困难的好处是什么?

最后,我创建了一个目标build-tests或类似的目标,并按照CMake开发人员的决定将构建测试与执行测试分离开来。然后,我可以决定是否需要并行构建,如何处理编译失败(例如,传递-k来创建)等等。

唯一的缺点是,这个目标只存在于顶层目录中,不能在子目录中使用。

要获得CMake内置的这样一个目标,将是一个很好的特性请求。继续咆哮也没有好处。

票数 2
EN

Stack Overflow用户

发布于 2017-02-14 20:11:50

CTest一点也不存在缺陷,但是使用CMake和CTest的方式似乎是“有缺陷的”。命令行接口(CLI)工具ctest的调用通常与CMake构建目标的调用无关(目标test除外)。

在我看来,应该使用CMake维基中描述的自定义CMake维基目标解决方案,而不是,因为它改变了CMake的默认行为,并且是不可配置的。

相反,应该使用以下使用内置选项BUILD_TESTING的方法:

代码语言:javascript
运行
复制
include(CTest)
if(BUILD_TESTING)
  find_package(GTest MODULE REQUIRED)
  add_executable(example_test example_test.cpp)
  target_link_libraries(
    example_test
    PRIVATE
      GTest::GTest
      GTest::Main
  )
  add_test(NAME example_test COMMAND example_test)
endif()

include(CTest)选项 BUILD_TESTING中定义,它允许控制是否构建项目的所有测试。

来自正式文件的报价

只有当调用了CMake命令时,enable_testing()才会生成测试。CTest模块在BUILD_TESTING选项为ON时自动调用命令。

上述内容可用于CLI,如下所示:

  1. 创建测试(默认): 测试-B_builds/示例-测试/发布-G"Unix“-DCMAKE_BUILD_TYPE=Release cmake --build _builds/示例-测试/发布-配置发布 在本例中,命令cd _builds/example-testing/releasectest / cmake --build . --target test构建运行测试。
  2. 不要创建测试,设置-DBUILD_TESTING=OFF: -G"Unix Makefiles“-DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF cmake _builds/示例测试/发布-非测试-配置发行版 在这种情况下,命令cd _builds/example-testing/release-no-testsctest没有运行测试,因为没有构建测试。命令cmake --build . --target test 失败,因为它没有在CMake的配置阶段创建。

我们只是在抓表面而已。请参考ctest --help,例如,有许多--build-<...>选项允许对测试/构建进行更精细的控制,尽管我没有这方面的经验。

我强烈建议阅读以下内容:

如果确实希望启用测试的构建,但是通过一个默认情况下不调用的单独目标运行测试(不是通过CTest ),而是直接运行测试,则可以执行以下操作:

代码语言:javascript
运行
复制
include(CTest)
if(BUILD_TESTING)
  find_package(GTest MODULE REQUIRED)
  option(
    BUILD_TESTING_EXCLUDE_FROM_ALL
    "Do not build the testing tree together with the default build target."
    OFF
  )

  if(BUILD_TESTING_EXCLUDE_FROM_ALL)
    set(add_executable_args_for_test EXCLUDE_FROM_ALL)
  endif()

  # The "build_test" target is used to build all test executables.
  add_custom_target(
    build_test
    # Workaround for printing the COMMENT, it does not work without a NOOP
    # COMMAND.
    COMMAND ${CMAKE_COMMAND} -E echo
    COMMENT "Building tests..."
    VERBATIM
  )
  add_executable(example_test ${add_executable_args_for_test} example_test.cpp)
  target_link_libraries(
    example_test
    PRIVATE
      GTest::GTest
      GTest::Main
  )
  add_test(NAME example_test COMMAND example_test)
  add_dependencies(build_test example_test)

  # The "check" target is used to build AND run all test executables.
  add_custom_target(
    check
    # Either invoke the test(s) indirectly via "CTest" (commented) or directly.
#   COMMAND ${CMAKE_CTEST_COMMAND}
    COMMAND example_test
    COMMENT "Building and running test..."
    VERBATIM
  )
  # Alternative to the COMMAND in the add_custom_target. Leads to the same
  # behavior as calling "CTest" directly.
#  add_custom_command(
#    TARGET check
#    COMMAND ${CMAKE_COMMAND} ARGS --build ${CMAKE_BINARY_DIR} --target test
#    VERBATIM
#  )
   add_dependencies(check build_test)
endif()
  • 注意,上面的代码不是为了运行测试而调用CTest或目标test,而是直接调用测试。
  • 请阅读使用CTest的替代方法的注释和注释代码,这些代码类似于问题中描述的方法。
  • 很容易增强上述代码以支持多个测试可执行文件。

应该删除整个CMake Wiki,因为Wiki几乎只包含CMake版本< 3.0的过时信息。它中的大部分信息不能被认为是现代CMake。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37627093

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档