理解集成测试

注意

一些集合没有集成测试。

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

集合中使用了两种集成测试

  • 使用 Ansible 角色的集成测试

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

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

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

集成测试示例

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

- 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-coreansible包中包含的ansible-test实用程序。有关详细信息,请参见运行集成测试。完成集成测试后,请参阅创建您的第一个集合拉取请求,了解如何提交拉取请求。

为集合准备集成测试

准备开发集成测试

  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问题部分中描述的错误。运行测试。

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

重构代码

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

涵盖模块/新功能

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

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

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

  • 返回值 - 模块在不同条件下是否一致地返回值?

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

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

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

  • 实际执行操作。这应该表明存在更改。

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

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

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

要检查任务

  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'

以下是摘要

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

  • 检查返回值。

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

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

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