pytest作用域内fixture的存储位置及内部实现细节问询
pytest Fixture 作用域与存储机制详解
1. pytest 如何维护作用域内的 fixture
pytest 会根据 fixture 的作用域(session/module/class/function),将它们分别维护在对应层级的测试节点缓存中:
- session 级 fixture:存在
Session实例的内部缓存结构中,整个测试会话周期内只实例化一次,所有测试节点共享。 - module 级 fixture:存储在对应的
Module测试节点的缓存里,该模块内的所有测试用例共享。 - class 级 fixture:绑定到对应的
Class测试节点,仅该类下的测试方法可访问。 - function 级 fixture:每个测试函数对应一个
Function测试节点,fixture 实例就存在该节点的缓存中,测试结束后销毁。
这些缓存并非全局统一的大字典,而是按作用域分层存储在各个测试节点的内部属性中(比如节点的 _fixture_cache 或 _setupstate 相关结构),确保不同作用域的 fixture 相互隔离,生命周期符合预期。
2. fixture 返回对象的存储与注入机制
注册阶段
所有定义的 fixture 首先会被注册到 pytest 的FixtureManager(通过 config._fixturemanager 访问)中,具体存储在 _arg2fixturedefs 字典里——键是 fixture 的名称,值是对应的 FixtureDef 对象,包含 fixture 的定义、作用域、依赖等元信息。
实例化与存储
当测试用例需要某个 fixture 时,pytest 会根据作用域找到对应的测试节点,然后检查该节点的缓存中是否已有实例化后的 fixture 对象:
- 如果没有,就执行 fixture 的定义函数,实例化对象后存入该节点的专属缓存(比如
_fixture_cache)。 - 如果已有,直接复用缓存中的对象,避免重复实例化。
注入原理
测试函数的参数名会和 fixture 名称做匹配,pytest 在执行测试前,会递归解析所有依赖的 fixture 链,依次实例化并从对应节点的缓存中取出对象,最后通过参数传递的方式注入到测试函数中。整个过程不需要手动传递,完全由 pytest 的执行框架自动完成。
简单来说,fixture 的定义元信息存在全局的注册表,而实例化后的对象则按作用域分层存在各个测试节点的缓存里,注入就是通过参数名匹配+缓存取值的方式实现的。
内容的提问来源于stack exchange,提问作者jxramos
相关产品推荐
相关产品推荐

