第15篇. pytest 入门指南:从零开始掌握 Python 测试框架的核心概念与使用方法**
1. 什么是 pytest?为什么选择它?
pytest 是目前 Python 生态中最受欢迎的测试框架。它简洁、强大、插件丰富,被广泛用于单元测试、集成测试、API 测试、自动化测试等场景。
相比 unittest,pytest 的优势:
- 测试函数无需继承类,写法更简洁
- 使用原生 assert 语句,失败信息更清晰
- 支持参数化测试、fixture、标记、插件系统
- 自动发现测试文件和测试函数
- 丰富的命令行选项和报告
2. 安装与基本使用
Bash
pip install pytest
验证安装:
Bash
pytest --version
创建一个简单测试文件 test_demo.py:
Python
# test_demo.py
def test_addition():
assert 1 + 1 == 2
def test_subtraction():
assert 5 - 3 == 2
运行测试:
Bash
pytest
或更详细输出:
Bash
pytest -v
3. 核心概念
3.1 测试发现规则
pytest 自动发现以下文件和函数:
- 文件名以 test_ 开头 或 以 _test.py 结尾
- 函数名以 test_ 开头
- 类名以 Test 开头,方法名以 test_ 开头
3.2 断言(assert)
pytest 使用 Python 原生 assert,失败时会显示详细差异:
Python
def test_list():
numbers = [1, 2, 3]
assert len(numbers) == 3
assert 2 in numbers
assert numbers == [1, 2, 3] # 失败时会显示详细对比
3.3 测试类(可选)
Python
class TestCalculator:
def test_add(self):
assert 1 + 2 == 3
def test_divide(self):
assert 10 / 2 == 5
4. 基本方法与常用特性
4.1 参数化测试(最常用特性)
使用 @pytest.mark.parametrize 一组数据运行多次测试:
Python
import pytest
@pytest.mark.parametrize("a, b, expected", [
(1, 2, 3),
(0, 0, 0),
(-1, 1, 0),
(10, -5, 5),
])
def test_add(a, b, expected):
assert a + b == expected
4.2 fixture(测试前置/后置)
fixture 是 pytest 最强大的特性之一,用于准备测试数据、初始化对象、清理资源:
Python
import pytest
@pytest.fixture
def sample_list():
return [1, 2, 3, 4, 5]
def test_list_length(sample_list):
assert len(sample_list) == 5
def test_list_sum(sample_list):
assert sum(sample_list) == 15
常用 fixture 作用域:
- function(默认):每个测试函数运行一次
- class:每个测试类运行一次
- module:每个模块运行一次
- session:整个测试会话运行一次
4.3 异常测试
使用 pytest.raises 验证异常:
Python
import pytest
def divide(a, b):
return a / b
def test_divide_by_zero():
with pytest.raises(ZeroDivisionError):
divide(10, 0)
4.4 标记(markers)
用于分类、跳过、预期失败等:
Python
import pytest
@pytest.mark.smoke # 冒烟测试
def test_login():
assert True
@pytest.mark.skip(reason="功能未完成")
def test_new_feature():
assert False
@pytest.mark.xfail(reason="已知 bug")
def test_known_bug():
assert 1 + 1 == 3
常用标记:
- @pytest.mark.skip
- @pytest.mark.xfail
- @pytest.mark.parametrize
- @pytest.mark.slow
- @pytest.mark.integration
5. 常用 pytest 命令
Bash
pytest # 运行所有测试
pytest -v # 详细输出
pytest tests/ # 指定目录
pytest -k "add" # 运行名称包含 "add" 的测试
pytest --tb=line # 简化错误堆栈
pytest --cov=src --cov-report=html # 生成覆盖率报告
pytest -m smoke # 运行带 @pytest.mark.smoke 的测试
pytest --maxfail=3 # 最多允许 3 个失败后停止
6. 最佳实践建议
- 测试文件统一命名为 test_xxx.py
- 一个测试函数只验证一个行为
- 使用 fixture 复用测试数据
- 优先使用参数化测试代替重复代码
- 为复杂 fixture 添加文档字符串
- 使用 conftest.py 定义全局 fixture
- 定期运行覆盖率检查(目标 > 80%)
7. 小结
pytest 的核心优势在于:
- 简洁的语法(无需类继承,使用原生 assert)
- 强大的参数化与 fixture
- 灵活的发现与标记机制
- 丰富的插件生态
掌握了测试函数、assert、参数化、fixture 这四个基本概念,你就已经具备了用 pytest 编写高质量测试的能力。
进阶方向:
- 自定义 fixture 作用域与依赖
- pytest-mock 模拟外部依赖
- 异步测试(pytest-asyncio)
- API 测试(requests + pytest)
- 报告生成(pytest-html、allure)
推荐资源:
- 官方文档:https://docs.pytest.org
- pytest 中文文档:https://pytest.org.cn
- Real Python pytest 教程
你现在就可以创建一个 tests/ 目录,写下第一个 test_xxx.py 文件,运行 pytest 试试看!