Pytest 插件方法:pytest_runtest_makereport

pytest_runtest_makereport 是 pytest 的一个钩子函数,用于在测试运行过程中生成测试报告。它允许用户在测试执行的不同阶段(setup、call、teardown)拦截并修改测试报告的内容,常用于定制化报告、收集额外信息或处理测试结果。

钩子函数的调用时机

该钩子函数会在以下阶段被调用:

  • setup:测试用例的初始化阶段。
  • call:测试用例的实际执行阶段。
  • teardown:测试用例的清理阶段。

每次调用会传入一个 item(测试项)和 call(调用信息)参数,返回一个 TestReport 对象,包含测试结果的状态(如 passedfailedskipped)。

python 复制代码
import pytest

@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
    outcome = yield
    report = outcome.get_result()

    if report.when == "call":
        print(f"Test {item.name} finished with status: {report.outcome}")
 
  • item: 当前测试项(测试函数或方法)的对象。
  • call : 包含测试阶段信息的对象(setupcallteardown)。

主要用途

1.动态修改测试报告:根据测试结果添加额外信息(如日志、截图)。

python 复制代码
def pytest_runtest_makereport(item, call):
    if call.when == "call" and call.excinfo is not None:
        item.add_marker(pytest.mark.skip(reason="条件不满足"))
 

2.失败重试逻辑:在报告生成阶段触发重试机制。

3.自定义报告字段:向报告中插入自定义属性或元数据。

python 复制代码
def pytest_runtest_makereport(item, call):
    report = item._report
    if call.when == "call":
        report.user_properties.append(("自定义字段", "值"))
 

4.自定义日志记录:在测试报告中添加额外信息(如测试环境变量)。

python 复制代码
@pytest.fixture
def data(request):
    request.node.test_data = "临时数据"

def pytest_runtest_makereport(item, call):
    if hasattr(item, "test_data"):
        print(f"测试数据: {item.test_data}")
 

5.失败截图处理:对于 UI 自动化测试,可在测试失败时自动截图。

以下代码展示如何通过 pytest_runtest_makereport 捕获测试失败并附加额外信息:

python 复制代码
def pytest_runtest_makereport(item, call):
    # 仅在测试执行阶段(call)处理  
    if call.when == "call":  
        report = item._report  
        if report.failed:  
            # 添加失败时的额外信息  
            report.sections.append(("自定义错误", "这里是失败时的详细描述"))  
            # 动态添加属性  
            setattr(report, "user_data", {"key": "value"})  
 

关键属性与方法

  • call.when :标识当前测试阶段("setup""call""teardown")。
  • report.outcome :测试结果状态("passed""failed""skipped")。
  • report.sections :用于向报告中添加多段文本(格式为 (title, content) 的元组列表)。

结合其他钩子

常与 pytest_runtest_protocolpytest_collection_modifyitems 配合使用,实现更复杂的测试流程控制。例如:

python 复制代码
# 在 conftest.py 中全局生效  
def pytest_runtest_protocol(item, nextitem):  
    # 自定义测试协议逻辑  
    pass  
 

注意事项

  • 执行顺序:该钩子会在每个测试阶段的报告生成时调用。
  • 避免副作用:修改报告时需谨慎,避免影响其他插件或 pytest 的正常流程。
  • 报告对象 :通过 item._reportcall.excinfo 访问详细的错误信息。

通过灵活使用 pytest_runtest_makereport,可以实现高度定制化的测试报告和结果处理逻辑。如果需要更复杂的报告处理,可以结合 pytest-htmlallure-pytest 等插件使用。