先看一组数字。
TestDino 2026 年 2 月的基准测试:同样一条操作动作,Playwright 平均 290 毫秒,Selenium 536 毫秒。一套 250 条用例的 E2E 套件,Playwright 跑完 3 分 48 秒,Selenium 要 6 分 52 秒,差了 45%。
45% 很可观。但 45% 解释不了“3 小时到 4 分钟”。
真正让差距从“快一点”变成“快一个量级”的,不是单步速度,是 Selenium 那 3 小时里,有大量时间根本不在“执行操作”上。
一、先算账:Selenium 的 3 小时,时间去哪了
一套典型的手写 Selenium 回归,耗时结构大概是这样:
驱动初始化。Selenium 每个 session 启动 driver 要多花 3 到 5 秒。如果用例之间不复用 session,几百条用例光启动浏览器就要吃掉十几分钟。
HTTP 往返。Selenium 的 WebDriver 协议是 HTTP 请求-响应模式,每一个命令——click、type、navigate——都是一次完整的 HTTP 往返。单次 536 毫秒听起来不多,但一条用例几十个动作,几百条用例叠起来,就是实打实的小时级开销。
等待写错了。Selenium 没有内建的自动等待,开发者要么写 time.sleep(3),要么写显式等待。写 sleep 就是在赌页面速度——赌输了 flaky,赌赢了浪费。学术研究对 51 个 Apache 项目的分析发现,45% 的 flaky 修复最终都指向异步时序问题。这些“修 flaky”的时间,不会出现在回归耗时里,但会吃掉 QA 的每一个下午。
并行是靠 Grid 堆出来的。Selenium 原生不提供轻量并行,要并行就得上 Selenium Grid。Grid 的代价是:节点间网络延迟、浏览器实例争抢 CPU 和内存、每个节点要单独维护浏览器和 driver 版本。设置过高反而因为资源争抢导致整体性能下降。
3 小时里,真正“必须串行、必须等”的部分,远比想象中少。 剩下的大部分是协议开销、等待浪费、和基础设施摩擦。
二、Playwright 的 4 分钟,快在哪
架构差异:长连接 vs 轮询
Playwright 不用 WebDriver 的 HTTP 模式。它通过 Chrome DevTools Protocol(CDP)建立一条持久的 WebSocket 连接,所有命令走这条长连接。没有每次命令的 HTTP 握手,没有轮询。
单步 290ms vs 536ms 的差距,根源就在这里。但更关键的是,这条长连接还带来了 原生的网络拦截和事件监听能力——不需要额外搭 Mock 服务,就能在测试里直接拦截和断言网络请求。
自动等待:把“等页面”从代码里删掉
Playwright 在执行每个动作之前,会自动检查元素的可见性、稳定性和可操作性,等待逻辑内建在 API 里。Selenium 需要手动写显式等待,而 Playwright 的自动等待机制直接消灭了“写错等待”这一整类问题。
Bitrise 分析超过 1000 万次 CI 构建后发现,经历 flaky 测试的团队比例从 2022 年的 10% 涨到了 2025 年的 26%。自动等待不是锦上添花,它是把“修 flaky”的时间从日常工作中拿掉。
原生并行:不需要 Grid
Playwright 原生支持并行执行,配合 pytest-xdist 用 -n auto 按 CPU 核心数自动分配 worker。Playwright 的 browser context 是隔离的,并行 worker 之间不会互相污染状态。
实际数据:有团队把完整测试套件从 30 分钟以上压到了 10 分钟以内,靠的就是并行。testquality 的 2026 年基准显示,并行套件运行大约快 3 倍,Playwright 的吞吐量约 1200 条测试/小时,Selenium 约 600 条。
4 分钟不是一个脚本的功劳,是“单步更快 + 不再手写等待 + 并行跑起来 + 不需要维护 Grid”四件事叠加的结果。
三、一个可以照着改的最小配置
如果现在手上有一套跑 3 小时的 Selenium 套件,不需要推倒重来。按这个顺序改,每一步都有可量化的收益。
第一步:换连接方式,先拿单步收益。 把 driver 初始化改成复用 storageState 或 browser context,跳过每条用例重新登录和启动浏览器的开销。仅这一步,几百条用例的套件就能省出十几分钟。
第二步:删掉所有 sleep,换成 Playwright 的自动等待和 web-first 断言。 不要写 page.wait_for_timeout(3000),用 expect(locator).to_be_visible()。这一步不会让“执行时间”数字变好看,但会大幅降低 flaky 率——而修 flaky 的时间,才是 QA 日常最大的隐性成本。
第三步:开并行。pytest -n auto,或者用 Playwright 的 --shard=1/N 做分片。注意两点:确保用例之间没有顺序依赖(-n auto 会打乱执行顺序),以及并行 worker 数量不要超过 CPU 物理核心数,否则资源争抢会吃掉并行收益。
第四步:断言分层,别让“工具成功”冒充“业务通过”。 Playwright 快,但它不会自动帮你校验业务逻辑。UI 断言之外,用 Playwright 的网络拦截能力捕获关键请求,校验状态码和核心字段;涉及支付、订单、库存的场景,加一层业务状态查询。快不是目的,快且能拦住 Bug 才是。
四、避坑指南
坑一:只看单步速度,不做并行。 Playwright 单步快 45% 是事实,但 3 小时到 4 分钟靠的是并行和等待机制的叠加。只换工具不开并行,收益远低于预期。
坑二:并行 worker 开太多。-n auto 在 CI 容器里可能拿到不准确的 CPU 核数。显式设置 worker 数,别超过物理核心数。Selenium Grid 的教训已经证明,过度并行会因为资源争抢导致整体效能下降。
坑三:以为换了 Playwright 就不需要等待策略。 Playwright 的自动等待解决的是“元素可操作性”的等待,不解决“业务异步完成”的等待。如果被测系统有一个异步回调需要几秒才落库,你仍然需要显式等待业务状态,而不是指望自动等待。
坑四:迁移时把 Selenium 的写法原样翻译。 把 WebDriverWait 换成 page.wait_for_timeout 等于没换。Playwright 的收益来自用它的原生机制——自动等待、web-first 断言、context 隔离、网络拦截——而不是把旧代码逐行翻译成新 API。
坑五:为了 4 分钟牺牲断言质量。 最快的测试是通过率 100% 但什么都不检查的测试。三层断言(工具层、页面层、业务层)不能因为追求速度而砍掉任何一层。
最后
Selenium 的 3 小时,不是因为它“老”。是因为它的架构决定了每一次操作都要付一次 HTTP 往返的税,每一条用例都要付一次驱动启动的税,每一次并行都要付一次 Grid 维护的税。
Playwright 的 4 分钟,也不是因为什么黑科技。它把协议开销压下去了,把等待逻辑内建了,把并行变成了原生能力,然后把省下来的时间还给了 QA。
但最根本的变化不在工具,在谁做机器的活。3 小时里大量的“启动、等加载、写 sleep、修 flaky、维护 Grid”,本来就是机器该做的事。把这些交还给机器之后,QA 的时间才能花在“这个改动该重点测哪里、这个失败是不是真 Bug、这个版本能不能发”上。
工具的快,是为了让人的判断不被操作拖住。
本文部分内容参考了霍格沃兹测试开发学社整理的相关技术资料,主要涉及软件测试、自动化测试、测试开发及 AI 测试等内容,侧重测试实践、工具应用与工程经验整理。