测试 Ansible

为什么要测试您的 Ansible 贡献?

如果您是一名开发者,最有价值的事情之一就是查看 GitHub 问题并帮助修复 Bug,因为 Bug 修复的优先级几乎总是高于功能开发。即使对于非开发者而言,协助测试用于 Bug 修复和功能的 Pull Request 也非常有价值。

了解如何编写 Playbook 和 Role 的 Ansible 用户应该能够测试自己的工作。GitHub Pull Request 会自动运行各种测试(例如 Azure Pipelines)以展示实际存在的 Bug。然而,贡献者也必须在自动化的 GitHub 检查之外测试其工作,并在 Pull Request 中提供这些测试的证明,以确保他们的工作更有可能被审查和合并。

请继续阅读以了解 Ansible 是如何测试的、如何在本地测试您的贡献,以及如何扩展测试能力。

如果您想了解有关集合(Collections)测试的信息,请阅读 测试集合

测试类型

总体而言,我们将测试分为以下几类

完整性测试(sanity):
  • 健全性测试

  • 完整性测试由用于执行静态代码分析的脚本和工具组成。

  • 这些测试的主要目的是强制执行 Ansible 的编码标准和要求。

集成测试(integration):
  • 集成测试

  • 针对模块和 Ansible Core 功能的功能测试。

单元测试(units):
  • 单元测试

  • 直接针对代码库各个部分的测试。

GitHub 和 Azure Pipelines 内的测试

组织

当创建 Pull Request (PR) 时,它们会使用持续集成 (CI) 工具 Azure Pipelines 进行测试。结果显示在每个 PR 的末尾。

当 Azure Pipelines 检测到错误,并且该错误可以追溯到 PR 中修改过的文件时,相关行将被添加为 GitHub 评论。例如

The test `ansible-test sanity --test pep8` failed with the following errors:

lib/ansible/modules/network/foo/bar.py:509:17: E265 block comment should start with '# '

The test `ansible-test sanity --test validate-modules` failed with the following error:
lib/ansible/modules/network/foo/bar.py:0:0: E307 version_added should be 2.4. Currently 2.3

从上面的示例中我们可以看到 --test pep8--test validate-modules 已经识别出了问题。所给出的命令允许您在本地运行相同的测试,以确保您已经修复了所有问题,而无需将更改推送到 GitHub 并等待 Azure Pipelines,例如

如果您还没有 Ansible,请通过运行以下命令使用本地检出版本

source hacking/env-setup

然后运行 GitHub 评论中详述的测试

ansible-test sanity --test pep8
ansible-test sanity --test validate-modules

如果没有说明失败原因的 GitHub 评论,您可以通过点击 PR 末尾“检查失败”消息下的“详细信息 (Details)”按钮来查看结果。

重新运行失败的 CI 作业

有时您可能会发现您的 PR 因与您的更改无关的原因而失败。这可能由多种原因导致,包括

  • 访问外部资源(如 yum 或 Git 仓库)时出现临时问题

  • 创建用于运行测试的虚拟机时超时

如果出现上述任一情况,您可以通过以下方式重新运行 Azure Pipelines 测试

  • 在 Pull Request 中添加一条包含 /rebuild(完全重建)或 /rebuild_failed(仅重建失败的 CI 节点)的评论

  • 关闭并重新打开 Pull Request(完全重建)

  • 对分支进行另一次更改并推送到 GitHub

如果问题仍然存在,请联系社区。访问 Ansible 沟通指南 了解详情。

如何测试 PR

理想情况下,代码应包含证明其能够正常工作的测试。但这并非总是可行,而且测试并不总是全面的,特别是当用户无法访问各种平台,或者正在使用 API 或 Web 服务时。在这些情况下,针对真实设备的实时测试可能比针对模拟接口运行的自动化测试更有价值。无论如何,事情在第一次时也应该总是手动测试。

幸运的是,只要您熟悉 Ansible 的工作原理,协助测试 Ansible 就非常简单。

设置:安装 Pytest 及所需的 Pytest 库

Ansible 的单元测试框架利用了 pytest 库。在进行测试之前,请确保您已安装 pytest 以及任何额外的 pytest 库,如 pytest-mockpytest-xdist

有关更多信息,请参考文档:单元测试

设置:检出 Pull Request

您可以通过以下方式做到这一点

  • 检出 Ansible

  • 将建议的更改拉取到测试分支中

  • 进行测试

  • 在 GitHub 上针对该特定问题发表评论

操作方法如下

警告

测试发送给我们的 GitHub Pull Request 的源代码确实存在一些固有风险,因为发送的源代码可能存在错误或恶意代码,可能会对您的系统产生负面影响。我们建议在虚拟机上进行所有测试,无论是云实例还是本地虚拟机。一些用户喜欢为此使用 Vagrant 或 Docker,但它们是可选的。拥有不同 Linux 发行版或其他系统的虚拟机也很有用,因为某些功能(例如 apt 或 yum 等包管理器)是特定于这些操作系统版本的。

创建一个干净的工作区

git clone https://github.com/ansible/ansible.git ansible-pr-testing
cd ansible-pr-testing

接下来,找到您想要测试的 Pull Request 并记下其编号。它看起来像这样

Use os.path.sep instead of hardcoding / #65381

注意

仅测试 ansible:devel

重要的是,PR 请求的目标必须是 ansible:devel,因为我们不接受针对任何其他分支的 Pull Request。点发布版本(Dot releases)由 Ansible 工作人员手动挑选。

使用 Pull Request 编号来获取建议的更改并创建您的测试分支

git fetch origin refs/pull/XXXX/head:testing_PRXXXX
git checkout testing_PRXXXX

第一条命令获取 Pull Request 中的建议更改,并创建一个名为 testing_PRXXXX 的新分支,其中 XXXX 是与该 Pull Request 关联的实际编号(例如 65381)。第二条命令检出新创建的分支。

注意

如果 GitHub 用户界面显示 Pull Request 无法干净地合并,如果您对 Git 和编码不太熟悉,我们不建议继续操作,因为您将不得不解决合并冲突。这是原始 Pull Request 贡献者的责任。

注意

一些用户不创建功能分支,这在他们的 devel 版本中存在多个不相关的提交时可能会导致问题。如果源代码看起来像 someuser:devel,请确保 Pull Request 中仅列出了一个提交。

Ansible 源代码包含一个脚本,允许您直接从源代码使用 Ansible,而无需进行完整的安装,这是 Ansible 开发者经常使用的。

只需 source 该脚本(使用 Linux/Unix 术语)即可立即开始使用它

source ./hacking/env-setup

该脚本会修改 PYTHONPATH 环境变量(以及其他一些事项),只要您的 shell 会话保持打开,这些变量就会被暂时设置。

测试 Pull Request

至此,您应该已经准备好开始测试了!

一些关于测试内容的建议

  • 创建一个包含示例的测试 Playbook,检查它们是否功能正常

  • 测试查看是否有返回任何 Python 回溯(那是 Bug)

  • 在不同的操作系统上或针对不同的库版本进行测试

运行完整性测试

ansible-test sanity

更多信息:完整性测试

运行单元测试

ansible-test units

更多信息:单元测试

运行集成测试

ansible-test integration -v ping

更多信息:集成测试

任何潜在问题都应作为评论添加到 Pull Request 中(如果功能正常也可以评论),记得包含 ansible --version 的输出

示例

Works for me! Tested on `Ansible 2.3.0`.  I verified this on CentOS 6.5 and also Ubuntu 14.04.

如果 PR 没有解决问题,或者如果您看到单元/集成测试有任何失败,只需包含该输出即可

此更改导致我出现错误。

当我运行此 Ubuntu 16.04 时,它失败并出现了以下内容

```
一些输出
堆栈跟踪
一些其他输出
```

在线代码覆盖率

在线代码覆盖率报告是识别 Ansible 中测试改进领域的好方法。通过跟随红色区域,您可以深入浏览报告,找到完全没有测试的文件。添加能够清晰展示代码应如何工作的集成测试和单元测试,验证重要的 Ansible 功能,并在没有任何测试的领域提高覆盖率,这是帮助改进 Ansible 的一种有价值的方式。

代码覆盖率报告仅覆盖进行新功能开发的 Ansible devel 分支。Pull Request 和新代码将不会出现在 codecov.io 的覆盖率报告中,因此需要本地报告。大多数 ansible-test 命令允许您收集代码覆盖率,这对于指示在哪里扩展测试特别有用。有关更多信息,请参见 测试 Ansible 和集合

想了解更多关于测试的信息吗?

如果您想了解更多关于改进 Ansible 测试的计划,何不加入 Ansible 社区论坛