pytest 是什么
pytest 是 Python 生态使用最广的测试框架:用普通函数加 assert 写用例,靠命名约定自动发现测试,断言失败时自动展开两侧表达式便于定位。夹具(fixture)、参数化、标记、插件体系都是内置或一等公民,覆盖并行执行、失败重试、覆盖率等日常需求。它的另一大优势是兼容性:能直接收集运行 unittest 风格的用例,存量项目可以渐进迁移而不必一次重写。对测试工程师而言,pytest 也是接口测试与集成测试的常用底座:用 fixture 管理登录态与数据库连接,用参数化驱动多组数据,用标记切分冒烟与慢速集合。
基本信息
| 安装 | pip install pytest |
|---|---|
| 发现规则 | 文件名 test_*.py 或 *_test.py,函数名以 test_ 开头 |
| 运行入口 | 命令行 pytest,可指定文件、目录或用例节点 |
| 核心能力 | assert 内省、fixture、parametrize、mark 标记、插件 |
| 异常断言 | pytest.raises 上下文断言异常类型与消息 |
| 配置文件 | pytest.ini 或 pyproject.toml 的 tool.pytest 段 |
| 兼容性 | 可直接运行 unittest 风格用例,渐进迁移 |
典型使用场景
- 新项目单元测试:函数级快速验证与 CI 门禁
- 存量 unittest 迁移:先混合运行,再逐步改写为函数式用例
- 接口测试:配合 requests/httpx 对 HTTP 接口断言状态与响应体
- 异常与边界用例:用 raises 断言异常类型与消息,用参数化覆盖边界数据
- 资源管理:用 fixture 统一准备数据库连接、临时目录与测试客户端
- 复杂筛选运行:按表达式、标记或上次失败集合挑选用例
最简用例
最简用例
# test_calc.py:被测函数与用例同文件仅用于演示
def add(a, b):
return a + b
def test_add():
assert add(1, 1) == 2
def test_add_negative():
assert add(-1, -2) == -3 # 负数同样满足加法语义运行方式
运行方式
pip install pytest # 安装
pytest -q # 安静模式跑全部用例
pytest tests/test_calc.py::test_add # 只跑指定用例
pytest --collect-only -q # 核对用例是否被正确收集
pytest -k "add and not slow" # 按名称表达式筛选常用命令行选项
| 选项 | 作用 | 典型用法 |
|---|---|---|
| -q | 精简输出,适合 CI 日志 | pytest -q |
| -k | 按名称表达式筛选用例 | pytest -k order |
| -x | 首个失败立即停止 | pytest -x |
| --lf | 只重跑上次失败用例 | pytest --lf |
| -m | 按标记筛选 | pytest -m smoke |
| --collect-only | 只收集不执行,核对发现结果 | pytest --collect-only -q |
用例文件与函数必须匹配 test_ 前缀,否则会被静默跳过;拿不准时用 --collect-only 核对收集结果,这是排查不执行问题的第一步。
断言风格:assert 由 pytest 重写后失败时自动打印两侧值;复杂断言拆成多条小断言,首条失败的位置往往就是根因位置。
异常路径用 pytest.raises(ValueError) 上下文捕获并断言异常类型;只捕获不断言类型,异常被吞掉时用例仍然通过。
常用插件:pytest-xdist 并行、pytest-cov 覆盖率、pytest-rerunfailures 失败重试;能用生态插件解决的能力,不要自研脚本。
夹具与钩子按目录层级由 conftest.py 提供;夹具作用域从函数到会话可选,配置与钩子细节见 pytest-conftest 与 pytest-fixture 条目。
运行配置建议:把常用选项(如 addopts 与 strict-markers)写进 pytest.ini 或 pyproject.toml,本地与 CI 行为一致,减少记忆成本。
用例组织习惯:一个文件对应一个被测模块,用例名采用被测函数加场景加预期的风格,失败列表不看代码也能还原场景。
覆盖率插件配合分支覆盖率选项观察未覆盖分支,比只看总行数更有指导意义;数字只作参考,断言质量才是核心。