Pytest 基础概念
以下是 Pytest 测试框架的 基础概念 整理,涵盖其核心设计、关键术语和基本用法:
1. 核心设计理念
- 简洁易用:通过简单的断言和自动测试发现,降低测试代码复杂度。
- 可扩展性:通过插件系统和钩子函数(Hooks)支持高度定制。
- 明确反馈:提供清晰的错误报告,快速定位问题。
2. 安装与运行
2.1 安装
pip install pytest
2.2 运行测试
pytest [文件或目录路径] # 默认运行当前目录下所有测试
常用选项:
- -v:显示详细输出。
- -k <表达式>:按名称匹配运行特定测试(如 -k "test_login")。
- -m <标记>:运行指定标记的测试(如 -m smoke)。
- --collect-only:仅列出可被发现的测试(不执行)。
3. 测试发现规则
Pytest 自动发现测试代码,规则如下:
- 文件匹配:文件名以 test_ 开头或结尾(如 test_*.py 或 *_test.py)。
- 测试对象:函数名以 test_ 开头的函数。类名以 Test 开头的类中的方法(方法名以 test_ 开头)。
# test_example.py def test_add(): # 会被识别为测试 assert 1 + 1 == 2 class TestMath: # 测试类 def test_multiply(self): # 会被识别为测试 assert 2 * 3 == 6
4. 断言机制
- 使用原生 assert 语句,无需额外断言方法。
- 失败时自动输出详细上下文(如变量值)。
def test_string(): s = "hello" assert s.upper() == "HELLO" # 失败时会显示 s.upper() 的实际值
5. 测试用例参数化
使用 @pytest.mark.parametrize
为单个测试函数提供多组输入数据,生成多个测试用例。
import pytest @pytest.mark.parametrize("a, b, expected", [ (1, 2, 3), (5, -3, 2), (0, 0, 0), ]) def test_addition(a, b, expected): assert a + b == expected
此测试会生成 3 个独立的测试用例。
6. 标记(Markers)
用于分类测试或附加元数据,常见用途:
- 跳过测试:@pytest.mark.skip(reason="...")
- 预期失败:@pytest.mark.xfail
- 自定义标记:@pytest.mark.smoke(需在 pytest.ini 中注册)
@pytest.mark.skip(reason="功能暂未实现") def test_unimplemented(): ... @pytest.mark.smoke def test_login(): ...
7. 配置文件(pytest.ini)
用于全局配置 pytest 行为,例如:
[pytest] addopts = -v -m "not slow" # 默认命令行选项 markers = slow: marks tests as slow smoke: quick validation tests testpaths = tests/ # 指定测试目录
8. 临时文件与目录
使用内置 Fixture 管理临时资源:
- tmp_path:生成临时目录(返回 pathlib.Path 对象)。
- tmpdir:生成临时目录(返回 py.path.local 对象,旧版)。
def test_temp_file(tmp_path): file = tmp_path / "test.txt" file.write_text("data") assert file.read_text() == "data"
9. 插件系统
- 内置插件:如 pytest-cov(覆盖率)、pytest-xdist(并行测试)。
- 自定义插件:通过编写钩子函数或 Fixture 扩展功能。
安装插件:
pip install pytest-<插件名>
10. 与 unittest 兼容
Pytest 可以直接运行基于 unittest
编写的测试,并支持混合使用两种风格的测试代码。
import unittest class TestLegacy(unittest.TestCase): def test_old_style(self): self.assertEqual(2 * 3, 6)
11. 常见问题与技巧
11.1 测试文件组织
推荐目录结构:
project/ ├── src/ # 源代码 └── tests/ # 测试代码 ├── conftest.py ├── test_math.py └── test_api.py
11.2 断言异常
使用 pytest.raises
捕获预期异常:
def test_divide_by_zero(): with pytest.raises(ZeroDivisionError): 1 / 0
11.3 调试测试
在失败时启动调试器:
pytest --pdb # 测试失败时进入 pdb 调试
总结
Pytest 通过简洁的语法、灵活的扩展机制和强大的断言系统,成为 Python 生态中最流行的测试框架。
进阶高级测试工程师 文章被收录于专栏
《高级软件测试工程师》专栏旨在为测试领域的从业者提供深入的知识和实践指导,帮助大家从基础的测试技能迈向高级测试专家的行列。 在本专栏中,主要涵盖的内容: 1. 如何设计和实施高效的测试策略; 2. 掌握自动化测试、性能测试和安全测试的核心技术; 3. 深入理解测试驱动开发(TDD)和行为驱动开发(BDD)的实践方法; 4. 测试团队的管理和协作能力。 ——For.Heart