4.10 使用测试固件

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

这个示例的灵感来自于Craig Scott,我们建议读者也参考相应的博客文章来了解更多的背景知识,https://crascit.com/2016/10/18/test-fixtures-withcmake-ctest/ ,此示例的动机是演示如何使用测试固件。这对于更复杂的测试非常有用,这些测试需要在测试运行前进行设置,以及在测试完成后执行清理操作(例如:创建示例数据库、设置连接、断开连接、清理测试数据库等等)。我们需要运行一个设置或清理操作的测试,并能够以一种可预测和健壮的方式自动触发这些步骤,而不需要引入代码重复。这些设置和清理步骤可以委托给测试框架(例如Google Test或Catch2),我们在这里将演示如何在CMake级别实现测试固件。

准备工作

我们将准备4个Python脚本,并将它们放在test目录下:setup.pyfeatures-a.pyfeatures-b.pyclean-up.py

具体实施

我们从CMakeLists.txt结构开始,附加一些步骤如下:

  1. 基础CMake语句:

    1. # set minimum cmake version
    2. cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
    3. # project name
    4. project(recipe-10 LANGUAGES NONE)
    5. # detect python
    6. find_package(PythonInterp REQUIRED)
    7. # define tests
    8. enable_testing()
  2. 然后,定义了4个测试步骤,并将它们绑定到一个固件上:

    1. add_test(
    2. NAME setup
    3. COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/setup.py
    4. )
    5. set_tests_properties(
    6. setup
    7. PROPERTIES
    8. FIXTURES_SETUP my-fixture
    9. )
    10. add_test(
    11. NAME feature-a
    12. COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-a.py
    13. )
    14. add_test(
    15. NAME feature-b
    16. COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-b.py
    17. )
    18. set_tests_properties(
    19. feature-a
    20. feature-b
    21. PROPERTIES
    22. FIXTURES_REQUIRED my-fixture
    23. )
    24. add_test(
    25. NAME cleanup
    26. COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/cleanup.py
    27. )
    28. set_tests_properties(
    29. cleanup
    30. PROPERTIES
    31. FIXTURES_CLEANUP my-fixture
    32. )
  3. 运行整个集合,如下面的输出所示:

    1. $ mkdir -p build
    2. $ cd build
    3. $ cmake ..
    4. $ ctest
    5. Start 1: setup
    6. 1/4 Test #1: setup ............................ Passed 0.01 sec
    7. Start 2: feature-a
    8. 2/4 Test #2: feature-a ........................ Passed 0.01 sec
    9. Start 3: feature-b
    10. 3/4 Test #3: feature-b ........................ Passed 0.00 sec
    11. Start 4: cleanup
    12. 4/4 Test #4: cleanup .......................... Passed 0.01 sec
    13. 100% tests passed, 0 tests failed out of 4
  4. 然而,当我们试图单独运行测试特性时。它正确地调用设置步骤和清理步骤:

    1. $ ctest -R feature-a
    2. Start 1: setup
    3. 1/3 Test #1: setup ............................ Passed 0.01 sec
    4. Start 2: feature-a
    5. 2/3 Test #2: feature-a ........................ Passed 0.00 sec
    6. Start 4: cleanup
    7. 3/3 Test #4: cleanup .......................... Passed 0.01 sec
    8. 100% tests passed, 0 tests failed out of 3

工作原理

在本例中,我们定义了一个文本固件,并将其称为my-fixture。我们为安装测试提供了FIXTURES_SETUP属性,并为清理测试了FIXTURES_CLEANUP属性,并且使用FIXTURES_REQUIRED,我们确保测试feature-afeature-b都需要安装和清理步骤才能运行。将它们绑定在一起,可以确保在定义良好的状态下,进入和离开相应的步骤。