e2e报告生成源码导读:list、markdown与JUnit如何产出
【免费下载链接】e2eNext generation e2e testing framework for web and mobile apps.项目地址: https://gitcode.com/GitHub_Trending/e2e6/e2e
e2e 是一个面向 Web 与移动端的新一代e2e 测试框架,内置了list、markdown、JUnit三种报告产出格式:终端里实时滚动的 list 报告、可直接贴进 Pull Request 的 markdown 报告,以及供 CI 平台摘要使用的 JUnit XML。本文带你读完 packages/e2e/src/report/ 目录下的核心源码,弄懂每种报告"从哪来、怎么写、写在哪"。
报告体系总览:4 个内置 Reporter,1 份契约
所有内置报告器集中注册在一个常量里,配置解析器、CLI 和 runner 都以它为唯一事实来源,避免三处"漂移":
export const BUILTIN_REPORTERS = ['list', 'json', 'junit', 'markdown'] as const见 builtin.ts#L14。这个设计保证"配置里能写的 id"和"实际存在的报告器"永远一致——漏注册会在编译期直接报错。
它们都实现同一个Reporter契约(types.ts#L1396-L1403),只有两个钩子:
| 钩子 | 作用 | 谁实现 |
|---|---|---|
onEvent(event) | 运行中逐条消费运行事件,实时渲染 | 仅list |
onRunFinished(run, signal) | 报告落盘后一次性渲染,可返回汇总行 | json、junit、markdown |
两条重要约定:
- 报告器永远不能改变运行状态或退出码——它坏了只是一行 stderr 警告;
onRunFinished带 1 分钟预算,超时的signal会中止它发起的请求。
📌 一句话记忆:list 是"直播",json/junit/markdown 是"录像回放"——后三者都只读最终的report.json文档(wire 格式report-1,由 report-v1.schema.json 锁定),不触碰 runner 的实时状态。
list 报告:事件流驱动的终端实时渲染
list是唯一带状态的报告器,由 runner 每次运行单独构造(builtin.ts#L19-L23)。核心类ListReporter(list.ts#L224)是一个事件汇,handle方法按switch分发十几种事件:run-started、plan、test-started、step、test-finished……
它最终呈现四段内容:
- 文件块:每个"测试文件 × 目标"一行徽章行,文件内所有测试跑完后整体打印,含各测试行与嵌套的 agent 步骤;
- Failed Tests 区:红底横幅 + 每个失败案例的错误码、首行错误、代码帧(code frame)、失败截图/视频与 trace 页路径;
- Run Errors 区:运行级错误(如服务起不来)单独成区;
- 对齐汇总:Test Files / Tests / AI 用量 / Cache / Duration 等行。
在交互式终端(TTY)上,它还会渲染一个实时窗口:下方固定区域显示正在运行的测试树和计数器,日志往上流;在非 TTY 的 CI 日志里则退化为纯流式输出——每步完成即打印,保证日志里每个名字恰好出现一次。
markdown 报告:把 report.json 渲染成 PR 评论页
markdownReporter(markdown.ts#L568-L578)在onRunFinished里把整份 report-1 文档交给renderMarkdownReport(markdown.ts#L516)渲染成单页 markdown,写入report.json同级的summary.md。
页面布局按"读者先看什么"排序:
- 标题行:🔴/🟢 状态图标 + 通过/失败计数,下方一行"花费"(agent 步骤数、缓存回放数、token、成本);
- 运行级错误:每条引用块一行;
- 失败块:每个失败测试一段——出错在第几步、错误与 agent 的"原话"引用、预期/实际事实列表、证据(截图/视频)与 trace 页链接;
- 折叠区:flaky 测试与"全部测试"表格都收在
<details>里,绿色运行时几乎"无事可读"。
为适配 GitHub 评论的 65536 字符上限,源码设了硬性预算(markdown.ts#L81-L90):正文 ≤ 60000 字符、失败块最多 30 个、运行错误最多 20 条、测试行最多 400 行,超出则用贪心裁剪并注明"完整报告见report.json"。
💡 配合 @e2e-dev/github 包,这份 markdown 还能自动作为评论贴到 Pull Request 上。
JUnit 报告:为 CI 测试摘要而生的 XML
junitReporter(junit.ts#L216)输出junit.xml,结构与 CI 摘要工具完美对齐:
- 一个测试文件 = 一个
<testsuite>,一个"测试 × 目标"组合 = 一个<testcase>(renderJunitReport); - 运行级错误单独成
run套件:像APP_UNREACHABLE这种没跑成测试的失败,在 CI 里也直接可见; - 状态映射:flaky 记为通过并附
<system-out>说明"先失败了 N 次";skipped/interrupted都映射为<skipped>;断言类错误用<failure>,其余(如超时、模型不可用)用<error>; - XML 安全:所有文本先做实体转义,XML 1.0 禁止的控制字符替换为
U+FFFD,避免"一个坏字符让解析器拒绝整份文档"(junit.ts#L29-L44)。
报告写到哪里:.e2e 目录布局与原子落盘
三个文件型报告器共用一个工厂函数 fileReporter:它把渲染结果写到report.json所在目录的同级文件,并返回一行"标签 + 相对路径",打印在终端汇总下方。写入走原子写(先写临时文件再替换),父目录缺失时自动创建。
默认输出目录是项目根下的.e2e(types.ts#L1443-L1453),一次运行后长这样:
.e2e/ ├── report.json # 报告真身(report-1 文档) ├── junit.xml # junit 报告器产出 ├── summary.md # markdown 报告器产出 ├── ai-trace.json # 可选,--ai-trace ├── results/ # 每个测试一个目录,含 trace.md 与截图 └── artifacts/ # 每次运行开始即清空json报告器则不落盘,直接把 report-1 文档打到 stdout,方便脚本管道处理。
如何配置与选择报告格式
在e2e.config.ts的reporters字段里按 id 勾选即可(详见 docs/reference/reporters.mdx):
export default { targets: [/* ... */], reporters: ['list', 'markdown', 'junit'], };- 默认是
list;加入json会顶替list(终端只出 JSON),markdown/junit则与list并存; - 也可以塞入自定义
Reporter对象,它始终运行、不会被--reporter移除。
官方示例项目 examples/with-next/ 展示了从配置到跑通的完整流程,可作为你接入报告体系的参照。
源码地图:快速定位关键文件
| 关心什么 | 看哪里 |
|---|---|
| 报告器注册表与 id 约束 | builtin.ts |
| list 实时渲染与失败区 | list.ts |
| markdown 页面渲染与字符预算 | markdown.ts |
| JUnit XML 结构与转义 | junit.ts |
报告器契约Reporter/FinishedRun | types.ts#L1348-L1403 |
原子落盘工厂fileReporter | write.ts |
| report-1 数据契约 | report-v1.schema.json |
读代码的建议路径:先读Reporter契约 → 再看fileReporter这条最短的落盘链路 → 然后任选junit.ts(约 210 行,最能体现"从文档到产物"的全过程)→ 最后回到list.ts感受事件流渲染的完整度。
【免费下载链接】e2eNext generation e2e testing framework for web and mobile apps.项目地址: https://gitcode.com/GitHub_Trending/e2e6/e2e
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考