🤖 E2E 测试:Cypress 与 Playwright
一句话定性
E2E(端到端)测试一直是前端测试里信心最高、口碑最差的一层:它测的是”用户在真浏览器里走完整条路径”,理论上最值钱;但十年来它的代名词是**“又慢又脆(slow & flaky)“,以至于很多团队宁可不写。Cypress 和 Playwright 的全部努力,就是把这个”理论上最值钱、实际上没人敢用”的层真正救活**——靠的不是新理论,而是重新设计运行方式与等待机制。
一、它是什么 & 出现的时代
E2E = 驱动一个真实浏览器,像真用户一样从头到尾走完业务流程(登录→下单→支付),断言整条链路的结果。它跨越前端、网络、后端,是信心最高的一层。
三个时代:
- Selenium / WebDriver 时代(古老):W3C WebDriver 协议驱动浏览器,跨语言跨浏览器,是工业级标准——但慢、脆、难写。
- Cypress 时代(2017):开发者友好、运行在浏览器内、时间旅行调试,掀起 E2E 的 DX 革命。
- Playwright 时代(2020,微软):多浏览器、自动等待、并行,后来居上成为当代首选。
二、为什么会出现(解决上一代什么痛点)
Selenium 时代:E2E = 又慢又脆的代名词
- flaky(间歇性失败)是头号杀手:Selenium 通过 WebDriver 进程外远程控制浏览器,测试代码和浏览器之间隔着网络往返。脚本”点完按钮立刻断言”,但页面还没加载完 → 偶发失败。于是大家到处加
sleep(2000)硬等待——慢且仍然不稳。一个会随机变红的测试套件,等于没有测试(没人信它)。- 慢:进程外通信 + 串行执行 + 启动开销,跑一轮 E2E 动辄几十分钟。
- 调试地狱:测试在 CI 里挂了,只有一行报错和或许一张截图,无法回看”当时页面到底什么样”。
- 难写:WebDriver API 啰嗦,环境(driver 版本对齐浏览器版本)配置繁琐。
本质矛盾:E2E 信心最高,但 flaky + 慢 + 难调试让它的”可用性”趋近于零——价值再高,没人敢依赖也是零。
三、核心机制 & 为什么流行
3.1 Cypress(2017):把 E2E 拉回开发者体验
Cypress 的三板斧
① 运行在浏览器内部(in-browser) Cypress 不像 Selenium 那样进程外遥控,而是和被测应用跑在同一个浏览器、同一个事件循环里。它”贴着”应用执行,延迟低、对页面状态掌握更直接。
② 自动重试式等待(automatic retry)——治 flaky 的关键 Cypress 的命令(如
cy.get('button').click())会自动等待元素出现/可交互,在超时前不断重试。sleep硬等待从此基本退役——flaky 的主因被从机制层消除。③ 时间旅行调试(time-travel) 测试运行器把每一步的页面快照留存,跑完能在界面上鼠标悬停回看”这一步点击前后页面长什么样”。“CI 里挂了不知道发生什么”的黑箱被打开了,这是它最被称道的 DX 创新。
Selenium(进程外遥控):
测试进程 ──网络往返──► WebDriver ──► 浏览器
点完立刻断言 → 页面没好 → flaky → 加 sleep(慢)
Cypress(浏览器内 + 自动等待):
测试 ≈ 与应用同进程,命令自动重试等元素就绪 ──► flaky 大降
+ 每步留快照 ──► 时间旅行回看
3.2 Playwright(2020,微软):后来居上
Playwright 凭什么反超
由微软团队(部分是原 Puppeteer 班底)打造,系统性补齐了 Cypress 的短板:
- 真正多浏览器:Chromium / Firefox / WebKit(Safari 内核) 全覆盖,且驱动机制统一。Cypress 早期只支持 Chromium 系,Safari 覆盖是真实痛点。
- auto-wait 内建且更强:每个操作前自动等待元素可见、可点击、稳定(actionability checks),flaky 进一步压低。
- 并行 + 多 worker,快:原生支持把测试分片并行跑,CI 时间大幅缩短;架构上不受 Cypress 的某些运行模型限制。
- 没有 Cypress 的同源/多标签限制:Cypress 早期受限于”运行在浏览器内”的架构,跨域、多 tab、多窗口、iframe 处理别扭;Playwright 用进程外但现代化的 CDP/协议控制,这些场景更自如。
- 强力工具链:
codegen(录制生成脚本)、trace viewer(比时间旅行更强的事后追溯)、自动等待 + 网络拦截一体。
四、带来的新问题 / 副作用
E2E 救活了,但它的"原罪"不会消失
- 仍是最慢、最贵的一层:再快也是真浏览器 + 整条链路,远慢于 unit/组件测试。这正是 测试奖杯主张”E2E 只覆盖最关键主流程、别全靠它”的原因。
- flaky 被压低,但没根除:网络抖动、第三方依赖、时序问题仍可能偶发失败,只是从”家常便饭”降到”偶尔”。
- 维护成本随 UI 变动累积:页面一改,选择器/流程要跟着维护(用
getByRole等语义选择器可缓解,理念与 Testing-Library与组件测试 相通)。- 环境/CI 复杂度:跑真浏览器需要安装浏览器、处理无头模式、CI 资源,比纯 jsdom 单元测试重得多。
- Cypress 的架构债:早期单浏览器 + 同源/多 tab 限制是它被 Playwright 追上的直接原因(后续有所改善,但起跑落后)。
五、为什么会衰落 / 现状
现状(2026):Playwright 已成新项目首选,Cypress 仍有存量
- Selenium:基本退居”必须用某些特定语言/遗留生态”的角落,新前端项目几乎不选。
- Cypress:依然流行、DX 口碑好、存量项目多,但其早期架构限制(浏览器内运行带来的同源/多 tab/单浏览器问题)让它在”多浏览器 + 并行 + 复杂场景”上不敌 Playwright。
- Playwright:凭多浏览器、自动等待、并行、trace viewer,成为新项目的默认 E2E 选择,且作为微软出品迭代迅猛。
- 更大的现状:E2E 不再扩张地盘,而是收缩到”最关键的几条主流程”——把信心需求的大头让给了更便宜的集成测试(Testing-Library与组件测试),这正是”奖杯”形状的现实落地。
六、对后续技术的影响(因果链)
E2E 信心最高,但 Selenium 让它=又慢又脆(flaky)
│ 进程外遥控 + 硬等待 sleep + 调试黑箱 ──► 没人敢依赖
│
▼
Cypress(2017):浏览器内运行 + 自动重试等待 + 时间旅行调试
│ ① 治 flaky(自动等待替代 sleep)
│ ② 打开调试黑箱(每步快照)──► E2E 的 DX 革命
│ 局限:早期单浏览器 + 同源/多 tab 限制(架构债)
│
▼ 微软补齐短板
Playwright(2020):多浏览器(含 WebKit)+ 更强 auto-wait + 并行 + trace
│ ──► flaky 更低、更快、场景更全 ──► 后来居上成首选
│
└──► E2E 整体"可用"了,但仍最慢最贵
│
▼
与 [[Testing-Library与组件测试|集成测试]] 分工 ──► 落地 [[前端测试演进史|Testing Trophy]]:
E2E 只守最关键主流程,信心大头交给集成层
历史地位
Cypress 与 Playwright 的贡献,是把前端测试金字塔(/奖杯)最顶端那一块从”理论上该有、实际没法用”变成了真能跑、能信的工程实践。它们没有提出新的测试哲学,而是用”自动等待 + 现代浏览器控制 + 可追溯调试”把 flaky 这个几十年的顽疾按了下去——证明了一件事:有时候让一个层”可用”比让它”先进”更有价值。
🔗 相关:前端测试演进史 | Jest与单元测试 | Vitest | Testing-Library与组件测试 🔗 框架:React | Vue 🔗 运行时:Node.js 🔗 时代:2013-2018 SPA时代 | 2018-2023 工程化时代 | 2023-未来 AI时代