理解集成测试

注意

一些集合没有集成测试。

集成测试是模块和插件的功能测试。通过集成测试,我们检查模块或插件是否满足其功能需求。简而言之,我们检查功能是否按预期工作,以及用户是否获得了模块或插件文档中描述的结果。

集合中使用了 两种类型的集成测试

  • 使用 Ansible 角色的集成测试

  • 使用 runme.sh 的集成测试。

本节重点介绍使用 Ansible 角色的集成测试。

集成测试使用调用这些模块的剧本检查模块。测试传递独立参数及其组合,使用 assert 模块检查模块或插件的报告内容,以及每个任务后系统的实际状态。

集成测试示例

假设我们要测试使用 name 参数调用的 postgresql_user 模块。我们希望该模块既可以根据 name 参数提供的 value 创建用户,也可以报告系统状态已更改。我们不能只依靠模块的报告。为了确保用户已创建,我们使用另一个模块查询数据库以查看用户是否存在。

- name: Create PostgreSQL user and store module's output to the result variable
  community.postgresql.postgresql_user:
    name: test_user
  register: result

- name: Check the module returns what we expect
  assert:
    that:
      - result is changed

- name: Check actual system state with another module, in other words, that the user exists
  community.postgresql.postgresql_query:
    query: SELECT * FROM pg_authid WHERE rolename = 'test_user'
  register: query_result

- name: We expect it returns one row, check it
  assert:
    that:
      - query_result.rowcount == 1

有关集成测试的详细信息

Ansible 集成测试的基本实体是 target。目标是在集合存储库的 tests/integration/targets 目录中存储的 Ansible 角色。目标角色包含测试模块所需的一切。

目标的名称包含它们测试的模块或插件名称。以 setup_ 开头的目标名称通常在模块和插件目标开始执行之前作为依赖项执行。有关详细信息,请参阅 创建新的集成测试

要运行集成测试,我们使用 ansible-test 实用程序,该实用程序包含在 ansible-coreansible 包中。有关详细信息,请参阅 运行集成测试。完成集成测试后,请参阅 创建你的第一个集合拉取请求,了解如何提交拉取请求。

为集合的集成测试做准备

要为开发集成测试做准备

  1. 设置你的本地环境.

  2. 确定是否已存在集成测试。

ansible-test integration --list-targets

如果集合已具有集成测试,则它们存储在集合存储库的 tests/integration/targets/* 子目录中。

如果你使用的是 bash,并且 argcomplete 包已在你的系统上使用 pip 安装,你也可以获得完整的目标列表。

ansible-test integration <tab><tab>

或者,你可以检查 tests/integration/targets 目录是否包含与模块同名的目录。例如,community.postgresql 集合的 postgresql_user 模块的测试存储在集合存储库的 tests/integration/targets/postgresql_user 目录中。如果那里没有相应的目标,则该模块没有集成测试。在这种情况下,请考虑为该模块添加集成测试。有关详细信息,请参阅 创建新的集成测试

关于覆盖率的建议

错误修复

在修复代码之前,请在 适当的测试目标 中创建一个测试用例,该用例可以重现问题报告者提供的错误,并在 Steps to Reproduce 问题部分中进行描述。运行 测试。

如果你无法重现错误,请让报告者提供更多信息。问题可能与环境设置有关。有时,特定的环境问题无法在集成测试中重现,在这种情况下,需要由问题报告者或其他感兴趣的用户进行手动测试。

重构代码

重构代码时,始终检查相关选项是否在 相应的测试目标 中得到覆盖。不要假设如果测试目标存在,则所有内容都已得到覆盖。

覆盖模块/新功能

覆盖模块时,请分别覆盖所有选项及其有意义的组合。模块的每个可能的用法都应针对以下内容进行测试

  • 幂等性 - 重新运行任务是否会报告没有更改?

  • 检查模式 - 干运行任务的行为是否与实际运行相同?它不会进行任何更改吗?

  • 返回值 - 模块在不同条件下是否始终返回 value?

每个测试操作至少需要测试以下次数

  • 如果支持,请在检查模式下执行操作。这应该表示更改。

  • 使用另一个模块检查更改 实际进行。

  • 实际执行操作。这应该表示更改。

  • 使用另一个模块检查更改已实际进行。

  • 再次在检查模式下执行操作。这应该表示 更改。

  • 再次实际执行操作。这应该表示 更改。

要检查任务

  1. 将任务结果注册为变量,例如,register: result。使用 assert 模块,检查

  1. 如果 - result is changed 或不是。

  2. 预期返回值。

  1. 如果模块改变了系统状态,请使用至少一个其他模块来检查实际的系统状态。例如,如果模块更改了文件,我们可以通过在测试任务前后使用 stat 模块检查其校验和来验证文件是否已更改。

  2. 如果模块支持检查模式,请使用 check_mode: true 运行相同的任务。使用其他模块检查实际的系统状态是否已更改。

  3. 涵盖模块必须失败的情况。使用 ignore_errors: true 选项,并使用 assert 模块检查返回的消息。

示例

- name: Task to fail
  abstract_module:
      ...
  register: result

- name: Check the task fails and its error message
  assert:
    that:
      - result is failed
      - result.msg == 'Message we expect'

以下是摘要

  • 涵盖选项及其合理的组合。

  • 检查返回值。

  • 如果支持,请涵盖检查模式。

  • 使用其他模块检查系统状态。

  • 检查模块必须失败的情况以及错误消息。