4.7 使用超时测试运行时间过长的测试

NOTE:此示例代码可以在 https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-04/recipe-07 中找到。该示例在CMake 3.5版(或更高版本)中是有效的,并且已经在GNU/Linux、macOS和Windows上进行过测试。

理想情况下,测试集应该花很短的时间进行,以便开发人员经常运行测试,并使每个提交(变更集)进行测试成为可能(或更容易)。然而,有些测试可能会花费更长的时间或者被卡住(例如,由于高文件I/O负载),我们可能需要设置超时来终止耗时过长的测试,它们延迟了整个测试,并阻塞了部署管道。本示例中,我们将演示一种设置超时的方法,可以针对每个测试设置不同的超时。

准备工作

这个示例是一个Python脚本(test.py),它总是返回0。为了保持这种简单性,并保持对CMake方面的关注,测试脚本除了等待两秒钟外什么也不做。实际中,这个测试脚本将执行更有意义的工作:

  1. import sys
  2. import time
  3. # wait for 2 seconds
  4. time.sleep(2)
  5. # report success
  6. sys.exit(0)

具体实施

我们需要通知CTest终止测试,如下:

  1. 我们定义项目名称,启用测试,并定义测试:

    1. # set minimum cmake version
    2. cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
    3. # project name
    4. project(recipe-07 LANGUAGES NONE)
    5. # detect python
    6. find_package(PythonInterp REQUIRED)
    7. # define tests
    8. enable_testing()
    9. # we expect this test to run for 2 seconds
    10. add_test(example ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test.py)
  2. 另外,我们为测试指定时限,设置为10秒:

    1. set_tests_properties(example PROPERTIES TIMEOUT 10)
  3. 知道了如何进行配置和构建,并希望测试能够通过:

    1. $ ctest
    2. Test project /home/user/cmake-recipes/chapter-04/recipe-07/example/build
    3. Start 1: example
    4. 1/1 Test #1: example .......................... Passed 2.01 sec
    5. 100% tests passed, 0 tests failed out of 1
    6. Total Test time (real) = 2.01 sec
  4. 现在,为了验证超时是否有效,我们将test.py中的sleep命令增加到11秒,并重新运行测试:

    1. $ ctest
    2. Test project /home/user/cmake-recipes/chapter-04/recipe-07/example/build
    3. Start 1: example
    4. 1/1 Test #1: example ..........................***Timeout 10.01 sec
    5. 0% tests passed, 1 tests failed out of 1
    6. Total Test time (real) = 10.01 sec
    7. The following tests FAILED:
    8. 1 - example (Timeout)
    9. Errors while running CTest

工作原理

TIMEOUT是一个方便的属性,可以使用set_tests_properties为单个测试指定超时时间。如果测试运行超过了这个设置时间,不管出于什么原因(测试已经停止或者机器太慢),测试将被终止并标记为失败。