pytest 是 Python 最流行的测试框架,相比 unittest 不需要继承类、不需要
assertXxxAPI,普通函数 + 原生assert即可写测试。掌握命名规则、断言、参数化、Fixture 即可覆盖 80% 场景。
安装与命名约定
pip install -U pytest
pytest --versionpytest 通过文件名/函数名自动发现测试:
| 类型 | 命名规则 |
|---|---|
| 测试文件 | test_*.py 或 *_test.py |
| 测试函数 | test_ 开头 |
| 测试类 | Test 开头,无 __init__ |
第一个测试
# test_calculator.py
def add(a, b):
return a + b
def test_add():
assert add(1, 2) == 3
assert add(-1, 1) == 0
# 运行
# pytest # 全部
# pytest -v # 详细断言
直接用 Python assert,失败时 pytest 会自动展示双方差异:
assert add(2, 3) == 5
assert "python" in "pytest"
assert 0.1 + 0.2 == pytest.approx(0.3) # 浮点比较
with pytest.raises(ZeroDivisionError): # 异常断言
1 / 0参数化
@pytest.mark.parametrize 一次声明多组输入:
@pytest.mark.parametrize("a, b, expected", [
(1, 2, 3),
(-1, 1, 0),
(0.1, 0.2, 0.3),
])
def test_add(a, b, expected):
assert add(a, b) == pytest.approx(expected)Fixture:前置/后置 + 复用
@pytest.fixture
def sample_data():
data = [1, 2, 3, 4]
yield data
data.clear() # yield 之后是 teardown
def test_len(sample_data):
assert len(sample_data) == 4
def test_sum(sample_data):
assert sum(sample_data) == 10可控制作用域:scope="function|class|module|session"。放到 conftest.py 即对整个目录生效。
常用命令
| 命令 | 作用 |
|---|---|
pytest | 全部测试 |
pytest -v | 详细输出 |
pytest path/test.py | 指定文件 |
pytest path/test.py::test_func | 指定函数 |
pytest -x | 首次失败即停 |
pytest --lf | 只跑上次失败的 |
pytest -k "expr" | 按表达式选择测试名 |
pytest --html=report.html | HTML 报告(需 pytest-html) |
常见问题
| 问题 | 解决 |
|---|---|
| 测试未被发现 | 检查命名规则与 pytest.ini / pyproject.toml 中的 testpaths |
| 浮点断言失败 | 使用 pytest.approx() |
| Fixture 未注入 | 检查参数名是否与 fixture 名一致;fixture 是否在 conftest.py 中可被发现 |
| 想看完整 print | 加 -s 关闭 capture |