fixture未放conftest.py中导致无法跨类共享:类内定义的fixture仅对该类生效,作用域默认function且彼此隔离;跨类复用必须提至conftest.py,且需确保其与测试文件同目录或父目录链中,文件名严格为conftest.py。

fixture没放在conftest.py里,只在测试类内部定义
这是最常见的原因:你在某个 TestA 类里用 @pytest.fixture 定义了一个 fixture,比如:
class TestA:
@pytest.fixture
def token(self):
return "abc123"
<pre class="brush:php;toolbar:false;">def test_a(self, token):
assert token == "abc123"
这个 token 只对 TestA 内部的测试方法有效。Pytest 不会跨类查找同名 fixture,哪怕另一个类 TestB 也写了同名 @pytest.fixture,它们彼此完全隔离。
- 类内定义的 fixture 作用域默认是
function,且仅对该类生效 - Pytest 不支持“继承式共享”,
TestB继承TestA也不自动获得其 fixture - 想让多个类共用,必须把 fixture 提到类外 —— 最佳位置是
conftest.py
conftest.py位置不对或未被识别
即使你写了 conftest.py,它也可能没起作用。Pytest 查找 conftest.py 是按目录层级向上搜索的,不是全局扫描。
-
conftest.py必须和测试文件(如test_api.py)在**同一目录**,或在其**父目录链上** - 如果测试文件在
tests/api/test_user.py,而conftest.py在tests/conftest.py,那它能被识别;但如果只放在tests/api/conftest.py,那tests/auth/test_login.py就用不到它 - 文件名必须严格是
conftest.py(大小写敏感),不能是Conftest.py或conftest.pyc - 目录下必须有
__init__.py(哪怕为空),否则 pytest 可能不把它当 package 处理
fixture作用域太小,或被同名fixture覆盖
你可能已经把 fixture 放进了 conftest.py,但还是无法跨类共享,问题常出在作用域或命名冲突上。
- 如果用了
@pytest.fixture(scope="function")(默认),它每次测试函数调用都重建,这本身没问题,但如果你在多个类里定义了同名 fixture,Pytest 会按“就近原则”优先取类内定义的,直接忽略conftest.py版本 - 如果两个
conftest.py(比如根目录和子目录各一个)都定义了token,子目录下的测试会优先用子目录conftest.py的,而不是根目录的 - 确保没有在测试类或测试函数里重复定义同名变量或 fixture,比如
def test_xxx(token):同时又在函数体内写了token = ...,会覆盖 fixture 注入
fixture返回了可变对象,导致状态污染
看起来“共享成功”了,但实际行为异常 —— 比如 token 被某个测试改了,后续测试拿到的是脏数据。这不是“无法共享”,而是共享方式错了。
- 直接返回字典、列表等可变对象(如
return {"auth": True})会导致所有测试共用同一内存地址 - 正确做法是返回不可变值(如字符串、tuple),或用工厂函数封装:
@pytest.fixture
def make_token():
def _make():
return {"auth": True, "user_id": 123}
return _make
<p>def test_one(make_token):
data = make_token() # 每次调用都生成新 dict
data["auth"] = False</p><p>def test_two(make_token):
data = make_token()
assert data["auth"] is True # 不受 test_one 影响
</p>
真正卡住人的往往不是“找不到 fixture”,而是它找到了、注入了、但行为不符合预期 —— 尤其当 fixture 返回可变对象且作用域设为 session 或 module 时,这种隐性污染最难排查。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











