Pytest 是什么
Pytest 是 Python 生态中最流行的 测试框架,用于编写、运行和组织单元测试、功能测试甚至复杂的集成测试。它以简洁的语法、强大的插件系统和高度可扩展性著称,广泛应用于 Python 项目的自动化测试中。以下是其核心特性和使用详解:
Pytest 的核心特点
-
极简语法
- 无需继承类,使用普通函数和
assert
语句即可编写测试。 - 示例:
def test_add():assert 1 + 1 == 2 # 直接使用 assert,无需复杂断言方法
- 无需继承类,使用普通函数和
-
自动发现测试
- 自动识别以
test_
开头的函数或Test
开头的类中的测试方法。
- 自动识别以
-
丰富的断言
- 直接使用 Python 原生
assert
,失败时输出详细上下文(如变量值)。 - 对比 JUnit 的
assertEquals(expected, actual)
,Pytest 更直观:assert user.name == "Alice" # 失败时会显示 user.name 的实际值
- 直接使用 Python 原生
-
Fixture 机制
- 通过
@pytest.fixture
定义测试依赖(如数据库连接、临时文件),实现复用和依赖注入。@pytest.fixture def database():conn = create_db_connection()yield conn # 测试结束后自动清理conn.close()def test_query(database): # 自动注入 fixtureresult = database.execute("SELECT 1")assert result == 1
- 通过
-
参数化测试
- 用
@pytest.mark.parametrize
轻松测试多组输入。@pytest.mark.parametrize("a, b, expected", [(1, 2, 3), (0, 0, 0)]) def test_add(a, b, expected):assert a + b == expected
- 用
-
插件生态
- 支持 1000+ 插件扩展功能,例如:
pytest-cov
:生成代码覆盖率报告。pytest-xdist
:并行运行测试。pytest-mock
:集成 Mock 功能。
- 支持 1000+ 插件扩展功能,例如:
Pytest 的适用场景
- 单元测试:验证函数或类的逻辑。
- API 测试:结合
requests
库测试 HTTP 接口。 - UI 自动化:与 Selenium 或 Playwright 搭配使用。
- 数据库测试:通过 Fixture 管理测试数据。
Pytest vs. Unittest(Python 标准库)
特性 | Pytest | Unittest |
---|---|---|
语法 | 简洁(assert ) | 冗长(self.assertEqual() ) |
Fixture | 支持(@pytest.fixture ) | 需手动实现 setUp() /tearDown() |
参数化 | 原生支持(@parametrize ) | 需依赖 subTest 或第三方库 |
插件生态 | 丰富 | 有限 |
报告输出 | 彩色输出,详细信息 | 基础格式 |
快速开始
- 安装 Pytest:
pip install pytest
- 编写测试文件(如
test_sample.py
):def func(x):return x + 1def test_answer():assert func(3) == 4 # 测试通过assert func(5) == 6 # 测试通过
- 运行测试:
输出示例:pytest test_sample.py # 运行指定文件 pytest # 自动发现并运行所有测试
================ test session starts ================= collected 2 items test_sample.py .. [100%] ================ 2 passed in 0.01s ==================
高级功能示例
1. Mock 对象测试
from unittest.mock import Mockdef test_mock():mock = Mock(return_value=42)assert mock() == 42 # 模拟函数调用
2. 跳过测试
@pytest.mark.skip(reason="尚未实现")
def test_skip():assert False
3. 异常断言
def test_exception():with pytest.raises(ValueError):int("invalid") # 预期抛出 ValueError
为什么选择 Pytest?
- 减少样板代码:更少的代码,更多的测试。
- 调试友好:失败时自动输出局部变量和调用栈。
- 社区支持:广泛用于开源项目(如 Django、NumPy)。
- 与 CI/CD 集成:无缝对接 GitHub Actions、Jenkins。
总结:Pytest 是 Python 测试的“瑞士军刀”,适合从简单单元测试到复杂系统验证的所有场景。若项目已使用 unittest
,也可通过 pytest
直接运行旧测试,逐步迁移。