conftest.py 的作用是使夹具在所在目录及子目录下自动生效,其作用域由文件路径和 scope 共同决定;pytest 仅向上查找最近的 conftest.py,不向下穿透兄弟目录,且同名夹具以更靠近测试文件者为准。

conftest.py 的作用不是“共享夹具”,而是让夹具在指定目录及子目录下自动生效——它本身不导出、不跨目录传播,作用域由其所在路径和 scope 共同决定。
conftest.py 文件放在哪才生效
pytest 只会向上查找最近的 conftest.py,不会向下穿透到兄弟目录。比如:
tests/
├── conftest.py ← 对 tests/ 下所有测试(含 unit/、e2e/)有效
├── unit/
│ └── test_api.py
└── e2e/
└── test_login.py
但如果把 conftest.py 放进 unit/ 目录,则 e2e/ 下的测试完全看不到它。
- 多个
conftest.py可共存,但同名夹具在更靠近测试文件的conftest.py中定义时,会覆盖上级的 - 文件名必须是
conftest.py,不能叫conftest_p.py或带其他后缀 - 它不能被直接 import,pytest 仅在收集测试时自动加载
定义夹具时必须加 @pytest.fixture 装饰器
只写函数不行,pytest 不识别未装饰的普通函数为夹具。常见错误是漏掉装饰器或拼错名字(比如写成 @pytest.fixtrue)。
正确写法示例:
import pytest
@pytest.fixture
def db_connection():
conn = connect_to_test_db()
yield conn
conn.close()
- 不加
@pytest.fixture,即使函数名是db_connection,测试函数里写def test_something(db_connection):也会报fixture 'db_connection' not found - 如果夹具需要参数化,用
params=+ids=,但注意scope='session'时参数化行为受限(每个参数会单独触发一次 setup/teardown) - 避免在夹具里做耗时操作却不设
scope;默认scope='function'意味着每次测试都重建,可能拖慢整个测试套件
跨目录使用夹具的唯一可靠方式:显式 import + @pytest.fixture(autouse=True)
pytest 不支持从其他 conftest.py 中 import 夹具并复用——即便你手动 from ..conftest import my_fixture,pytest 依然不认识它。真正可行的是:
- 把夹具定义在普通 Python 模块(如
tests/fixtures/db.py)中,用@pytest.fixture装饰 - 在目标
conftest.py中 import 并重新声明一次,例如:from ..fixtures.db import db_connection @pytest.fixture def db_connection(): return db_connection() - 或者更常用的是设
autouse=True,让夹具自动注入,不用在每个测试函数签名里写参数名:@pytest.fixture(autouse=True, scope='session') def setup_logging(): configure_test_logging()
注意:autouse=True 容易引发隐式依赖,尤其当多个 autouse 夹具之间有执行顺序要求时,得靠 yield 或 request.addfinalizer 控制 teardown 时机。
为什么 fixture 有时“看起来没生效”
最常遇到的不是语法错,而是作用域和命名冲突问题:
-
scope='module'的夹具,在同一个.py文件内多次测试共享一个实例;但如果测试分散在多个文件,每个文件都会新建一份——这不是 bug,是预期行为 - 两个
conftest.py都定义了同名夹具(比如都叫client),pytest 会选择离测试文件路径更近的那个,不会合并或报错 - 夹具函数名和测试函数参数名必须完全一致(包括大小写),
def test_foo(api_client)要求夹具名为api_client,写成ApiClient就找不到 - 如果夹具里抛异常,pytest 默认只显示 “fixture failed”,需加
-v -s查看完整 traceback
最易被忽略的一点:conftest.py 里的夹具无法被 python -m pytest tests/ 之外的路径调用——比如你在项目根目录运行 pytest,但 conftest.py 在 tests/ 下,那只有 tests/ 子树里的测试能用它;根目录下的 test_*.py 是看不到的。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











