allure报告json数据需从allure-report/data/目录读取,用json.load()配合utf-8-sig编码解析test-cases/等文件,提取status、time、labels等字段;统计通过率应排除skipped,分离failed与broken,耗时分析需识别retried记录,并兼容不同allure版本的summary.json路径。

如何用Python读取Allure报告的JSON数据结构
Allure报告的核心数据都存在 allure-report/data/ 目录下的 JSON 文件里,不是 HTML 页面本身。直接解析 HTML 会失败,因为生成的报告是静态前端渲染的,真实指标藏在 test-cases/、categories.json、summary.json 这些文件中。
实操建议:
- 确保 Allure 已执行过
allure generate,且输出目录结构完整(常见错误:误读allure-results/—— 那是原始结果,不是可解析的报告数据) - 用 Python 的
pathlib定位到allure-report/data/test-cases/,遍历所有*.json文件 - 每个测试用例 JSON 中关键字段包括:
status("passed"/"failed"/"broken")、time(start和stop时间戳)、labels(含epic、feature、story等) - 注意编码:Allure 输出的 JSON 默认为 UTF-8,但某些 Windows 环境下可能带 BOM,建议用
open(... , encoding="utf-8-sig")
怎样准确统计通过率、失败根因和耗时分布
通过率不能只数 "passed" 个数——Allure 把跳过("skipped")和未知("unknown")也计入总数;而 "broken" 通常表示 fixture 失败或环境异常,应和 "failed" 分开归因。
实操建议:
- 聚合时按
status分组,排除"skipped"(它不反映用例逻辑问题),把"broken"单独计为「环境/框架问题」 - 从
categories.json提取自定义分类规则(比如匹配 error message 正则),用于自动归因失败类型(如"ConnectionRefusedError"→ 「服务未启动」) - 耗时分析不要直接用
stop - start:部分用例可能被重试(retries字段存在),需检查statistic下的retried布尔值,只取最后一次执行的时间 - 示例判断逻辑:
if case.get("statistic", {}).get("retried", False): continue # 跳过重试中间记录
为什么用 allure-python-api 比手动解析 JSON 更危险
allure-python-api 是运行时库,用于生成报告,**不是解析工具**。它的 TestResult 类型只在 pytest 执行过程中有效,无法加载已生成的 report 数据。
常见错误现象:
- 试图用
TestResult.from_json(...)加载test-cases/xxx.json→ 报AttributeError: 'dict' object has no attribute 'name' - 误以为
allure_commons模块提供反序列化能力 → 实际上它只负责序列化输出,无公开反向接口 - 依赖
allure-pytest的 hook(如pytest_runtest_makereport)去“监听”结果 → 这只能捕获执行时状态,无法复现报告生成后的最终判定(比如被 categories 规则重分类的失败)
结论:坚持用标准 json.load() + 手动字段校验,别绕路。
提取指标时最容易忽略的路径和兼容性细节
Allure 2.13+ 把 summary.json 移到了 allure-report/data/ 根下,而旧版本(≤2.12)放在 allure-report/data/summary/ 子目录。硬编码路径会导致脚本在不同 Allure 版本间失效。
实操建议:
- 先检查
allure-report/data/summary.json是否存在;不存在则 fallback 到allure-report/data/summary/summary.json -
test-cases/下的文件名是 UUID,不是用例名,别试图用文件名做业务映射;必须读name字段 - 某些 CI 环境(如 GitLab CI)生成的报告可能压缩为
allure-report.zip,需先解压再解析,不能直接用zipfile.ZipFile读内部 JSON —— 因为路径是相对的,要确保解压后保留data/目录层级 - 如果用例打了多个相同 label(如两个
feature),labels是数组,需遍历去重,否则统计 feature 覆盖率会重复计数
真正卡住人的往往不是逻辑,而是某个版本悄悄改了 JSON 字段嵌套层级,或者 CI 打包时漏掉了 categories.json。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











