Pytest入门系列之pytest的hooks功能

Pytest入门系列之pytest的hooks功能

📌 pytest hookspytest 提供的插件机制,允许开发者在测试运行的不同阶段插入自定义逻辑,比如:

✅在测试开始前执行初始化

✅在测试执行后收集结果

✅自定义测试发现和报告

✅修改测试用例执行流程

什么是 pytest hooks?

pytest hookspytest 提供的回调函数 组成,用户可以重写这些函数来修改 pytest 行为。

pytest hooks 的定义格式:

1
2
def pytest_钩子名称(参数):
# 自定义逻辑

📌 如何使用 pytest hooks

所有 pytest hooks 必须写在 conftest.py 中。

pytest自动检测 conftest.py 里的 hooks,无需导入。

📌 示例:拦截 pytest 运行

1
2
3
4
5
6
7
8
9
10
11
12
# conftest.py
import pytest

def pytest_runtest_setup(item):
print(f"\n🔧 运行前:设置测试环境 - {item.name}")

def pytest_runtest_teardown(item):
print(f"\n🗑️ 运行后:清理测试环境 - {item.name}")

def test_example():
print("✅ 运行 test_example")

📌 运行结果

1
2
3
🔧 运行前:设置测试环境 - test_example
✅ 运行 test_example
🗑️ 运行后:清理测试环境 - test_example

常见 pytest hooks 速查表

Hook 名称 作用
pytest_configure 测试启动时执行(全局设置)
pytest_unconfigure 测试结束时执行(清理资源)
pytest_sessionstart 测试会话开始时执行
pytest_sessionfinish 测试会话结束时执行
pytest_collection_modifyitems 修改收集到的测试用例(重命名、跳过等)
pytest_runtest_setup 测试函数运行前执行
pytest_runtest_teardown 测试函数运行后执行
pytest_runtest_call 实际运行测试函数
pytest_runtest_logreport 获取测试结果
pytest_addoption 自定义命令行参数
pytest_terminal_summary 测试结束后自定义报告

pytest_configure & pytest_unconfigure:全局初始化和清理

📌 pytest_configure()pytest_unconfigure() 适用于全局配置和测试结束后清理资源。

🔹 示例:测试开始时连接数据库,测试结束后断开

1
2
3
4
5
6
7
8
9
# conftest.py
import pytest

def pytest_configure(config):
print("\n🔗 连接数据库...")

def pytest_unconfigure(config):
print("\n❌ 断开数据库连接...")

📌 运行输出

1
2
3
4
🔗 连接数据库...
✅ 运行测试...
❌ 断开数据库连接...

📌 适用于

✅ 全局资源初始化

✅ 日志记录

✅ 设置全局变量

pytest_runtest_setup & pytest_runtest_teardown:测试函数前后置

📌 适用于测试级别的前后置逻辑,比如:

✅打开和关闭数据库连接

✅初始化测试数据

✅模拟用户登录

🔹 示例:测试开始前初始化,结束后清理

1
2
3
4
5
6
7
8
9
10
11
12
# conftest.py
import pytest

def pytest_runtest_setup(item):
print(f"\n🔧 设置测试环境: {item.name}")

def pytest_runtest_teardown(item):
print(f"\n🗑️ 清理测试环境: {item.name}")

def test_example():
print("✅ 运行 test_example")

📌 运行输出

1
2
3
4
🔧 设置测试环境: test_example
✅ 运行 test_example
🗑️ 清理测试环境: test_example

📌 适用于

✅测试前创建数据库表

✅测试后删除文件

pytest_collection_modifyitems:修改测试用例

📌 可以用于:

✅重命名测试(添加前缀、转换编码)

✅自动跳过特定测试

✅按关键字排序测试

🔹 示例:修改测试名称

1
2
3
4
5
6
7
8
# conftest.py
import pytest

def pytest_collection_modifyitems(items):
for item in items:
item.name = item.name.upper() # 把测试名称改为大写
item._nodeid = item.nodeid.upper()

📌 运行

1
2
pytest -v

1
test_example.py::TEST_EXAMPLE ✅

📌 适用于

✅自动翻译测试名称

✅修改测试运行顺序

pytest_addoption:添加命令行参数

📌 自定义 pytest 命令行参数,可用于:

✅选择测试环境

✅开启或关闭调试模式

✅传递测试数据

🔹 示例:添加 –env 选项

1
2
3
4
5
6
7
8
9
10
11
12
13
# conftest.py
import pytest

def pytest_addoption(parser):
parser.addoption("--env", action="store", default="test", help="选择环境: dev, test, prod")

@pytest.fixture
def env(pytestconfig):
return pytestconfig.getoption("--env")

def test_env(env):
print(f"✅ 当前环境: {env}")

📌 运行不同环境

1
2
pytest test_env.py --env=dev  ✅ 运行开发环境
pytest test_env.py --env=prod ✅ 运行生产环境

pytest_terminal_summary:自定义测试报告

📌 pytest_terminal_summary() 可用于自定义测试报告,比如:

✅统计通过/失败的测试

✅生成 HTML/CSV 报告

✅在测试完成后发送邮件通知

🔹 示例:统计失败的测试

1
2
3
4
5
6
7
8
9
# conftest.py
import pytest

def pytest_terminal_summary(terminalreporter):
total = terminalreporter.stats.get("passed", [])
failed = terminalreporter.stats.get("failed", [])
print(f"\n✅ 通过测试: {len(total)}")
print(f"❌ 失败测试: {len(failed)}")

📌 运行

1
pytest

📌 示例输出

1
2
3
✅ 通过测试: 3
❌ 失败测试: 1

📌 适用于

✅ CI/CD 报告

✅ 统计测试结果

✅ 自动化邮件通知

总结

上面只是提供了一些经常遇见的,后面有时间继续补充其他的案例。


Pytest入门系列之pytest的hooks功能
https://dreamshao.github.io/2025/03/24/pytest入门系列7/
作者
Yun Shao
发布于
2025年3月24日
许可协议