首页
/ Ansible 测试实战:用 ansible-test 运行 Sanity、单元与集成测试

Ansible 测试实战:用 ansible-test 运行 Sanity、单元与集成测试

2026-09-04 21:43:48作者:苗圣禹Peter

在 ansible-core 仓库中,所有测试工作都通过 ansible-test 这一统一入口完成,它覆盖三类测试:静态检查类的 sanity 测试、基于 pytest 的单元测试(unit tests),以及面向真实环境的集成测试(integration tests)。本文基于仓库内的 context/running-tests.md 编写,在完整保留其中全部命令与约束的基础上,结合 ansible-test 自身的实现源码,讲清每类测试的适用场景、容器选择规则和测试隔离选项,帮助你在改动 Ansible 代码后准确、可靠地验证自己的修改。

一、测试体系总览:一切以 ansible-test 为中心

context/running-tests.md 开宗明义:

All testing uses ansible-test, which supports sanity tests (linting/static analysis), unit tests, and integration tests.

即三类测试各有分工:

测试类型 关注点 是否需要容器 典型实现位置
Sanity tests lint、静态分析、文档/元数据校验 不需要(--docker 可选) test/lib/ansible_test/_internal/commands/sanity/
Unit tests 函数级行为,pytest 风格 推荐 --docker test/lib/ansible_test/_internal/commands/units/
Integration tests 插件/模块的公开 API 端到端行为 需要发行版容器 test/lib/ansible_test/_internal/commands/integration/

从源码结构看,ansible-test 的命令行解析层位于 test/lib/ansible_test/_internal/cli/,每类测试的子命令注册在独立的模块中,例如 sanity 子命令的参数定义就在 test/lib/ansible_test/_internal/cli/commands/sanity.py。这意味着下文中出现的所有 --test--list-tests 等选项,都不是约定俗成的写法,而是有明确的 argparse 定义可以查证。

二、Sanity 测试:不依赖容器的静态检查

2.1 核心约束

原文档给出两条关键规则:

  • Sanity 测试不需要 --docker;
  • 若本地缺少某些依赖(如额外的 Python 版本、shellcheck、PowerShell),对应测试可能被跳过——但对你验证自己的改动而言,"这通常无关紧要";
  • 要对整个变更集的所有文件运行 sanity,而不只是你正在编辑的文件。

2.2 完整命令集(继承自原文档)

# Run all sanity tests
ansible-test sanity -v

# List available sanity tests
ansible-test sanity --list-tests

# Run specific sanity tests
ansible-test sanity -v --test pep8 --test pylint

# Run sanity on specific files (paths relative to repo root)
ansible-test sanity -v lib/ansible/modules/command.py

# Run all sanity tests in a container (for full coverage)
ansible-test sanity -v --docker

对应关系说明:

  • --test 可重复使用,且取值受校验约束。在 test/lib/ansible_test/_internal/cli/commands/sanity.py#L49-L63 中,--test--skip-test 均为 action='append',并且 choices 直接来自 sanity_get_tests() 返回的测试清单,因此写错测试名会在参数解析阶段立即报错;
  • --list-tests 定义于同一文件的 #L71-L75,用于先枚举可用测试再挑选运行;
  • 针对特定文件运行时,路径以仓库根目录为基准(如 lib/ansible/modules/command.py)。

2.3 原文档的容器参数警告(务必注意)

[!NOTE] --docker 不带参数时默认使用 default 容器。不要把非容器名参数紧跟在 --docker 之后,否则它会被解析为镜像名。

也就是说,ansible-test sanity --docker ubuntu 并不是"在 ubuntu 容器里跑 sanity",而是试图使用名为 ubuntu 的镜像——sanity/unit 场景下应直接使用裸 --docker

2.4 更多可用选项(源码级补充)

除原文档涉及的选项外,sanity 子命令在 test/lib/ansible_test/_internal/cli/commands/sanity.py#L65-L112 中还注册了以下选项,按帮助文本原义列出:

  • --allow-disabled:允许运行默认被禁用的测试;
  • --enable-optional-errors:启用可选错误级别;
  • --lint:lint 输出写 stdout,其余写 stderr;
  • --junit:测试失败结果输出为 junit XML 文件;
  • --failure-ok:测试失败也返回成功退出码(保存结果后);
  • --prime-venvs:只准备虚拟环境而不实际运行测试;
  • --fix(仅 ansible 内容):能自动修复的问题直接修复,而不是仅报告。

另外,sanity 测试对历史遗留问题的豁免集中记录在 test/sanity/ignore.txt,排查"为什么某文件没有被检查到"时值得查看该文件。

三、单元测试:pytest 风格的单元验证

3.1 命令(继承自原文档)

# Run all unit tests
ansible-test units -v --docker

# Run a specific unit test (paths relative to repo root, targets in test/units/)
ansible-test units -v --docker test/units/modules/test_command.py

# Run with coverage
ansible-test units -v --docker --coverage

要点:

  • 单元测试目标位于 test/units/ 目录下,路径同样相对仓库根目录;
  • 单元测试默认需要容器执行(原文档给出的示例统一带 --docker);
  • --coverage 开启覆盖率收集,其底层由 test/lib/ansible_test/_internal/coverage_util.py 支持。

3.2 本仓库中的真实单元测试示例

单元测试目录 test/units/modules/ 中按模块组织了对应测试文件,例如 test/units/modules/test_apt.pytest/units/modules/test_get_url.pytest/units/modules/test_systemd.py 等,均可直接作为单文件运行 ansible-test units 的参数。单元测试的运行依赖由 test/units/requirements.txt 声明。

配套的测试编写约定见 context/writing-tests.md:单元测试应为 pytest 风格、以功能行为为导向而不是与 mock 强耦合;几乎所有的插件改动都要求集成测试覆盖公开 API。

四、集成测试:在发行版容器中验证端到端行为

4.1 命令(继承自原文档)

# Run all integration tests
ansible-test integration -v --docker ubuntu

# Run a specific integration target (directory name in test/integration/targets/)
ansible-test integration -v --docker ubuntu ping
  • 单个集成目标对应 test/integration/targets/ 下的一个目录名;
  • 例如 ping 目标就是一个真实存在的目录 test/integration/targets/ping/,其中包含 aliases 文件(声明该目标的别名与运行环境要求)和 tasks/(具体任务),这展示了集成目标的物理结构。

4.2 容器选择规则(原文档核心结论)

  • Sanity/Unit 测试:--docker(默认落到 default 容器);
  • 集成测试:--docker ubuntu--docker fedora发行版容器,不能使用 default/base;
  • basedefault 容器用于 sanity/unit 测试;
  • 集成测试应依据被测模块选择合适的发行版容器;
  • 各命令支持的容器清单及其支持的 Python 版本,可查看对应测试命令的 --help 输出。

从实现角度看,容器解析逻辑位于 test/lib/ansible_test/_internal/containers.pytest/lib/ansible_test/_internal/docker_util.py,因此 --help 中列出的可用容器并非文档约定,而是由这份代码动态给出。

五、测试隔离选项:--docker 与 --venv

原文档对执行环境的隔离给出了两个选项:

  • --docker(支持 Docker 或 Podman)——首选,提供可靠、隔离的测试环境;
  • --venv ——容器不可用时的回退方案,但由于宿主机环境差异,单元测试在 --venv 下可能不可靠。

选择建议:只要本机具备容器运行时,三类测试都优先走 --docker;仅在容器环境缺失时用 --venv 快速验证,并把最终结论保留到容器环境(或 CI)中确认。

六、把命令落到实际改动上的推荐工作流

结合本文各节,对一次典型的 ansible-core 改动,建议的验证顺序为:

  1. ansible-test sanity -v --list-tests 先确认要跑的测试项;
  2. ansible-test sanity -v <改动文件...> 对整个变更集跑静态检查(本地缺依赖导致的个别跳过可接受);
  3. ansible-test units -v --docker <目标文件> 运行相关单元测试;
  4. ansible-test integration -v --docker <发行版容器> <目标名> 验证插件/模块的公开行为;
  5. 需要留档或接入 CI 时,追加 --junit 之类的输出选项(见 sanity.py 源码中的定义)。

需要留意的两个边界:其一,--docker 后误跟非容器参数会被当作镜像名,集成测试务必显式指定发行版容器;其二,路径一律以仓库根目录为基准书写,避免相对路径歧义。

参考位置(便于继续深入)

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
987
504
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384