~/blog/e2e-gate-for-solo-site
工程2026-10-14 · 9 min

一个人怎么维护 100 条 e2e 门禁

Tier1 必过 Tier2 尽力、webdriver 守卫双向防污染、duration hook 不造长素材测多窗——门禁的红色必须有权威,否则会被无视。

ffmpegtool.com 没有测试团队,所有验证靠我一个人。早期每次发布的状态是"本地看着没问题",后来建成一套 100 多条用例的 e2e 门禁,改完代码不跑完它不敢部署。这篇讲这套门禁的设计,重点不是工具选型,是几个反直觉的决策。

分层:必过和尽力要分开

用例按稳定性分两档,这是整套门禁最重要的一刀:

  • Tier1 必过:headless 下稳定的路由——全路由 SEO/渲染断言、首页、上传链路、canvas 工具页(图片裁剪/压缩/水印,不依赖 wasm 引擎的完整流程)、实验室构建面、i18n-en、博客。任何一条 fail,退出码非零,发布中止;
  • Tier2 尽力:真实跑 WASM 引擎的处理用例(gifsicle 压缩 GIF、ffmpeg 转码视频)。引擎是 32MB WASM,headless 下加载不稳,跑挂不代表代码错——单列、不阻塞、只做人肉参考。

判定标准就一条:这条用例 fail 的时候,你能不能立刻说出是代码错了还是环境抖了。说不出来就放 Tier2。

parse(解析)用例只打生产目标——本地起的服务没有 /api 后端可测,硬测只会得到一堆无意义的 skip。

不污染统计:webdriver 守卫是双向的

测试跑生产环境(e2e:prod 直连 ffmpegtool.com)最大的风险是把测试数据埋进真实统计。解法两端配合:Puppeteer 起浏览器时 webdriver=true,前端埋点在 track() 入口检查这个标志(IS_PRERENDER),命中直接不入队。

这个守卫还有反向作用:本地开发时如果想验证埋点真的发出去了,普通 headless 是验证不了的——必须在 evaluateOnNewDocument 里覆写掉 webdriver 标志,才能看到真实的采集请求。守卫本身也是需要被测试的代码。

fixture 纪律:headless 没有 H.264

Chrome for Testing(headless Chromium)不带 H.264 解码器。用 mp4 做测试视频,videoWidth=0,一切依赖视频元数据的用例(裁剪框、预览)全部卡死。fixtures 一律用系统 ffmpeg 合成 VP8 WebM(320×240),脚本入库,谁都能重建。

这条纪律还反过来影响产品设计:我们曾因"预览不了 WMV"收到"预览坏了"的反馈——浏览器和 wasm 引擎的解码器白名单是两套(浏览器无 WMV,wasm 有),报错文案必须区分"浏览器解不了"和"处理失败"。

断言要绑在真实事故上

门禁的价值不在条数,在每条用例背后有一个真实事故。几个例子:

  • 标题显示宽 ≤60 硬卡(汉字按 2 计宽):超宽即 Tier1 失败。这条抓到过好几次"改 title 顺手写长"的回归;
  • desc ≥100 字符:Bing too-short 阈值的固化,前面那篇 SEO 笔记里写过;
  • dist/en 无中文残留:防英文站混入中文文案;
  • /parse/douyin 无 en alternate:防给没有英文版的页面声明 hreflang。

流程约定:每次事故修复后,把回归用例补进对应 Tier。门禁是越长越值钱的资产,只在事故后生长。

两个不造大 fixture 的取巧技巧

测多窗分段不需要长视频。evaluateOnNewDocument 里 hook HTMLMediaElement.duration 把 2 秒视频骗成 12 秒,再 hook Worker 的 postMessage 数 EXEC 消息次数:12 秒 ÷ 5 秒窗长 = 3 次 exec。拿到 3 就证明分段逻辑真的分了窗,2 秒真实视频跑得完,整个用例几秒钟。

测流转用真实流转按钮。有一个白屏缺陷(流转文件后预览区不渲染),播种测试怎么也复现不了——因为复现必须点页面底部真实的"流转到"按钮,从相关工具的 <a> 链接进去会整页刷新清空内存 store,产生假阴性;而且播种 File 的 mime 必须和真实流转 File 一致才走同一条判类路径。测试手段偏离真实路径一步,结论就不可信。

报告与部署核对

产物三件套:report.json(机器可读,跨运行 diff,看哪条用例从绿变红)、report-<时间戳>.html(深色,KPI/分层/失败控制台与截图)、screenshots/。本地跑一轮 Tier1 约 3~5 分钟。

部署后的最后一道核对不是 e2e,是指纹比对:构建产物里 index-*.js 的哈希和线上 curl 到的一致,才说明部署真的生效了。这个习惯抓到过 tar 管道漏传的情况——服务 200、页面正常,但 JS 还是上一版。

复盘

单人项目做测试门禁,最大的敌人是"写了没人维护"。这套东西能活下来的原因:用例只在真实事故后增加(每条都有名字和故事)、必过集稳定在 3~5 分钟跑完(再长就会被绕过)、环境相关的全部去 Tier2(红色必须等于代码错了)。门禁的红色如果没有权威,它就会被无视——这比没有门禁更糟。

RELATED TOOLS · 把文章里的东西用起来