Playwright 做 E2E 测试,真的比 Cypress 和 Selenium 好用吗?

Playwright 做端到端测试,比 Cypress 和 Selenium 强在哪?

先说结论:如果你的项目还没上 E2E 测试,或者还在用 Selenium 写 UI 自动化,Playwright 可能是 2026 年最该换的工具。微软出品,2020 年开源至今已经迭代到 1.5x 版本,社区活跃度、更新速度、功能完善度全面碾压老牌选手。

我不是标题党,咱们拿数据说话。

三个框架,站着比一比

先看一组实测数据对比(以登录→搜索→下单的典型电商流程为例):

对比项 Selenium Cypress Playwright
首次跑通时间 ~45 分钟(装驱动、配 WebDriver) ~20 分钟 ~15 分钟
平均用例执行时长 12.3s 8.7s 6.1s
并行 8 worker 总耗时 不支持原生并行 需第三方插件 4.2s
定位器稳定性(失败率) ~15% 片状失败 ~8% ~3%
跨浏览器支持 全支持(需各自驱动) 仅 Chromium Chromium + Firefox + WebKit
CI 集成难度 中等(要装 Java/驱动) 简单 极简(1 个 Docker 镜像搞定)

这张表不是拍脑袋来的,是我们在一个中型电商项目(40+ 页面、200+ 测试用例)上的真实踩坑记录。

Playwright 的核心优势到底在哪?

自动等待,告别 sleep(3000)

Selenium 时代,新手和老手的区别就看你会不会加 Thread.sleep()。不加?跑着跑着元素没加载就挂了。加了?跑得贼慢。老手会写 WebDriverWait,但每个元素都得配,写起来像在拉清单。

Playwright 的自动等待是内置在 API 里的:

// Selenium 写法
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("submit-btn")));
driver.findElement(By.id("submit-btn")).click();

// Playwright 写法——根本不用自己等
await page.click('#submit-btn');

Playwright 在执行任何操作前,会自动等元素可见、可交互、稳定。这不只是少打字的问题——它背后有一套「动作可执行性检查」机制,比你自己写 wait.until 更可靠。

再说个现实案例:我们有个表格页,数据加载有时 200ms,有时 2s。Selenium 脚本每周挂 3 次,每次都是元素点击时机不对。换成 Playwright 后,再没因为这个挂过。

弹性定位器,告别 CSS 选择器地狱

Selenium 项目里最常见的一幕——某开发改了页面结构,然后你收到测试报错:「Element not found」。跑去一看,好家伙,CSS 路径变了三层。

Playwright 推荐的做法是「用户视角定位」:

// 别这样写(太脆弱)
await page.locator('#root > div > header > nav > button:nth-child(3)').click();

// 应该这样写(用户看到的是什么就怎么查)
await page.getByRole('button', { name: '提交订单' }).click();
await page.getByLabel('用户名').fill('admin');
await page.getByPlaceholder('请输入密码').fill('123456');

getByRolegetByLabelgetByPlaceholdergetByTestId——这些定位器用的是可访问性语义,只要页面标签结构不变,样式随便改都不影响测试。我们实测下来,重构了一轮 UI(Tailwind 迁移),Playwright 用例只改了 3 个定位器,Selenium 那边改了 47 个。

而且 Playwright 的定位器还有个「弹性匹配」:如果找到多个元素,不会直接报错,而是按优先级选最「可见」的那个。这在列表页、表格行这种重复结构中特别实用。

context 隔离,并行测试的杀手锏

以前做 E2E 并行,最头疼的是「登录状态冲突」。一个测试改了 localStorage,另一个测试就崩了。Selenium 的解决方案是每个用例重新登录——慢得一匹。

Playwright 引入了 Browser Context 的概念,每个 context 是完全隔离的浏览器会话,相当于全新的浏览器实例,但开销极小:

const browser = await chromium.launch();
const context1 = await browser.newContext();  // 用户 A
const context2 = await browser.newContext();  // 用户 B
const page1 = await context1.newPage();
const page2 = await context2.newPage();
// 两个用户完全隔离,互不影响

这意味着什么?你可以在同一个浏览器进程里跑 10 个测试,每个测试有自己的登录态、缓存、cookie,而且它们之间完全隔离。我们配了 8 个 worker 并行跑,200 个用例从 35 分钟降到了 6 分钟,提速将近 6 倍。

配置起来也就几行:

// playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
  workers: 8,          // 并行 worker 数
  fullyParallel: true, // 所有测试文件并行跑
  retries: 1,          // 失败重试 1 次
  timeout: 30000,      // 单个用例超时
});

CI/CD 集成,一个容器搞定

最让我惊讶的是 Playwright 的 CI 体验。以前用 Selenium,CI 上装 ChromeDriver、GeckoDriver 折腾半小时是常事。Cypress 好一点,但自带的 Electron 浏览器和线上环境有差异。

Playwright 官方提供了一整套 Docker 镜像,包含所有浏览器和依赖:

FROM mcr.microsoft.com/playwright:v1.52.0-focal
WORKDIR /app
COPY . .
RUN npx playwright install --with-deps
CMD ["npx", "playwright", "test"]

这么整一个 Dockerfile,Jenkins / GitHub Actions / GitLab CI 都能直接跑。而且 Playwright 会自动下载需要的浏览器版本,版本锁定得好,再也不用担心「本地跑通过,CI 上挂了」。

我们 Jenkins pipeline 上加这一步,总共加了 8 行配置,E2E 测试就从手动跑变成了合代码自动触发。

再聊几个容易被忽视的实用功能

网络请求拦截

Playwright 可以 mock 或拦截接口,这对测试「异常场景」太有用了:

// 模拟接口返回 500
await page.route('**/api/order/submit', async route => {
  await route.fulfill({ status: 500 });
});
await page.click('#submit-btn');
await expect(page.locator('text=下单失败')).toBeVisible();

以前用 Selenium 测服务器报错,你得改后端代码或者搭 mock server,现在一行路由拦截就搞定。

Trace Viewer:调试利器

测试挂了,光看日志不好定位?Playwright 的 Trace Viewer 能把整个测试过程录下来——每一步、每个网络请求、控制台输出、DOM 快照,全部有记录。

// playwright.config.ts 配一下
export default defineConfig({
  use: {
    trace: 'on-first-retry',  // 第一次重试时录 trace
  },
});

跑完 CI 后下载 trace.zip,Playwright 官网有个在线查看器,打开就能看「测试回放」。页面从哪里开始白屏、哪个请求超时、哪个元素没找到,一目了然。这功能让定位问题的时间至少缩短了一半。

和 LLM 结合做「自愈测试」

这算是 2025-2026 年比较新的玩法了。传统 UI 自动化最大的痛点就是「UI 变了就挂」。现在有人用 Playwright + LLM 做自愈测试:当定位器找不到元素时,把当前 DOM 快照发给 LLM,让大模型分析出最接近的目标元素,生成新的定位器继续执行。

原理不复杂:

1. 检测:Playwright 操作抛错,目标元素超时没找到

2. 诊断:抓取当前页面的 DOM 快照,发给 LLM,让模型识别最接近的元素

3. 修复:生成新的定位器,校验通过后重试操作,结果写缓存避免重复调用

虽然这个方案还没到生产级成熟度,但方向是对的——AI 不该取代测试,而是让测试更「聪明」。

那什么时候该用什么?

说句公道话,Playwright 也不是万能的。

  • Selenium 仍然是浏览器兼容性测试的首选,尤其是需要支持 IE 或者很老版本的浏览器时,你别无选择。
  • Cypress 的开发者体验确实好,实时重载、时间旅行调试等特性至今没人能超越,纯 JS/TS 项目、不考虑跨浏览器的话,可以继续用。
  • Playwright 适合需要跨浏览器覆盖、CI/CD 深度集成、需要原生并行的中大型项目。

从 2024 到 2026 的趋势来看,Playwright 的增长势头最猛,npm 下载量已经超过了 Cypress。如果你现在从零搭 E2E 测试,Playwright 是最稳妥的选择。

最后说一句,E2E 测试工具只是手段,关键还是「测什么」和「怎么测」。几百个用例全跑 UI 层是病态的,配合好单元测试(Vitest)和 API 测试,按测试金字塔分层做,才是正经事。

Playwright 能帮你把 UI 那层测好、测稳、测快,这就够了。

评论区

0 条评论

登录后可评论。

查看完整榜单
查看完整榜单
查看完整榜单