Pytest Fixtures 完全指南

Pytest fixtures 是消除测试准备代码重复的利器。本文系统讲解 fixture 的创建、fixture 间依赖、conftest.py 共享、五种作用域、参数化 fixture 与内置 fixture 用法。

最佳实践
测试检测与质量验证插画

本文依据官方文档整理,未执行运行验证或性能基准。代码片段展示局部用法,业务函数、数据和环境需按项目补齐;版本与配置以所引文档为准。

直接回答:Pytest fixture 是一种声明式的测试准备机制:把重复的 setup 代码封装成可复用的函数,测试通过参数注入自动获得所需资源——消除复制粘贴、集中维护测试数据、提升可读性,按作用域复用资源;是否隔离仍取决于数据设计与清理。

为什么需要 fixture

没有 fixture 时,测试文件里往往堆满重复的"建连接、造数据、清现场"代码。fixture 把这些准备工作抽出来,由 pytest 按需注入,测试函数只留核心断言。

第一个 fixture

import pytest

@pytest.fixture
def sample_user():
    return {"name": "Ada", "email": "ada@example.com"}

def test_user_email(sample_user):
    assert sample_user["email"].endswith("@example.com")

测试函数把 fixture 名写进参数列表,pytest 自动调用并传入返回值。需要清理时用 yield:

@pytest.fixture
def db():
    conn = connect("sqlite:///:memory:")
    yield conn          # 测试执行
    conn.close()        # 正常pytest收尾时执行;进程强杀/崩溃不保证

fixture 依赖 fixture

fixture 之间可以互相请求,构建出层次化的准备链:

@pytest.fixture
def admin_user(db):
    return db.create_user(role="admin")

def test_admin_can_ban(admin_user):
    assert admin_user.has_permission("ban")

conftest.py:跨文件共享

把 fixture 放进 conftest.py,同目录及子目录的所有测试文件都能直接使用,无需 import。目录可以嵌套多层 conftest,就近覆盖——这是 pytest 项目组织测试基础设施的标准做法。

四种作用域

作用域 生命周期 典型用途
function(默认) 每条用例重建 需要干净状态的资源
class 每个测试类一次 类内共享的重资源
module 每个文件一次 只读配置、种子数据
package 包内测试结束后清理 包级共享资源
session 每个测试进程的会话一次 数据库容器、浏览器

yield之前若已分配资源又报错,不会运行yield后的清理,可用try/finally或及时注册finalizer。pytest-xdist中session fixture通常每个worker各一份。重资源用长作用域提速,状态敏感的资源保持 function 级保隔离——性能与独立性之间的取舍就藏在这一参数里。

参数化 fixture

一个 fixture 跑多份配置:

@pytest.fixture(params=["sqlite", "postgres"], scope="session")
def engine(request):
    return create_engine(request.param)

def test_migration(engine):
    assert run_migrations(engine)

每条使用它的测试会按参数各跑一遍,报告里清晰标注 test_migration[sqlite] / test_migration[postgres]。跨数据库兼容性测试这类场景因此变得极其简洁。

好用的内置 fixture

  • tmp_path:每条测试独立临时目录;默认会保留最近几次运行的目录用于排错,不保证测试结束立刻删除;
  • capsys:捕获 print 输出做断言;
  • monkeypatch:安全地打补丁(改属性、环境变量),测完自动还原;
  • request:访问当前测试上下文,高级参数化的钥匙。

常见问题(FAQ)

Q:fixture 和 setUp/tearDown 有什么区别?
A:fixture 是声明式、可组合、带作用域的依赖注入;unittest setUp 是命令式、每条测试前执行,setUpClass 才是类级。pytest 项目统一用 fixture,表达力和复用性都更好。

Q:什么时候该把 fixture 提到 session 级?
A:创建代价高且测试不会修改其状态的资源(只读数据、容器、浏览器驱动)。一旦被某些测试"写脏",降级或加清理逻辑。

Q:fixture 报错会怎样?
A:使用它的测试标记为 ERROR 而非 FAILED,pytest 会展示 fixture 内部的完整堆栈。调试时可以先单独跑一条用例缩小范围。

官方参考

资料核对日期:2026-09-29。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台