首页/开发/软件测试速查/pytest fixture 夹具
自动化测试66 条

pytest fixture 夹具

fixture 用 @pytest.fixture 声明可复用的前置资源(连接、临时数据、浏览器),通过参数注入用例;scope 控制生命周期,yield 之后执行清理。

软件测试速查开发更新于 2026-10-13

pytest fixture 是什么

fixture 是 pytest 的依赖注入机制:用 @pytest.fixture 声明一个可复用的前置资源(数据库连接、临时目录、测试客户端、浏览器实例),用例把夹具名写成参数即可获得注入。scope 控制生命周期(函数、类、模块、会话),生成器写法的夹具在 yield 之后执行清理——无论用例失败与否都会执行,这是资源归还可靠性的来源。夹具既可以替代传统的 setUp/tearDown,也比它更灵活:按需组合、跨文件共享、可参数化。

基本信息

声明方式@pytest.fixture 装饰器标注函数
注入方式用例把夹具名作为形参
生命周期scope 取值:function、class、module、session
清理机制yield 之后的代码在用例结束后执行
共享范围同文件直接可用;跨文件放在 conftest.py
内置夹具tmp_path、capsys、monkeypatch 等由 pytest 提供

典型使用场景

  • 数据库连接管理:会话级建连、用例级事务回滚
  • 临时文件与目录:用内置 tmp_path 生成隔离的测试工作区
  • 登录态复用:会话级登录一次,函数级复制用户上下文
  • 测试客户端:为接口测试准备带鉴权的 client 对象
  • 参数化夹具:用 params 对同一用例跑多组环境配置
  • 清理兜底:yield 后关闭连接、停止容器、回滚数据

夹具示例

夹具示例
import pytest

@pytest.fixture
def db():
    conn = connect()      # 建立资源
    yield conn            # 注入给用例使用
    conn.close()          # 用例结束后清理(失败也会执行)

def test_query(db):
    assert db.query("select 1") == 1

@pytest.fixture(scope="session")
def api_client():
    client = login()      # 整个会话只登录一次
    yield client

scope 取值与代价

scope生命周期适用与注意
function每个用例一次(默认)状态隔离最好,重资源场景代价高
class每个测试类一次类内用例共享,跨类重新构建
module每个模块一次模块级数据准备,注意用例顺序耦合
session整个会话一次最省资源,但修改会串场需复位
session 级夹具产出的对象被用例修改会串场:共享状态要在用例间复位,或者把可变部分降到 function 级;依赖执行顺序互不得的套件在并行下必炸。
夹具间的依赖也能注入:一个夹具把另一个夹具名写成参数即形成链式构建;把公共组合沉淀成高层夹具,用例只声明它真正需要的资源。
conftest.py 按目录层级生效:子目录可以看到父目录的夹具,反向不可见;跨团队共享的夹具放在对应层级的 conftest 中,避免全项目铺开。

易错点

  • 数据库连接、浏览器等重资源用 function 级作用域创建,整体执行时间被放大
  • yield 之后的清理未考虑异常路径:夹具清理代码自身抛错会掩盖用例的真实失败
  • session 级共享对象被用例修改,后续用例读到脏状态且难以定位
  • 夹具名与模块变量重名:注入被遮蔽,用例实际拿到的是错误对象
  • 把大量互不相关的准备逻辑塞进一个万能夹具:依赖关系混乱,单跑与全量跑结果不一致

数据来源与参考

  • pytest 官方文档:Fixtures(docs.pytest.org)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌