大数跨境

Selenium vs Playwright:真实电商应用上的7项性能实测结果

Selenium vs Playwright:真实电商应用上的7项性能实测结果 51Testing软件测试网
2026-11-03
8
导读:对比Selenium与Playwright性能:单Worker基准、并行执行与多Worker调优,看清真实速度差异与适用场景。

绝大多数 Selenium 和 Playwright 的性能对比,都是在理想环境下跑的合成测试:在专门做的演示应用里测按钮点击、表单填写、页面跳转,全是干净的 HTML,没有任何服务端渲染的意外状况。

这种结果只能体现理想条件下的框架开销,说明不了真实应用里的实际表现。

Sanzu Oracle APEX 电商门户 —— 就是我之前写 Playwright PCOM 和 AI 智能体文章时用的被测应用 —— 环境可以说一点都不理想。

APEX 运行时会生成动态 ID,几乎每次交互都会触发 AJAX 区域刷新,用会话式鉴权,重复登录会被限流,还有些 UI 元素完全靠 CSS 伪元素渲染,DOM 里根本不存在。

用它做测试,才是真刀真枪地检验两个框架在真实场景下,处理现代服务端驱动 Web 应用的能力。

我用 Selenium WebDriver(Ruby/RSpec)和 Playwright(TypeScript)各跑了一遍完全相同的 7 个测试,其中 Playwright 分别开了 1、2、3、4 个 worker。

这篇文章会讲清楚我测了什么、每个测试实际覆盖什么场景、两套框架的配置细节,以及数据反映的结论 —— 包括那些不符合常规认知的反常结果。

七个测试项及各自的测量维度

选哪些测试做性能对比,本身就是个设计决策。全选快的测试,测的其实是测试启动开销;全选慢的测试,测的就是应用本身,不是框架。我的目标是覆盖 APEX 电商应用里,有代表性的各类性能场景。

HP-01 — 商品网格渲染所有目录商品
性能维度:重度页面渲染 + 批量元素校验

Sanzu 首页会加载 11 个商品卡片,每个都包含名称、原价 / 促销价、星级评分、折扣商品倒计时、“加入购物车” 按钮。HP-01 验证这 11 个卡片全部存在、结构正确。

这个测试的核心差异,在于两个框架在整页加载后,定位和校验大量元素的效率。

Selenium 每次元素查询都要走一次 HTTP 往返,规模上来之后开销会持续叠加;Playwright 用持久 WebSocket 连接加 CDP 集成,处理批量元素的效率要高得多。本来预期这是差距最大的测试项之一。

AUTH-01 — 登录成功后跳转首页
性能维度:表单填写、提交、重定向链路

跳转登录页,填写账号密码,提交,断言浏览器最终落在/home路径。APEX 在服务端处理登录,返回重定向,URL 里嵌入新的会话 ID—— 所以测试要等 POST 请求和后续的 GET 跳转都完成。

这个测试代表所有鉴权类流程:表单交互加导航等待。APEX 的限流机制是个很真实的约束:如果账号错误,下一次登录会被冷却拦截,这也是种子用例里用Promise.race()同时匹配成功、限流、账号错误三种 URL 模式的原因。

AUTH-02 — 密码错误显示错误提示
性能维度:表单填写 + 错误状态 DOM 断言

同样的表单,故意输错密码。测试断言页面出现错误信息,且不发生页面跳转。APEX 是内联渲染错误 —— 不跳转、不刷新,靠局部页面更新实现。

有意思的地方在于“提交”到“断言”之间,两个框架的处理逻辑差异。

Selenium 通常要显式等待错误元素出现,Playwright 自带自动等待机制,断言本身就带重试逻辑,会一直重试直到条件满足或者超时。本来预期这个架构差异会带来非常明显的速度提升。

CART-01 — 加入商品更新购物车侧边栏(已登录)
性能维度:AJAX 交互 + 动态 DOM 更新

这个测试需要登录态。点击第一个商品的 “加入购物车”,等待购物车侧边栏组件更新总价。

购物车更新是典型的 APEX AJAX 区域刷新:点击按钮触发apex.server.process(),向服务端发请求,局部重渲染购物车组件,不整页刷新。

这个测试测的,是 APEX 交互模式里最容易让自动化出问题的场景:操作触发了可见变化,但没有导航事件。

依赖 URL 变化或页面加载判断 “有事情发生” 的框架,在这里会很吃力。Playwright 的waitForResponse或者元素状态等待,能很顺畅地处理这类场景。

CHK-01 — 进入结算页(已登录)
性能维度:已登录多步导航

从首页开始,保持登录态且购物车已有商品,测试先跳购物车页,再点击 “去结算”,断言结算页加载完成。整个流程串联两次 APEX 页面导航,都要求有效会话。

这个测试的 DOM 交互不多,主要是导航和重定向处理。预期两个框架速度差不多,因为元素交互极少,应用响应时间占主导,框架开销的影响很小。

PD-01 — 商品详情页展示完整信息
性能维度:简单内容页校验

跳转商品详情页,验证商品名称、描述、价格、加入购物车按钮都存在且可见。这是整套测试里最轻的一项 —— 一次简单导航,加上在单功能 APEX 页面上的几个元素断言。

加入简单测试是为了对比公平。如果一个框架只在复杂交互上快,简单场景和对手差不多,和全程都更快,结论是完全不一样的。

SF-04 — 智能筛选开关展开与收起
性能维度:JS 组件交互 + 状态验证

智能筛选是首页的可收起侧边栏,一个带 CSS 动画的组件,点击头部就展开或收起,显示 / 隐藏分类和价格筛选控件。测试先点击展开,断言筛选可见;再点击收起,断言隐藏。

这个测试测的是框架处理 JS 驱动 UI 状态变化的速度。它也是 worker 数量增加后,表现最反常的一项 —— 后面会详细说。

两套测试环境配置
Selenium WebDriver(Ruby/RSpec)

Selenium 套件基于 RSpec 运行,使用selenium-webdriver gem,通过 ChromeDriver 驱动有界面的 Chrome 实例。

测试单进程串行执行 ——RSpec 默认不支持并行,也没有配置 Selenium Grid 或者外部并行执行器。

每个测试用独立的浏览器会话,用例内部完成打开和关闭。自定义的ResultsLogger会在每个用例结束后,把单测耗时和时间戳写入 CSV 文件。


# spec/support/results_logger.rb (简化版)
config.after(:each) do |example|
elapsed = Time.now - @test_start_time
CSV.open(csv_path, 'a') do |csv|
csv << [example.full_description, elapsed.round(2), 'selenium-ruby', Time.now.iso8601]
end
end

套件执行命令:


bundle exec rspec spec/tests/ --format documentation

总运行时长由 RSpec 在执行结束后输出。

Playwright(TypeScript)

Playwright 套件使用专门的对比配置playwright.comparison.config.ts,包含两个项目:

• comparison-setup:执行seed.spec.ts,验证应用可访问,将登录后的storageState保存到.auth/目录。这一步在对比测试前运行,是 Selenium 配置里没有的额外开销。
• comparison:运行 7 个测试文件,全部开启 Playwright 的fullyParallel: true模式。1 个 worker 时为串行执行;2 个及以上 worker 时测试并发运行。

单测耗时取自 JSON 报告的duration字段(单位毫秒),仅统计测试本体执行时间,不含测试间开销。总墙钟时间来自同一份报告的stats.duration。


// playwright.comparison.config.ts (节选)
export default defineConfig({
fullyParallel: true,
reporter: [['list'], ['json', { outputFile: 'playwright-report/comparison-results.json' }]],
projects: [
{ name: 'comparison-setup', testMatch: ['/seed\\.spec\\.ts/'] },
{ name: 'comparison', testMatch: ['**/hp-01*.ts', '**/auth-0*.ts', /* ... */] },
],
});

Playwright 测试采用了前一篇文章提到的 PCOM 架构,所有元素交互都走带类型的页面对象方法,不直接调用原始的page.locator()。Selenium 测试也使用了类似的页面对象模式。

Selenium vs Playwright:单worker对比

最公平的正面较量,是串行执行的 Selenium,和同样 1 个 worker、同样测试顺序的 Playwright 对比。这样可以排除并行效应,只看纯框架开销的差异。

表格 <左右滑动>
测试项
Selenium Ruby(秒)
Playwright 1worker(秒)
提速倍数
AUTH-01 — 登录成功
7.32
6.45
1.13×
AUTH-02 — 密码错误提示
9.76
3.63
2.69×
CART-01 — 加购(已登录)
6.61
6.16
1.07×
CHK-01 — 进入结算(已登录)
7.78
7.93
0.98×
HP-01 — 商品网格(11 项)
16.69
3.84
4.35×
PD-01 — 商品详情页
4.44
2.82
1.57×
SF-04 — 智能筛选开关
5.22
4.19
1.25×
套件总墙钟时间
57.83
49.84
1.16×

整套测试整体提速 1.16 倍,提升真实但幅度有限 —— 处于 “串行 Playwright 比 Selenium 快 1.5–2 倍” 预期范围的偏低区间。

原因主要有两点:测试里包含大量导航和服务端操作,这部分应用响应时间的权重远高于框架开销;另外 Playwright 有 Selenium 没有的初始化开销 —— 对比测试前要先跑种子项目。

分开看每个测试项,结果要更有意思。

理论预期和实际结果

简单场景的结果基本符合预期。AUTH-02 提速 2.69 倍,正好对应 Playwright 自动等待架构的优势:Selenium 要显式写wait.until(element_to_be_visible)等错误元素出现,这部分额外开销,Playwright 的断言重试机制直接就消掉了。

PD-01 提速 1.57 倍、SF-04 提速 1.25 倍,体现了 Playwright 持久 WebSocket 连接的低延迟优势 —— 对比 Selenium 每条命令都走一次 HTTP 的 WebDriver 协议,优势稳定存在。

AUTH-01 提速 1.13 倍、CART-01 提速 1.07 倍,提升就很小了。这两个测试的耗时主要在服务端往返,不是框架操作,框架能优化的空间自然就被压缩了。

两个反常结果
›HP-01 提速 4.35 倍,远超预期

商品网格测试 Selenium 要 16.69 秒,Playwright 只要 3.84 秒 —— 这个差距单靠框架协议差异解释不完。三个因素叠加在一起放大了差距:

• HP-01 要校验 11 个商品卡片,每个卡片要查多个元素;Selenium 每个命令都有 HTTP 开销,11 个卡片乘以每    个的多个断言,延迟累积非常明显,而 Playwright 的 WebSocket 和 CDP 集成几乎消掉了这部分成本。
• Playwright 的元素可见性智能等待,每个元素就绪就立刻继续,不用像 Selenium 那样,为了适配 APEX 不稳定的渲染时间,写保守的固定等待或者重试循环。
• Ruby 和 TypeScript 的语言差异在这里体现最明显:TypeScript 的 async/await 模式和 Node.js 非阻塞 IO,处理批量元素查询比 Ruby 同步模型效率高得多。

三个因素叠加,结果看起来差距悬殊,但每个影响项都是真实存在的。这也说明“框架开销” 不是一个固定数字 —— 它是乘数效应,测试里元素交互越多,叠加越明显。

›CHK-01 提速 0.98 倍,Playwright 反而略慢

结算导航测试是唯一一个 Playwright 比 Selenium 稍慢的项(7.93 秒 vs 7.78 秒,差 150 毫秒)。单次运行看这个差值在误差范围内,但依然值得注意。

CHK-01 串联两次已登录的 APEX 导航:首页→购物车→结算。每次导航都要 APEX 验证会话、生成页面、触发 JS 页面加载生命周期,测试才能继续。

当测试几乎全由服务端响应时间主导时,Playwright 的框架开销优势就消失了 —— 而且 Playwright 的等待策略是等页面达到完全可交互状态,在服务端很快、元素交互极少的场景下,等待时间可能比 Selenium 基于 URL 的断言稍长一点。

这就是基准测试资料里常说的 “收益极小” 场景:测试耗时主要看应用响应速度,不是自动化开销,框架能发挥的空间本来就很小。

未完待续

图片

【声明】内容源于网络
0
0
51Testing软件测试网
博为峰51Testing软件测试网提供各种线上招聘、线上课程等网络服务,出版软件测试系列丛书及电子杂志,组织线上技术交流活动;同时还举办多种线下公益活动,如软件测试沙龙、软件测试专场招聘会等。
内容 3989
粉丝 0
51Testing软件测试网 博为峰51Testing软件测试网提供各种线上招聘、线上课程等网络服务,出版软件测试系列丛书及电子杂志,组织线上技术交流活动;同时还举办多种线下公益活动,如软件测试沙龙、软件测试专场招聘会等。
总阅读7.2k
粉丝0
内容4.0k