向现有集成测试添加内容

测试任务存储在 tests/integration/targets/<target_name>/tasks 目录中。

main.yml 文件包含测试任务并包含其他测试文件。查找合适的测试文件以集成您的测试,或创建并包含或导入单独的测试文件。您可以使用现有测试文件之一作为草稿。

修复错误时

修复错误时

  1. 确定模块是否存在集成测试。如果不存在,请参阅 创建新的集成测试 部分。

  2. 将重现错误的任务添加到 tests/integration/targets/<target_name>/tasks 目录中的相应文件中。

  3. 运行测试。新添加的任务应失败。

  4. 如果它们没有失败,请重新检查您的环境或测试任务是否满足问题 Steps to Reproduce 部分中描述的条件。

  5. 如果您重现了错误并且测试失败,请更改代码。

  6. 再次运行测试

  7. 如果它们失败,请重复步骤 5-6,直到测试通过。

以下是一个示例。

假设有人在 community.postgresql 集合中报告了一个问题,即当用户将包含下划线的名称传递给 postgresql_user 模块时,模块会失败。

我们将集合存储库克隆到 ~/ansible_collections/community/postgresql 目录并 准备了我们的环境。从集合的根目录中,我们运行 ansible-test integration --list-targets,它显示了一个名为 postgresql_user 的目标。这意味着我们已经对该模块进行了测试。

我们从重现错误开始。

首先,我们查看 tests/integration/targets/postgresql_user/tasks/main.yml 文件。在这种特定情况下,该文件从 tasks 目录导入其他文件。 postgresql_user_general.yml 看起来像是添加到我们的测试中的一个合适的选项。

# General tests:
- import_tasks: postgresql_user_general.yml
  when: postgres_version_resp.stdout is version('9.4', '>=')

我们将以下代码添加到该文件中。

# https://github.com/ansible-collections/community.postgresql/issues/NUM
- name: Test username containing underscore
  community.postgresql.postgresql_user:
    name: underscored_user
  register: result

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

- name: Query the database if the user exists
  community.postgresql.postgresql_query:
    query: SELECT * FROM pg_authid WHERE rolename = 'underscored_user'
  register: result

- name: Check the database returns one row
  assert:
    that:
      - result.query_result.rowcount == 1

当我们使用 postgresql_user 作为测试目标 运行测试 时,此任务必须失败。

现在我们有了失败的测试;我们将修复错误并再次运行相同的测试。一旦测试通过,我们将认为错误已修复,并将提交一个 pull request。

添加新功能时

注意

本节中描述的过程也适用于您希望向已存在但缺少集成测试的功能添加集成测试时。

如果您尚未实现新功能,您可以先为其编写集成测试。它们将无法工作,因为代码尚不存在,但它们可以帮助您在开始编写任何代码之前改进实现设计。

添加新功能时,添加测试的过程包括以下步骤

  1. 确定模块是否存在集成测试。如果不存在,请参阅 创建新的集成测试

  2. tests/integration/targets/<target_name>/tasks 目录中找到适合您的测试的文件。

  3. 使用测试覆盖您的功能。有关详细信息,请参阅 关于覆盖范围的建议 部分。

  4. 运行测试.

  5. 如果它们失败,请查看测试输出以获取详细信息。修复您的代码或测试并再次运行测试。

  6. 重复步骤 4-5,直到测试通过。

以下是一个示例。

假设我们决定向 community.postgresql 集合的 postgresql_user 模块添加一个名为 add_attribute 的新选项。

该选项为布尔值。如果设置为 yes,则会向数据库用户添加其他属性。

我们将集合存储库克隆到 ~/ansible_collections/community/postgresql 目录并 准备了我们的环境。从集合的根目录中,我们运行 ansible-test integration --list-targets,它显示了一个名为 postgresql_user 的目标。因此,我们已经对该模块进行了一些测试。

首先,我们查看 tests/integration/targets/<target_name>/tasks/main.yml 文件。在这种特定情况下,该文件从 tasks 目录导入其他文件。 postgresql_user_general.yml 文件看起来像是添加到我们的测试中的一个合适的选项。

# General tests:
- import_tasks: postgresql_user_general.yml
  when: postgres_version_resp.stdout is version('9.4', '>=')

我们将以下代码添加到该文件中。

# https://github.com/ansible-collections/community.postgresql/issues/NUM
# We should also run the same tasks with check_mode: true. We omit it here for simplicity.
- name: Test for new_option, create new user WITHOUT the attribute
  community.postgresql.postgresql_user:
    name: test_user
  register: result

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

- name: Query the database if the user exists but does not have the attribute (it is NULL)
  community.postgresql.postgresql_query:
    query: SELECT * FROM pg_authid WHERE rolename = 'test_user' AND attribute = NULL
  register: result

- name: Check the database returns one row
  assert:
    that:
      - result.query_result.rowcount == 1

- name: Test for new_option, create new user WITH the attribute
  community.postgresql.postgresql_user:
    name: test_user
  register: result

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

- name: Query the database if the user has the attribute (it is TRUE)
  community.postgresql.postgresql_query:
    query: SELECT * FROM pg_authid WHERE rolename = 'test_user' AND attribute = 't'
  register: result

- name: Check the database returns one row
  assert:
    that:
      - result.query_result.rowcount == 1

然后,我们使用 postgresql_user 作为测试目标 运行测试

实际上,我们将上面的任务与使用 check_mode: true 选项运行的相同任务交替执行,以确保我们的选项在检查模式下也能按预期工作。有关详细信息,请参阅 关于覆盖范围的建议

如果我们预计任务会失败,我们将使用 ignore_errors: true 选项并检查任务是否确实失败并返回了我们期望的消息

- name: Test for fail_when_true option
  community.postgresql.postgresql_user:
    name: test_user
    fail_when_true: true
  register: result
  ignore_errors: true

- name: Check the module fails and returns message we expect
  assert:
    that:
      - result is failed
      - result.msg == 'The message we expect'