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

enable_testing()

要么
include(CTest)

然后针对每个测试(名称fooTest,可执行foo)
add_executable(foo <foo_sources>)
add_test(fooTest foo)

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

此外,只要添加一次,我们就可以使用make check命令运行测试。
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})

对于每个测试,我们通过关键字EXCLUDE_FROM_ALL和命令add_dependencies扩展以上内容:
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] https://cmake.org/Wiki/CMakeEmulateMakeCheck
[2] http://comments.gmane.org/gmane.comp.programming.tools.cmake.user/47300
[3] CMake & CTest : make test doesn't build tests
[4] http://public.kitware.com/Bug/view.php?id=8774

最佳答案

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

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

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

  • Autotools可以按您想要的方式进行操作,因此人们已经习惯了。但是为什么要成为一个单位呢?为什么没有两个命令?混合两个任务并使有特殊需求的项目变得更加困难有什么好处?

    我得出的结论是,创建目标build-tests或类似的代码,并遵循CMake开发人员做出的决定来分离构建测试和执行测试。然后,我可以决定是否要并行构建,如何处理编译失败(例如,传递-k进行make)等等。
    唯一的缺点是,此目标仅存在于顶级目录中,不能在子目录中使用。
    要获得CMake内置的目标,是一个很好的功能要求。肆无忌SO就没有好处。

    关于cmake - “ctest”与 “make check”:不良的构建时间与 splinter 的选项传递,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37627093/

    10-13 09:00