创建新的集成测试

本节涵盖以下情况

  • 集合或集合中的一组模块根本没有集成测试。

  • 您要添加一个新模块,并且您希望包含集成测试。

  • 您希望为现有模块添加集成测试,而该模块没有集成测试。

换句话说,目前没有模块的测试,无论模块是否存在。

如果模块已经存在测试,请参阅 添加到现有集成测试.

简化示例

这是一个简化的抽象示例。

假设我们要为 community.abstract 集合中的一个新模块添加集成测试,该模块与某个服务进行交互。

我们 检查 并确定根本没有集成测试。

我们应该基本上执行以下操作

  1. 使用 setup 目标安装并运行服务。

  2. 创建一个测试目标。

  3. 为该模块添加集成测试。

  4. 运行测试.

  5. 根据需要修复代码和测试,再次运行测试,并重复此循环,直到测试通过。

注意

在实现也使用相同服务的其他目标时,您可以重用 setup 目标。

  1. 将集合克隆到本地机器上的 ~/ansible_collections/community.abstract 目录。

  2. ~/ansible_collections/community.abstract 目录创建 setup 目标的目录

mkdir -p tests/integration/targets/setup_abstract_service/tasks
  1. 编写准备环境、安装和运行服务所需的所有任务。

为简单起见,假设该服务在原生发行版存储库中可用,并且不需要复杂的配置环境。

将以下任务添加到 tests/integration/targets/setup_abstract_service/tasks/main.yml 文件以安装和运行服务

- name: Install abstract service
  package:
    name: abstract_service

- name: Run the service
  systemd:
    name: abstract_service
    state: started

这是一个非常简化的示例。

  1. 添加您要测试的模块的目标。

假设该模块名为 abstract_service_info。在目标中创建以下目录结构

mkdir -p tests/integration/targets/abstract_service_info/tasks
mkdir -p tests/integration/targets/abstract_service_info/meta

添加所有需要的子目录。例如,如果您要使用默认值和文件,请添加 defaultsfiles 目录,等等。方法与创建角色时相同。

  1. 要使 setup_abstract_service 目标在模块目标之前运行,请将以下行添加到 tests/integration/targets/abstract_service_info/meta/main.yml 文件中。

dependencies:
  - setup_abstract_service
  1. 从编写单个独立任务开始,以检查您的模块是否可以与该服务进行交互。

我们假设 abstract_service_info 模块从 abstract_service 获取一些信息,并且它具有两个连接参数。

除了其他字段之外,它还返回一个名为 version 的字段,其中包含服务版本。

将以下内容添加到 tests/integration/targets/abstract_service_info/tasks/main.yml

- name: Fetch info from abstract service
  abstract_service_info:
    host: 127.0.0.1  # We assume the service accepts local connection by default
    port: 1234       # We assume that the service is listening to this port by default
  register: result   # This variable will contain the returned JSON including the server version

- name: Test the output
  assert:
    that:
      - result.version == '1.0.0'  # Check version field contains what we expect
  1. 运行测试 使用 -vvv 参数。

如果存在任何连接问题(例如,服务不接受连接)或代码问题,该剧本将失败。

检查输出以查看失败发生在哪一步。调查原因,修复它,然后再次运行。重复此循环,直到测试通过。

  1. 如果测试成功,请编写更多测试。有关详细信息,请参阅 关于覆盖率的建议 部分。

community.postgresql 示例

以下是如何从头开始为 community.postgresql.postgresql_info 模块编写集成测试的实际示例。

为了简单起见,我们将创建非常基本的测试,我们将使用 Ubuntu 20.04 测试容器运行这些测试。

我们使用 Linux 作为工作环境,并已安装并运行 gitdocker

我们还安装了 ansible-core

  1. 在您的主目录中创建以下目录

mkdir -p ~/ansible_collections/community
  1. 通过 GitHub 网页界面分叉 集合存储库

  2. 将分叉的存储库从您的个人资料克隆到创建的路径

git clone https://github.com/YOURACC/community.postgresql.git ~/ansible_collections/community/postgresql

如果您希望使用 SSH 协议

git clone [email protected]:YOURACC/community.postgresql.git ~/ansible_collections/community/postgresql
  1. 转到克隆的存储库

cd ~/ansible_collections/community/postgresql
  1. 确保您位于默认分支

git status
  1. 检出测试分支

git checkout -b postgresql_info_tests
  1. 由于我们已经为 postgresql_info 模块生成了测试,因此我们将运行以下命令

rm -rf tests/integration/targets/*

现在所有目标都已删除,当前状态就像我们根本没有为 community.postgresql 集合创建任何集成测试一样。现在我们可以从头开始编写集成测试。

  1. 我们将从创建一个 setup 目标开始,该目标将安装所有必需的软件包并启动 PostgreSQL。创建以下目录

mkdir -p tests/integration/targets/setup_postgresql_db/tasks
  1. 创建 tests/integration/targets/setup_postgresql_db/tasks/main.yml 文件,并将以下任务添加到其中

- name: Install required packages
  package:
    name:
      - apt-utils
      - postgresql
      - postgresql-common
      - python3-psycopg2

- name: Initialize PostgreSQL
  shell: . /usr/share/postgresql-common/maintscripts-functions && set_system_locale && /usr/bin/pg_createcluster -u postgres 12 main
  args:
    creates: /etc/postgresql/12/

- name: Start PostgreSQL service
  ansible.builtin.service:
    name: postgresql
    state: started

对于我们非常基本的示例来说,这已经足够了。

  1. 然后,为 postgresql_info 目标创建以下目录

mkdir -p tests/integration/targets/postgresql_info/tasks tests/integration/targets/postgresql_info/meta
  1. 要使 setup_postgresql_db 目标作为依赖项在 postgresql_info 目标之前运行,请创建 tests/integration/targets/postgresql_info/meta/main.yml 文件,并将以下代码添加到其中

dependencies:
  - setup_postgresql_db
  1. 现在我们准备为 postgresql_info 模块添加我们的第一个测试任务。创建 tests/integration/targets/postgresql_info/tasks/main.yml 文件,并将以下代码添加到其中

- name: Test postgresql_info module
  become: true
  become_user: postgres
  community.postgresql.postgresql_info:
    login_user: postgres
    login_db: postgres
  register: result

- name: Check the module returns what we expect
  assert:
    that:
      - result is not changed
      - result.version.major == 12
      - result.version.minor == 8

在第一个任务中,我们运行 postgresql_info 模块以从我们使用 setup_postgresql_db 目标安装和启动的数据库中获取信息。我们将模块返回的值保存到 result 变量中。

在第二个任务中,我们使用 assert 模块检查 result 变量,它是第一个任务返回的结果。我们期望结果包含版本信息以及系统状态未更改的报告,以及其他信息。

  1. 在 Ubuntu 20.04 docker 容器中运行测试。

ansible-test integration postgresql_info --docker ubuntu2004 -vvv

测试应该通过。如果查看输出,应该看到类似以下内容。

TASK [postgresql_info : Check the module returns what we expect] ***************
ok: [testhost] => {
  "changed": false,
  "msg": "All assertions passed"
}

如果在开发项目时测试失败,请检查输出以查看故障发生在哪个步骤。调查原因,修复它并再次运行。重复此循环直到测试通过。如果测试成功,请编写更多测试。有关详细信息,请参考 覆盖范围建议 部分。