> For the complete documentation index, see [llms.txt](https://chenxiaowei.gitbook.io/cmake-cookbook/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://chenxiaowei.gitbook.io/cmake-cookbook/4.0-chinese/4.10-chinese.md).

# 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.py`、`features-a.py`、`features-b.py`和`clean-up.py`。

## 具体实施

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

1. 基础CMake语句:

   ```
   # set minimum cmake version
   cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

   # project name
   project(recipe-10 LANGUAGES NONE)

   # detect python
   find_package(PythonInterp REQUIRED)

   # define tests
   enable_testing()
   ```
2. 然后，定义了4个测试步骤，并将它们绑定到一个固件上:

   ```
   add_test(
     NAME setup
     COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/setup.py
     )
   set_tests_properties(
     setup
     PROPERTIES
         FIXTURES_SETUP my-fixture
     )
   add_test(
     NAME feature-a
     COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-a.py
     )
   add_test(
     NAME feature-b
     COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/feature-b.py
     )
   set_tests_properties(
     feature-a
     feature-b
     PROPERTIES
         FIXTURES_REQUIRED my-fixture
     )
   add_test(
     NAME cleanup
     COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/cleanup.py
     )
   set_tests_properties(
     cleanup
     PROPERTIES
         FIXTURES_CLEANUP my-fixture
     )
   ```
3. 运行整个集合，如下面的输出所示:

   ```
   $ mkdir -p build
   $ cd build
   $ cmake ..
   $ ctest

   Start 1: setup
   1/4 Test #1: setup ............................ Passed 0.01 sec
   Start 2: feature-a
   2/4 Test #2: feature-a ........................ Passed 0.01 sec
   Start 3: feature-b
   3/4 Test #3: feature-b ........................ Passed 0.00 sec
   Start 4: cleanup
   4/4 Test #4: cleanup .......................... Passed 0.01 sec

   100% tests passed, 0 tests failed out of 4
   ```
4. 然而，当我们试图单独运行测试特性时。它正确地调用设置步骤和清理步骤:

   ```
   $ ctest -R feature-a

   Start 1: setup
   1/3 Test #1: setup ............................ Passed 0.01 sec
   Start 2: feature-a
   2/3 Test #2: feature-a ........................ Passed 0.00 sec
   Start 4: cleanup
   3/3 Test #4: cleanup .......................... Passed 0.01 sec

   100% tests passed, 0 tests failed out of 3
   ```

## 工作原理

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