pytest官方Tutorial所有示例详解(二)
11. 测试发现规则(Test Discovery)
pytest 默认按以下规则发现测试:
- 文件名匹配:
test_*.py
或*_test.py
。 - 函数/方法名匹配:
test_*
。 - 类名匹配:
Test*
(且类中不能有__init__
方法)。
自定义发现规则:
在 pytest.ini
中配置:
[pytest]
python_files = check_*.py # 文件名匹配 check_*.py
python_functions = check_* # 函数名匹配 check_*
12. 命令行参数进阶
常用命令行选项:
选项 | 作用 |
---|---|
-k EXPRESSION | 运行名称匹配表达式的测试(如 -k "add or sub" ) |
-x | 遇到第一个失败立即停止 |
--maxfail=num | 最多允许失败次数 |
-s | 禁止捕获输出(显示 print() 内容) |
--lf | 仅重新运行上次失败的测试 |
--ff | 先运行上次失败的测试,再运行其他 |
示例:
pytest -k "test_add" -s # 运行名称包含 test_add 的测试,并显示输出
13. Fixture 作用域与生命周期
Fixture 可以通过 scope
参数控制创建和销毁的频率:
function
(默认):每个测试函数运行一次。class
:每个测试类运行一次。module
:每个模块运行一次。session
:整个测试会话运行一次。
示例:
@pytest.fixture(scope="module")
def db_connection():conn = create_db_connection() # 模块级共享的数据库连接yield connconn.close() # 测试结束后关闭连接
14. Fixture 依赖与参数化
Fixture 依赖其他 Fixture:
@pytest.fixture
def user(db_connection): # 依赖 db_connection Fixturereturn create_user(db_connection)def test_user(user):assert user.name == "admin"
参数化 Fixture:
@pytest.fixture(params=[1, 2, 3])
def number(request): # request 是内置 Fixture,用于访问参数return request.paramdef test_number(number):assert number > 0
15. Mock 与猴子补丁(Monkeypatching)
使用 monkeypatch
修改环境变量或属性:
def test_env_var(monkeypatch):monkeypatch.setenv("API_KEY", "test_key") # 设置环境变量assert os.getenv("API_KEY") == "test_key"def test_mock_method(monkeypatch):def mock_return():return "mocked"monkeypatch.setattr("module.Class.method", mock_return) # 替换方法
更强大的 Mock:pytest-mock
插件
安装:
pip install pytest-mock
使用:
def test_with_mock(mocker):mocker.patch("module.function", return_value=42)assert module.function() == 42
16. 测试覆盖率(Coverage)
结合 pytest-cov
插件统计代码覆盖率:
pip install pytest-cov
pytest --cov=my_module tests/ # 统计 my_module 的覆盖率
pytest --cov-report=html # 生成 HTML 报告
输出示例:
- 终端显示覆盖率百分比。
- HTML 报告可视化哪些代码被测试覆盖。
17. 并行测试(pytest-xdist)
通过 pytest-xdist
插件加速测试:
pip install pytest-xdist
pytest -n 4 # 使用 4 个 CPU 核心并行运行测试
适用场景:大型项目测试耗时较长时。
18. 插件系统
pytest 的强大之处在于其插件生态,常用插件包括:
插件 | 功能 |
---|---|
pytest-django | Django 项目专用 |
pytest-flask | Flask 项目专用 |
pytest-asyncio | 测试异步代码 |
pytest-benchmark | 性能基准测试 |
安装插件:
pip install pytest-<plugin_name>
19. 配置文件的更多选项
pytest.ini
还支持:
- 自定义标记(
markers
)。 - 忽略特定文件/目录(
norecursedirs
)。 - 修改断言输出格式(
addopts = --assert=plain
)。
示例:
[pytest]
markers =slow: marks tests as slow (deselect with '-m "not slow"')
norecursedirs = .* venv # 忽略隐藏目录和虚拟环境
20. 最佳实践总结
- Fixture 复用:将数据库连接、临时文件等公共逻辑封装为 Fixture。
- 参数化测试:避免重复代码,覆盖多组输入。
- 分层测试:单元测试(快速反馈) + 集成测试(验证交互)。
- 持续集成:在 CI 中运行
pytest --cov
确保覆盖率。 - 插件生态:按需引入插件(如并行测试、Django 支持)。
官方 Tutorial 完整目录
pytest 官方 Tutorial 的完整结构如下(部分内容已涵盖):
- 创建你的第一个测试(基础断言)。
- 运行测试(命令行参数)。
- Fixture(资源管理)。
- 参数化测试(多组输入)。
- 标记和跳过测试(分类测试)。
- Mock 和猴子补丁(隔离依赖)。
- 插件系统(扩展功能)。
- 配置文件(自定义行为)。
下一步学习建议
- 实践:尝试用 pytest 测试一个小型项目(如计算器、API 服务)。
- 阅读文档:pytest 官方文档(尤其是 Fixtures 和 Configuration 部分)。
- 探索插件:根据项目需求选择插件(如
pytest-django
或pytest-asyncio
)。