还在用 Selenium 跑 3 小时的回归?有人用 Playwright 砍到了 4 分钟

举报
霍格沃兹测试开发学社 发表于 2026/10/21 18:45:08 2026/10/21
【摘要】 先看一组数字。TestDino 2026 年 2 月的基准测试:同样一条操作动作,Playwright 平均 290 毫秒,Selenium 536 毫秒。一套 250 条用例的 E2E 套件,Playwright 跑完 3 分 48 秒,Selenium 要 6 分 52 秒,差了 45%。45% 很可观。但 45% 解释不了“3 小时到 4 分钟”。真正让差距从“快一点”变成“快一个量级...
先看一组数字。

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 测试等内容,侧重测试实践、工具应用与工程经验整理。


【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。