创建新的集成测试
本节涵盖以下情况
- 集合或集合中的一组模块根本没有集成测试。 
- 您正在添加一个新模块,并且想要包含集成测试。 
- 您想为一个已经存在的模块添加集成测试,而该模块目前没有集成测试。 
换句话说,目前无论模块是否存在,都没有该模块的测试。
如果模块已经有测试,请参见 添加到现有的集成测试。
简化示例
这是一个简化的抽象示例。
假设我们要向community.abstract集合中的一个新模块添加集成测试,该模块与某些服务交互。
我们 检查 并确定根本没有集成测试。
我们基本上应该执行以下操作
- 使用 - setup目标安装并运行服务。
- 创建一个测试目标。 
- 为模块添加集成测试。 
- 运行测试. 
- 根据需要修复代码和测试,再次运行测试,并重复此循环,直到测试通过。 
注意
在实现也使用相同服务的其他目标时,您可以重复使用setup目标。
- 将集合克隆到本地计算机上的 - ~/ansible_collections/community.abstract目录。
- 从 - ~/ansible_collections/community.abstract目录中,为- setup目标创建目录
mkdir -p tests/integration/targets/setup_abstract_service/tasks
- 编写所有必要的任务来准备环境、安装和运行服务。 
为简单起见,让我们假设该服务在本地发行版的存储库中可用,并且不需要复杂的配置环境。
将以下任务添加到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
这是一个非常简化的示例。
- 添加要测试的模块的目标。 
假设该模块名为abstract_service_info。在目标中创建以下目录结构
mkdir -p tests/integration/targets/abstract_service_info/tasks
mkdir -p tests/integration/targets/abstract_service_info/meta
添加所有需要的子目录。例如,如果您要使用默认值和文件,请添加defaults和files目录,依此类推。方法与创建角色时相同。
- 要使 - setup_abstract_service目标在模块目标之前运行,请将以下几行添加到- tests/integration/targets/abstract_service_info/meta/main.yml文件中。
dependencies:
  - setup_abstract_service
- 首先编写单个独立任务以检查您的模块是否可以与服务交互。 
我们假设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
- 运行测试,使用 - -vvv参数。
如果连接有任何问题(例如,服务不接受连接)或代码有问题,则该play将失败。
检查输出以查看故障发生在哪一步。调查原因,进行修复,然后再次运行。重复此循环,直到测试通过。
- 如果测试成功,请编写更多测试。有关详细信息,请参阅关于覆盖率的建议部分。 
community.postgresql示例
这是一个从头开始为community.postgresql.postgresql_info模块编写集成测试的真实示例。
为简单起见,我们将创建非常基本的测试,我们将使用 Ubuntu 20.04 测试容器运行这些测试。
我们使用Linux作为工作环境,并已安装并运行git和docker。
我们还安装了ansible-core。
- 在您的主目录中创建以下目录 
mkdir -p ~/ansible_collections/community
- 通过 GitHub 网页界面分叉集合存储库。 
- 将分叉的存储库从您的个人资料克隆到创建的路径 
git clone https://github.com/YOURACC/community.postgresql.git ~/ansible_collections/community/postgresql
如果您更喜欢使用 SSH 协议
git clone git@github.com:YOURACC/community.postgresql.git ~/ansible_collections/community/postgresql
- 转到克隆的存储库 
cd ~/ansible_collections/community/postgresql
- 确保您在默认分支中 
git status
- 检出一个测试分支 
git checkout -b postgresql_info_tests
- 由于我们已经为 - postgresql_info模块进行了测试,我们将运行以下命令
rm -rf tests/integration/targets/*
现在所有目标都已删除,当前状态就好像我们根本没有community.postgresql集合的任何集成测试一样。现在我们可以从头开始编写集成测试。
- 我们将从创建一个 - setup目标开始,该目标将安装所有必需的软件包并将启动 PostgreSQL。创建以下目录
mkdir -p tests/integration/targets/setup_postgresql_db/tasks
- 创建 - 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
这对我们非常基本的例子来说已经足够了。
- 然后,为 - postgresql_info目标创建以下目录
mkdir -p tests/integration/targets/postgresql_info/tasks tests/integration/targets/postgresql_info/meta
- 要使 - setup_postgresql_db目标作为依赖项在- postgresql_info目标之前运行,请创建- tests/integration/targets/postgresql_info/meta/main.yml文件并将以下代码添加到其中
dependencies:
  - setup_postgresql_db
- 现在,我们可以为 - 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变量。我们期望的是,除其他事项外,结果包含版本并报告系统状态未更改。
- 在 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"
}
如果在处理项目时测试失败,请检查输出以查看故障发生在哪一步。调查原因,进行修复,然后再次运行。重复此循环,直到测试通过。如果测试成功,请编写更多测试。有关详细信息,请参阅关于覆盖率的建议部分。
