pytest 是测试思维和工程实践的升级:用 fixture 替代 setUp/tearDown 实现解耦复用,原生 assert 提升可读性与失败定位,@pytest.mark.parametrize 简化参数化,conftest.py 统一管理跨模块配置。

从 unittest 过渡到 pytest 不是简单换一个装饰器,而是测试思维和工程实践的升级:pytest 用更少代码表达更多意图,天然支持参数化、fixture 分层、插件生态和清晰的失败定位,让自动化测试真正可维护、易扩展、能落地。
用 fixture 替代 setUp/tearDown,实现逻辑解耦与复用
unittest 中重复的初始化(如启动浏览器、创建数据库连接)常堆在 setUp 里,一旦多个用例依赖不同前置条件就容易混乱。pytest 的 fixture 通过函数声明 + scope 控制 + 自动注入,把“准备什么”和“怎么用”分开。
- 用 @pytest.fixture(scope="function") 定义单个用例级资源(如临时文件、干净的 API client)
- 用 @pytest.fixture(scope="session") 管理全局一次性资源(如测试数据库实例、Selenium driver)
- 在测试函数参数中直接写 fixture 名,pytest 自动调用并传入,无需 self.driver = …
- 支持 yield 实现“setup + teardown”一体化,yield 前是准备,之后是清理
告别冗长的 assertEqual,用原生 assert + pytest 自动断言重写
unittest 要写 self.assertEqual(a, b, "提示信息"),既啰嗦又限制表达力。pytest 允许直接写 assert a == b,失败时自动展开变量值、显示上下文、高亮差异部分。
- 字符串对比自动展示 diff(尤其对 JSON 响应或 HTML 片段非常友好)
- 断言失败时显示完整调用栈 + 变量快照,无需手动 print 或 logging
- 配合自定义异常或 pytest.raises(),可精准验证错误路径
参数化测试不再拼 for 循环,用 @pytest.mark.parametrize 一行驱动多组数据
unittest 中要实现“同一逻辑测多组输入”,得靠继承、data-driven 模板或第三方库。pytest 内置参数化能力,结构清晰、报告直观、失败独立标记。
立即学习“Python免费学习笔记(深入)”;
- @pytest.mark.parametrize("user, pwd, expected", [("a", "123", True), ("b", "", False)]) 直接为测试函数注入多组参数
- 支持 ids 参数自定义用例名(如 ids=["login_ok", "empty_pwd"]),报告里一目了然
- 可嵌套使用(如组合用户类型 × 权限级别),避免用例爆炸但逻辑仍清晰
用 conftest.py 统一管理跨模块 fixture 和公共配置
当项目变大,多个 test_*.py 文件都需要登录态、mock server 或测试配置时,重复定义 fixture 会失控。conftest.py 是 pytest 的“配置中心”——它自动被同目录及子目录下所有测试识别,无需 import。
- 在项目根目录或 tests/ 下建 conftest.py,集中声明常用 fixture(如 db_session、auth_token)
- 可在其中配置 pytest_configure 修改全局行为(如添加命令行选项 --env)
- 结合 pytest_plugins 可加载本地插件,比如封装截图、日志收集等通用能力
不复杂但容易忽略:pytest 的强大不在语法糖,而在它把“测试即代码”的原则落到实处——可读即文档,可运行即验证,可组合即扩展。










