ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Cypress测试报告生成实战:mochawesome输出HTML报告与合并

Cypress测试报告生成实战:mochawesome输出HTML报告与合并 Cypress 跑完测试只会看到命令行里一串绿色的通过标记如果只把这条输出给团队那可太亏了。测试跑完只是第一步真正关键的是把结果转成一眼能看出问题、能归档、能塞进CI流水线的报告。这篇是Cypress系列的第三十三篇专门聊生成测试报告的第一部分——先把最常用的HTML报告方案讲透后续再补上其他格式与CI深度集成。先说清楚这篇要解决什么问题你的自动化测试已经写了不少在本地跑能通过但项目成员怎么确认当前版本的回归结果历史用例失败趋势怎么追踪新同事进来如何快速查看最近一次全量测试的失败用例这些问题的答案都指向同一个东西一份漂亮且信息完整的测试报告。Cypress 本身默认基于 Mocha底层渲染出一份简单的“点线报告”但那种样式只适合开发机上看一跑而过。真正的团队级报告需要更丰满的数据每个用例的执行时间、失败栈、截图与视频链接、断言详情等。这篇文章适合三类人刚能把 Cypress 跑起来、但还没认真研究过报告格式的入门者已经在用mochawesome但没搞定数据合并的进阶选手还有需要在 Jenkins 这类工具里稳定产出报告的工程化实践者。下面直接进入正题我尽量用实操时的经验顺一遍而不是照着官方文档念。1. 报告设计思路先想清楚你要的是一份什么样的报告很多人一上来就装mochawesome装完发现生成的 JSON 和 HTML 分开又不知道合并最后干脆只保留 HTML。这种用法不能说错但如果你真想用好测试报告第一步其实是问自己这份报告最终给谁看要承载哪些信息1.1 报告的使用场景与核心需求拆解个人开发时你需要的可能只是“哪些用例挂了、挂在哪个断言”这时候 Cypress 自带的终端输出配合截图就能凑合。但团队协作时就需要一份包含汇总统计、失败用例趋势、历史对比的报告最好还能按套件或标签筛选。再往上走CI 流水线里要自动归档那么报告文件名就不能带时间戳或随机值否则每次构建都会覆盖旧记录问题追溯无从谈起。我在项目里见过最典型的翻车场景报告生成出来了很好看但有个同事跑完本地后顺手把mochawesome-report目录提交到代码仓库导致合并冲突不断。这就是典型的没有设计好报告存放与命名规则。我的建议是先把报告的输出目录统一固定为test-results并且加入.gitignore任何本地产出的报告都不入库只在 CI 服务端备份或者使用插件上传到公共平台。1.2 Cypress 报告机制的本质Mocha reporter 的扩展逻辑Cypress 的测试执行器沿用了 Mocha 的 reporter 机制也就是说你在cypress.config.js里配置的reporter字段直接被 Cypress 读取并传给内置的 Mocha 实例。这带来一个很大的好处生态里绝大多数为 Mocha 开发的 reporter 插件都能在 Cypress 中使用哪怕插件从没说过自己支持 Cypress。理解了这一点你就知道为什么配置报告不需要改动测试代码只需在配置文件中指定reporter和reporterOptions。Cypress 在运行时会把每个测试文件spec单独交给 Mocha 跑一遍对应的 reporter 也会在每个 spec 结束时生成输出。这个“按 spec 单独生成”的特性直接导致了多 spec 场景下报告文件会被多次覆盖或各自独立。这也是后面我会强调合并数据的关键原因。2. 基础配置reporters 与 reporterOptions 的准确含义大部分 Cypress 用户都知道在cypress.config.js里写reporter: mochawesome但未必理解reporterOptions中每个字段怎么设。这一节先把配置项讲明白后续再给完整示例。2.1 Cypress 配置文件中的 reporter 字段与内置选项打开cypress.config.js配置片段一般长这样const { defineConfig } require(cypress); module.exports defineConfig({ e2e: { specPattern: cypress/e2e/**/*.cy.js, reporter: mochawesome, reporterOptions: { reportDir: cypress/results, overwrite: false, html: true, json: true, charts: true, }, }, });reporter指定使用的 reporter 包名。如果不加任何配置默认走的是specreporter也就是终端里列出每个用例的√或×的结果。这个选择只会影响输出形式不影响测试执行行为。reporterOptions则直接传给 reporter 插件不同插件的配置项不一样但几个常用项在 mochawesome 里很关键reportDir控制输出目录overwrite决定是否覆盖已有文件html和json分别控制是否生成两种格式的文件charts控制是否在报告中渲染统计图表。有件事得单独拎出来说Cypress 的reporterOptions不一定能被所有插件完整读取。有些 reporter 插件只认顶层reporterOptions如果你在某个测试文件的before钩子里动态调整配置会不生效。所以尽量保证配置文件的静态设置不要用代码动态改。2.2 为什么默认的报告不适合团队协作三个致命缺陷先看 Cypress 内置specreporter 的几个问题。第一个缺陷没有统计汇总。跑完 20 个文件终端底部会给出总量、通过数、失败数但你想看每个文件的“通过率柱状图”抱歉没有。第二个缺陷历史比对困难。今天的报告和上周对比只能靠肉眼一行一行看如果测试数量从三百条涨到三百五十条很难直观看出新增了哪些。第三个缺陷截图和视频信息脱离用例。失败用例在 Cypress 的cypress/screenshots目录里能翻到 PNG但报告页面上看不到快捷入口尤其在 CI 机器上你不可能远程登录去看文件系统。mochawesome这类报告器正好补上了这几个缺口。它生成的 HTML 页面自带统计面板、用例列表、失败信息、截图嵌入通过相对路径预览还有按套件折叠的视图。更关键的是它会把每个用例的数据完整写到 JSON 里之后想二次处理或生成自定义报表JSON 就是数据源。3. 实操基础直接用 mochawesome 生成你的第一份 HTML 报告前面理论聊得差不多了下面进入动手环节。这一步不难但有几个坑我踩过会在过程中指出来。3.1 依赖安装与初始配置三步实现从零到报告第一步安装必须的 npm 包。这里要注意比较稳妥的组合是mochawesome和mochawesome-mergenpm install --save-dev mochawesome mochawesome-merge第二步在cypress.config.js中写入 reporter 配置const { defineConfig } require(cypress); module.exports defineConfig({ reporter: mochawesome, reporterOptions: { reportDir: cypress/results/mochawesome, overwrite: false, html: false, json: true, }, });这里我把html设为false只先生成 JSON。原因后面会说当你有多个 spec 文件时mochawesome 会为每个 spec 生成独立的报告而这些报告会互相覆盖。如果在每个独立报告里都生成 HTML最后你只会得到最后一个 spec 的 HTML意义不大。正确玩法是先让每个 spec 生成独立的 JSON再用合并工具把 JSON 合成一份完整数据最后基于合并后的数据生成总报告。第三步运行测试npx cypress run跑完后进入cypress/results/mochawesome目录应该能看到类似.json的文件里面包含每个用例的标题、状态、耗时、错误信息等。如果这一步报错多半是 reporter 包没装上或者目录不可写。3.2 用 mochawesome 直接生成 HTML 时的坑多 spec 覆盖问题有人会想既然mochawesome本身就能生成 HTML那我直接在配置里设html: true不就行了不行除非你的项目里只有单个 spec 文件。只要 Cypress 执行了多个 spec每一个 spec 跑完时 mochawesome 都会尝试写一个固定名字的mochawesome.html后写的会把先写的覆盖掉。最终你得到的是最后一个 spec 的报告前面 spec 的结果全丢。解决思路是设置overwrite: false让它为每个 spec 生成带不同后缀的文件。但overwrite: false生成的文件名仍基于同一个基础名会变成mochawesome_001.json、mochawesome_002.json这种。如果项目 spec 数量不固定编号乱掉的可能性很高。所以我的推荐配置还是html: false, json: true把生成最终 HTML 的职责交给合并脚本。4. 合并与生成mochawesome-merge 的正确打开方式先说明一下为什么需要合并。Cypress 执行多个 spec 时测试数据其实是分散在多个 JSON 文件里的如果直接打开某个 spec 的 JSON里面只有那个 spec 的用例信息。团队报告要的是“全量汇总”你需要把多个 JSON 合并成一个“总 JSON”再用 mochawesome 的 HTML 生成能力渲染总报告。4.1 合并命令的三种写法与适用场景合并命令的核心很简单npx mochawesome-merge cypress/results/mochawesome/*.json cypress/results/mochawesome/merged.json注意我加了引号因为通配符需要让 shell 展开某些 Windows 环境下没有引号会匹配不到文件。执行完这个命令你会得到一个merged.json里面是一个完整的 JSON 数组包含了所有 spec 的数据。如果你不想在命令行里拼字符串也可以写成 npm scripts{ scripts: { merge-reports: mochawesome-merge \cypress/results/mochawesome/*.json\ cypress/results/mochawesome/merged.json, generate-report: marge cypress/results/mochawesome/merged.json --reportDir cypress/results/mochawesome --reportTitle My Test Report } }这里的marge就是mochawesome-report-generator的命令行工具在安装 mochawesome 时会作为依赖一起被安装也可以显式安装mochawesome-report-generator。marge接受一个 JSON 文件生成一个完整的 HTML 报告。第三种写法是直接在 Node 脚本里调用const merge require(mochawesome-merge).merge; const generate require(mochawesome-report-generator).generate; (async () { const report await merge({ files: [./cypress/results/mochawesome/json/*.json], }); await generate({ report, reportDir: cypress/results/mochawesome/final, reportTitle: 最终测试报告 }); })();这种写法适合你需要在合并前后做额外处理的场景比如过滤某些 spec或者改报告标题。但对于大部分项目命令行方式足够。4.2 报告文件名管理与防覆盖策略刚才我提到文件名覆盖问题这里展开讲一下常用策略。当overwrite: false时mochawesome 会生成mochawesome_001.json、mochawesome_002.json……这样的文件。问题是如果你在同一个目录里第二次跑测试新生成的文件序号可能会接着原来的编号继续也可能前缀相同而直接覆盖这取决于 Cypress 执行时的内部逻辑。保险做法是每次跑测试前先清空报告输出目录rm -rf cypress/results/mochawesome或者在 npm script 里加一句清理命令scripts: { clean:reports: rm -rf cypress/results/mochawesome, test:report: npm run clean:reports cypress run npm run merge-reports npm run generate-report }这样每次都是一次干净的执行不会出现旧数据残留导致合并结果翻倍。5. 让报告真实可用几项关键配置与踩坑记录配置对了报告能出来。但离“真实可用”还差几步这节把最常见的几个坑和对应的解决思路整理成表格方便你对照排查。5.1 常见问题速查表从无报告到报告信息不全现象可能原因解决方式跑完后results目录为空reporter 配置没生效或reporterOptions里的输出目录写错确认cypress.config.js在cypress run时被加载删掉node_modules/.cache后重试多个 spec 只生成一份 HTMLoverwrite设为true或没设多 spec 互相覆盖设overwrite: false并使用mochawesome-merge合并JSON 文件生成但没有 HTMLhtml设为false或合并后没跑marge执行npx marge或调用generate生成最终报告报告里失败用例没有截图Cypress 截图文件路径与报告不在同一根目录将screenshotsFolder与reportDir设置在同一个父目录下配置overwrite之外还需要手动处理相对路径合并后报告数量翻倍旧 JSON 未被清理与新 JSON 一起合并每次跑测试前清理输出目录CI 上报告文件名为空或固定名被覆盖未使用时间戳或不传唯一标识在 CI 脚本中为报告目录加入构建号如--reportDirtest-results/$BUILD_NUMBER这张表是我在维护多个项目时总结出来的高频问题。其中最隐蔽的是截图路径问题Cypress 默认会把截图放在cypress/screenshots下而报告的 HTML 在cypress/results/mochawesome下两者没有相对关系导致 HTML 中嵌入的img src../../screenshots/...失效。解决办法是设置统一根目录比如把截图目录设为cypress/results/screenshots这样报告的 HTML 就能通过相对路径访问到截图。5.2 高级配置技巧标题、时间戳、环境变量与自定义图表报告生成出来了接下来要让它更符合项目需要。几个常用技巧在marge命令中设置--reportTitle给报告起一个包含日期或版本号的标题方便历史留存。使用--enableChart或配置charts: true让报告顶部显示柱状图看起来更专业。如果想在 HTML 中显示测试环境信息可以通过--showPassed、--showFailed、--showPending控制展示哪些状态的用例默认全显示测试量很大时可以只显示失败项。我最常用的 npm script 示例scripts: { start:report: npm run clean:reports cypress run npm run merge:json npm run gen:html, merge:json: mochawesome-merge \cypress/results/mochawesome/*.json\ cypress/results/mochawesome/merged.json, gen:html: marge cypress/results/mochawesome/merged.json --reportDir cypress/results/mochawesome/final --reportTitle \$(date %Y-%m-%d_%H-%M-%S) Report\ --charts true }这段脚本既完成了清理、执行、合并、生成四个环节还动态生成了带时间戳的标题用于区分不同轮次的测试。注意 macOS/Linux 的date命令格式Windows 下要换成 PowerShell 或使用第三方工具来生成时间字符串这块在 CI 上一般有现成的环境变量供使用。6. 从本地到CI报告产物交付前的最后几步本地能出报告只是万里长征第一步。如果报告不能稳定地在 CI 上生成并归档团队的效率还是上不来。最后聊聊 CI 集成时的几个关键点。6.1 在 CI 流水线中执行报告命令的顺序与缓存清理以 Jenkins 为例流水线的 shell 步骤可以这样组织npm ci npm run test:report关键是test:report里的清理步骤不能省。很多情况下 CI 的工作空间是复用的上一次构建留下的test-results会混入本次产物导致报告数据重复。最佳实践是把报告输出目录和node_modules一样放入缓存清理范围或者用 CI 自带的工作空间清理插件。还要注意一个细节Cypress 在 CI 上默认可能并行执行 spec并行模式下各进程的输出目录是一样的如果没有按进程号区分报告文件合并时就会互相覆盖。建议在并行执行时给每个进程设置一个独立的环境变量并将reportDir设置成包含该变量的路径。例如配置reporterOptions: { reportDir: test-results/${process.env.CYPRESS_PARALLEL_INDEX || default} }然后合并时用mochawesome-merge test-results/*/*.json来汇总。6.2 让报告成为团队资产归档与可视化页面CI 上生成的 HTML 报告默认没有地方展示。如果只是放在工作空间里构建结束后通过链接下载体验很差。可以考虑两个方向一是用 CI 自带的上报插件把报告目录作为构建产物归档这样在构建详情页能直接打开 HTML。二是对接开源或商业的报告平台把 JSON 数据上传生成可长期访问的在线报告。无论哪种方案都需要在流水线中加入“上传归档”的步骤而不能只生成文件就完事。归档时要注意HTML 报告引用的是 JSON 文件如果只把 HTML 上传而 JSON 文件不在同目录页面会加载不全。所以要整个目录一起归档。另外报告里的截图路径如果指向 Cypress 的临时截图目录归档时也要一并包含否则页面里图片区域会裂开。这个坑我是在一次演示给上司看的时候踩的当时报告标题、统计都正常唯独截图全裂原因就是归档时漏了截图目录。从本地跑通报告到在 CI 上稳定产出并归档整个过程贯穿着“数据完整性”和“文件命名可预测性”这两个原则。只要每次都先想清楚这两点即使换了不同的 reporter 插件也不会走太多弯路。下一部分我会继续写如何将 mochawesome 的 JSON 数据类型转换为 JUnit XML 格式以及如何在 GitLab CI 中与测试趋势图结合让报告真正变成项目里的“仪表盘”而不是一堆静态文件。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表