You need to enable JavaScript to run this app. 如何从pytest_runtest_makereport钩子识别xfailed或xpassed测试结果?
优惠活动
大模型
产品
解决方案
定价
更多

如何从pytest_runtest_makereport钩子识别xfailed或xpassed测试结果?

在pytest_runtest_makereport钩子中精准识别xfailed/xpassed的实现方案

此前观察到的“xfailed、xpassed被统一标记为skipped”现象,本质是仅依赖report.outcome单一字段做判断导致的分类偏差。pytest内置的xfail插件在生成测试报告时,会将非严格模式下的xfailed、xpassed类用例的outcome统一设置为skipped,但报告对象本身挂载了可精准识别分类的专属属性,所有分类需要的字段在pytest_runtest_makereport触发时就已完整写入,完全不需要等到pytest_terminal_summary阶段再匹配nodeid列表。

核心判定规则

直接从钩子返回的TestReport对象上提取属性做分类即可,逻辑与pytest内置终端统计的分类逻辑完全同源:

  • 识别xfailed:报告触发阶段为测试用例实际执行的call阶段,报告对象存在非空wasxfail属性(由xfail插件挂载,记录预期失败的标记原因),且用例执行未出现非预期通过结果。
  • 识别xpassed:报告触发阶段为call阶段,存在非空wasxfail属性,且报告对象的passed值为True——对应标记了预期失败、实际执行通过的用例场景。
  • 识别普通skipped:报告任意触发阶段不存在wasxfail属性,且outcome为skipped,对应@pytest.mark.skip、条件不满足触发常规跳过的场景。

可直接运行的钩子实现

def pytest_runtest_makereport(item, call):
    # 仅处理用例真正执行的call阶段,过滤setup/teardown阶段的报告干扰
    if call.when != "call":
        return
    report = call.report
    result_category = None
    # 优先判断xfail关联场景
    has_xfail_mark = bool(getattr(report, "wasxfail", ""))
    if has_xfail_mark:
        result_category = "xpassed" if report.passed else "xfailed"
    else:
        # 处理非xfail的常规测试结果
        if report.passed:
            result_category = "passed"
        elif report.failed:
            result_category = "failed"
        elif report.skipped:
            result_category = "skipped"
    # 此处可直接推送近实时测试指标,无需等待全量测试流程结束
    print(f"实时上报测试结果: 用例{item.nodeid} -> 分类{result_category}")

注意事项

  • 上述分类结果与pytest终端统计中terminalreporter.stats的分类结果完全一致,不存在偏差,不需要额外维护xfailed、xpassed的nodeid列表做二次匹配。
  • 必须过滤setup、teardown阶段的报告内容,否则会把环境初始化阶段触发的跳过,误判为用例执行完成的结果,影响指标准确性。

内容的提问来源于stack exchange,提问作者Loren

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 22:45:03