cached_result 不是 pytest 原生功能,官方文档、源码及主流插件中均不存在;需通过 scope="session" 等 fixture 作用域实现跨用例复用,而非伪缓存。

cached_result 不是 pytest 原生提供的功能,它并不存在于 pytest 核心或标准插件中。你无法直接使用 cached_result 实现跨用例缓存。
为什么找不到 cached_result?
pytest 官方文档、源码及主流插件(如 pytest-xdist、pytest-cache)中均无此函数或 fixture 名。常见混淆来源包括:
- 误将自定义 fixture 命名为
cached_result,但未正确定义作用域和依赖 - 混淆了
pytest-cache(已弃用)的旧 API 或第三方库(如pytest-cached)的命名 - 把
functools.cache或lru_cache的用法错误映射到 pytest 上下文
如何真正实现测试间共享计算结果?
必须借助 pytest 的 fixture 机制,并显式控制其 scope。关键点不是“缓存”,而是“复用生命周期长的 fixture 实例”:
- 使用
@pytest.fixture(scope="session")—— 最常用,适用于进程级不变的数据(如初始化一次的数据库连接、配置字典) - 避免在
session级 fixture 中引用function-scope 的 fixture(会触发 scope 冲突错误:ScopeMismatch) - 若需条件性重算,不能靠“缓存失效”,而应手动加标志位或封装成带状态的对象
- 示例:一个只初始化一次的 HTTP client
@pytest.fixture(scope="session")
def api_client():
# 只执行一次
return requests.Session()
哪些做法看似“缓存”实则危险?
以下模式容易导致状态污染或非预期行为:
- 在
function-scope fixture 中用global或模块变量保存结果(多进程/多线程下不可靠) - 用
pytest.config.cache(config.cache是 session-scoped,但仅支持字符串/JSON 序列化值,且写入磁盘,不适用于对象实例) - 试图给 fixture 加
@lru_cache()装饰器——fixture 本身是函数调用入口,装饰后会绕过 pytest 的 scope 管理,造成 fixture 失效或重复初始化 - 在测试函数内直接调用耗时操作并赋值给全局变量——违反测试隔离原则,后续用例可能读到脏数据
跨用例共享数据的真实限制
pytest 的 fixture scope 是静态声明的,无法运行时动态“清除某次缓存”。如果你需要“同一组用例内复用、不同组之间隔离”,必须拆分为多个 class 或用 pytest.mark.parametrize + scope="class" 配合:
-
scope="class":每个测试类共用一份 fixture 实例 - 注意
class内测试方法顺序不确定,不要假设执行先后 - 若类内某测试失败,pytest 默认跳过后续方法(除非用
pytest-xdist或--tb=no等调整),此时共享状态可能处于中间态
真正的难点不在“怎么存”,而在“何时失效、谁负责清理、并发下是否安全”——这些都得自己设计,pytest 不替你管。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











