# pytest 缓存机制:重跑失败测试与状态保持策略

## 摘要
本文基于 pytest 官方文档资料,解析 `--lf`、`--ff` 等选项在重跑失败测试时的内部工作原理,介绍如何查看缓存内容以及如何在 CI/CD 环境中通过清除缓存确保环境隔离。

## pytest 如何记录失败状态
当首次运行包含失败的测试套件时(例如使用 `pytest -q`),pytest 会自动记录失败的测试项。这些记录并非存储在数据库或外部文件中,而是保存在当前会话的内存配置对象中。官方文档指出,pytest 内部通过 `config.cache` 对象来存储跨会话的值。

在命令行层面,pytest 提供了两个核心选项来处理失败状态:
- **--lf (last-failed)**:仅重跑上次运行中失败的测试。此时,通过的测试会被“ deselected”(不执行),输出中会显示 `run-last-failure: rerun previous X failures`。
- **--ff (failed-first)**:先运行上次失败的测试,然后再运行其余测试。这有助于快速定位问题,输出中会显示 `run-last-failure: rerun previous X failures first`。

此外,还有一个新选项 **--nf (new-first)**,它会根据文件修改时间对测试进行排序,优先运行较新的文件中的测试,随后再处理其他测试。

## 查看缓存中的具体内容
如果用户想深入了解 pytest 内部保存了哪些状态(例如哪些测试被标记为失败,或者自定义的缓存值),可以使用 **--cache-show** 命令。

该命令会列出 `.pytest_cache` 目录下的内容。默认情况下,它会显示所有缓存键:
- `cache/lastfailed`:包含上次失败的测试列表(如 `{'test_caching.py::test_function': True}`)。
- `cache/nodeids`:记录已收集的测试节点 ID 列表。

用户还可以使用通配符过滤特定内容,例如运行 `pytest --cache-show example/*` 仅查看以 `example/` 开头的缓存键。如果未指定参数,pytest 会显示所有可用的缓存数据,包括失败的测试标记和自定义存储的值。

## CI/CD 环境下的缓存清除与隔离策略
在持续集成(CI)或持续部署(CD)环境中,测试环境的隔离性和结果的正确性至关重要。为了避免上次运行的失败状态影响本次运行(例如导致误判为“仅重跑失败项”),或者为了清理自定义的缓存数据,必须清除 pytest 缓存。

pytest 提供了 **--cache-clear** 选项来实现这一操作。执行 `pytest --cache-clear` 会删除所有跨会话的缓存内容。官方文档明确建议:在 CI 服务器等对隔离性和正确性要求高于速度的场景中,应使用此选项。

需要注意的是,pytest 的缓存插件默认是启用的(内部名称为 `cacheprovider`),但可以通过配置禁用。如果完全不需要缓存功能,可以选择不启用该插件;但在常规开发或 CI 流程中,通常保留缓存以利用其重跑失败测试的功能,仅在需要彻底重置环境时使用 `--cache-clear`。

## 总结
pytest 的缓存机制通过内存中的 `config.cache` 对象记录失败状态,支持通过 `--lf`、`--ff` 等选项灵活重跑测试。用户可通过 `--cache-show` 查看缓存详情,并在 CI/CD 环境中使用 `--cache-clear` 确保每次运行都是独立且干净的。这些功能共同构成了 pytest 高效调试和自动化测试的基础。

信息来源