十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Selenium太痛?8款替代工具横评:Playwright、Cypress、Puppeteer如何选

Selenium太痛?8款替代工具横评:Playwright、Cypress、Puppeteer如何选 先交代清楚一个问题我并不是说 Selenium 已经过时了。做了这么多年自动化我手头相当一部分线上项目到现在还是用 Selenium 在跑稳定性和社区资料都有保障。但如果你和我一样经历过“Chrome 自动升级之后全部脚本崩掉”“find_element 加显式等待写到手软”“CI 上跑一套 200 条的用例要 40 分钟”这种处境你大概也会开始认真看替代方案。Selenium 的生态地位不用怀疑可它的体验停留在“能用”而现在的自动化需求已经是“省心”。这篇内容不是让你彻底告别 Selenium而是把 8 款实战中真正能顶替它、甚至更省事的工具按场景拆清楚。无论你是做 Web UI 自动化测试、爬虫脚本还是内部运营工具的页面操作都应该能找到比自己现在这套更顺手的方案。1. Selenium 的痛点不是工具不好而是时代变了Selenium 能撑到今天说明它的设计在 Web 早期是成立的。问题是今天的网页已经不是当年那个页面了前端框架、微服务架构、动态渲染、复杂交互全都变了自动化工具的思路却还停留在“驱动浏览器 找元素 操作元素”这条老路上。1.1 真正的障碍在哪我总结下来最折磨人的其实就四类问题。驱动管理和浏览器版本捆绑。这是 Selenium 用户绕不过去的第一道坎chromedriver、geckodriver 都有严格的对齐要求。Chrome 一升级本地脚本立刻罢工CI 上如果镜像里的浏览器版本没锁住问题更明显。现在 Selenium 有了 Selenium Manager 能自动管理部分驱动但你在直接上手新项目时体验还是不如那些把浏览器下载、版本锁定一并做掉的现代工具。等待机制全靠自己写。Selenium 的显式等待本身是合理的但每个元素都要 WebDriverWait稍微复杂一点的页面一个用例里能出现十几个 EC 条件代码块。新手最常见的做法是把隐式等待调成 10 秒、20 秒来掩盖网络波动结果整个测试套件肉眼可见地变慢。慢还不是最可怕的隐式等待和显式等待混用造成的随机超时才是 CI 上最经典的玄学问题。定位元素绕不过 CSS/XPath还特别脆。现代前端经常把 class 名语义化得很弱今天btn-submit明天重构就变btn_cus_123。项目规模一大维护定位器的成本已经不亚于维护业务代码本身。你要靠 XPath 去定位页面里某个文本内容更是每动一次页面结构都要跟着改。浏览器能力覆盖不全。如果你做的是那种带下载、上传、多标签页、shadow DOM、网络请求拦截的自动化Selenium 能实现但实现方式绕得很。比如 CDP 相关的底层操作在 Selenium 里支持的完整度一直不如协议级工具来得干净。1.2 Selenium 为什么还活着它有一个巨大的护城河生态成熟。文档、Stack Overflow 问答、各语言 binding、Appium 移动端复用同一套 WebDriver 协议、和 Jenkins/Azure DevOps 等 CI 系统的整合文档到处都是。团队新增一个人的时候招来的测试开发基本都用过 Selenium学习成本几乎为零。在我接触过的不少企业里已有的自动化资产往往就是 Selenium 代码库。不是说换就换的。这也是为什么后面介绍的工具里我会特意保留一条“和现有 WebDriver 体系兼容”的路线——你完全可以用 WebdriverIO 或 Nightwatch 这样的工具逐渐替代旧脚本而不是推翻重来。1.3 什么情况确实该换我给一个很简单的判断标准如果在你的工作流里“让脚本稳定跑起来”这件事消耗的时间超过了“写业务操作”本身你就应该考虑换了。还有一种情况是你只是想做一次爬虫或一次性的页面查询结果光写 driver 环境配置、等待函数、异常重试就花了半天。这种短期任务用 Selenium 明显是在给自己挖坑。新工具普遍把浏览器安装、自动等待、页面交互封装得更彻底你一上手就是写业务不用先处理那些前置逻辑。2. 两条主流进化路线Playwright 与 Puppeteer这一节我放在最前面是因为它们代表了目前网页自动化的主流进化方向直接通过浏览器 DevTools 协议CDP与浏览器底层通信而不是走 HTTP WebDriver 服务。速度和稳定性都是代际级别的提升。2.1 Playwright一站式跨浏览器自动化如果说现在只让我推荐一个 Selenium 替代工具我会说 Playwright。它由微软团队维护目前在 GitHub 的活跃度、文档完善度、社区口碑都属于第一梯队。真正的杀手锏有三个。第一自动等待。Playwright 内置了可执行性检查你在点击一个按钮之前它会自动判断这个元素是否可见、是否被遮挡、是否可交互、是否处于稳定状态满足条件才会执行点击。这些检查不是盲目 sleep也不是反复扫页面而是轮询判断且有超时上限。我做过对比同一个支付流程用例Selenium 里我写了 7 次 WebDriverWaitPlaywright 里一个 wait 方法都没写跑下来比 Selenium 的用例更快、更稳。第二浏览器管理器。一条命令npx playwright install chromium它会自动下载匹配的浏览器内核并锁定版本你的脚本不再依赖系统升级后你第一时间去补版本。它同时支持 Chromium、Firefox、WebKit同一套脚本可以平行跑三种内核。第三生态闭合成环。Codegen 录制脚本、UI Mode 调试、Trace Viewer 回放全部内置。你在代码里加一个--trace on跑完之后打开 trace 文件就能看到每一步的页面截图、网络请求、DOM 快照和 console 日志。Selenium 里你得额外集成 Allure 或者自研上报才能达到这种调试体验。用 Python 也非常顺。Selenium 的 Python 用户切过来基本上没有心理负担from playwright.sync_api import sync_playwright with sync_playwright() as p: browser p.chromium.launch() page browser.new_page() page.goto(https://example.com) page.get_by_role(button, name登录).click() page.get_by_label(用户名).fill(test) page.screenshot(pathlogin.png) browser.close()它和 Selenium 最大的区别就是定位器。# Selenium 时代 driver.find_element(By.CSS_SELECTOR, #login-btn).click() # Playwright 时代 page.get_by_role(button, name登录).click()角色定位器的好处是你不再依赖前端必须保留某个 class 名只要按钮的语义角色和可访问名称不变页面重构也不影响脚本。这本质上是让自动化测试代码和前端的耦合度下降了一大截。当然也有劝退点它对测试架构是有要求的组件化、夹具fixture、并发隔离都需要你去理解它的 runner 模型。如果你只想要“快速跑一条冒烟用例”它要比 Selenium 多一点框架感。2.2 PuppeteerChrome 生态里的轻骑手Puppeteer 是 Google 官方出的 Node.js 库主打 Chrome/Chromium 控制。它解决的问题更聚焦给你的 Node 应用一个完整的浏览器自动化能力。Puppeteer 的定位不是“测试框架”它没有内置断言和 test runner。它的强项是页面抓取、页面渲染、生成 PDF、性能分析这一类“我要在一个无头浏览器里做事情”的场景。比如我要批量抓取一组页面并生成淘宝风格的商品快照Selenium 会先启动 webdriver、再启动浏览器、每个 URL 都要重新写等待逻辑Puppeteer 的代码则非常直接const puppeteer require(puppeteer); (async () { const browser await puppeteer.launch(); const page await browser.newPage(); await page.goto(https://example.com, { waitUntil: networkidle0 }); await page.click(#accept); await page.screenshot({ path: page.png, fullPage: true }); await browser.close(); })();waitUntil: networkidle0这个参数就很能说明 Puppeteer 的取向——它关注的是页面状态是否稳定而不是简单判断某个元素存不存在。只要你清楚自己要抓取的目标 URL 列表这套链路写起来非常顺。但它的局限也明显默认只支持 Chromium 系列Firefox 支持是实验性的。如果你需要跨浏览器覆盖率来验证兼容性Puppeteer 不是最优解Playwright 才是。我的建议是如果你的目标是“自动化操作 Chrome 完成特定任务”选 Puppeteer如果你的目标是“团队级 Web 自动化测试”直接上 Playwright。3. 前端与全链路视角Cypress 与 TestCafe如果说 Playwright/Puppeteer 是“浏览器协议派”那 Cypress 和 TestCafe 就是“换个跑法”的典型代表。它们不再站在浏览器外部发指令而是直接插进前端运行环境里很多同步问题从根上就消失了。3.1 Cypress测试代码写起来像前端代码Cypress 的架构和 Selenium 完全不是一个生态。它的测试代码和被测应用跑在同一个浏览器进程里所以它天然知道页面内部发生的很多事情。这种架构最直接的好处是再也不会出现“元素已经在页面上但脚本点击没反应”这种 Selenium 常见问题。Cypress 内置了相似的自动重试机制命令执行前会确认元素可交互且默认快照、录像、可调试前端开发者上手几乎没有陌生感。它的 API 是这样的describe(登录流程, () { beforeEach(() { cy.visit(/login); }); it(应该能正常登录, () { cy.intercept(POST, /api/login).as(loginRequest); cy.get(#username).type(testuser); cy.get(#password).type(123456); cy.get(button[typesubmit]).click(); cy.wait(loginRequest); cy.contains(欢迎回来).should(be.visible); }); });cy.intercept直接拦截网络请求这和 Selenium 里要借助代理才能实现同样的功能相比根本不是一个时代的体验。你可以在测试里 mock 接口返回、延迟响应、断言请求体不需要额外起一个网管或者搭一层代理。但 Cypress 有个硬伤它只支持在自己的环境里打开浏览器并跑测试无法控制浏览器原生的多标签页逻辑跨域 iframe 和某些企业级登录方案比如需要打开额外窗口支持起来都很别扭。如果你做的是后台管理系统、内部 OA 这类相对单一的前端应用Cypress 体验极佳如果做的是涉及大量第三方站点跳转、复杂窗口管理的流程它就不是最合适的。3.2 TestCafe还不想要浏览器驱动试试这套TestCafe 走的是另一条技术路线它通过一个代理服务器来操纵浏览器不需要任何浏览器驱动也不需要安装插件。这一点在限制严格的企业内网环境里价值巨大。它的 API 简洁到没什么存在感import { Selector } from testcafe; fixture(登录测试) .page(https://example.com/login); test(验证登录提示, async (t) { await t .typeText(#username, test) .typeText(#password, password) .click(#login-btn) .expect(Selector(.welcome).innerText).eql(欢迎回来); });TestCafe 会在页面加载后自动等待元素可用。它不像 Selenium 那样让你纠结“到底用显式等待还是隐式等待”大部分情况下它就是能等等到了才执行下一步。它支持桌面浏览器、移动端远程浏览器以及各种云测试平台且测试代码本身不绑定浏览器环境。这意味着你可以用同一套测试用例在本地、CI、SauceLabs、BrowserStack 上跑。这里需要提醒一下TestCafe 的发展方向有过几次调整授权策略也曾变化你在把它引进团队之前要去官网确认最新版本的 license 和服务支持范围。它依然是一个好工具但“免费开源到永远”不一定成立。4. 靠 WebDriver 起飞的老熟人WebdriverIO 和 Nightwatch.js有些人看到上面这些新框架第一反应不是“真香”而是“我们已经有一堆 Selenium 资产了换不起”。如果你有这种顾虑WebdriverIO 和 Nightwatch.js 就是为你准备的。4.1 WebdriverIO从 Selenium 无缝切过来的首选WebdriverIO 本质上还运行在 WebDriver 协议之上但你完全可以把它理解成“重新设计过的 Selenium”。它依旧能复用 Selenium Grid、能接入 Appium 做移动端、能对接你现有的各种 infra但开发体验完全重做了。它最大的变化是把异步语法和测试 runner 做进了框架。你不再需要自己封装 driver factory、等待工具类、报告生成器WebdriverIO 都帮你内置好了import { browser, expect } from wdio/globals; describe(购物车流程, () { it(应该能添加商品, async () { await browser.url(https://example.com); const addButton await $(#add-to-cart); await addButton.waitForDisplayed({ timeout: 5000 }); await addButton.click(); await expect($(.cart-count)).toHaveText(1); }); });和 Selenium 最大的区别是什么它有一整套命令链和钩子机制你不需要每次都要现写WebDriverWait而是像waitForDisplayed这种链式方法直接用。测试报告、Allure 集成、视觉回归对比、Spec 测试报告等都是官方或社区插件装一个包就能用不像 Selenium 要把一堆第三方依赖手工拼起来。不过要注意WebdriverIO 从 v8 开始全面转向 async/await 模式。如果你在网上看教程看到早期版本的browser.click、browser.setValue同步写法那是老版本别照着抄。现代 WebdriverIO 的每条命令都是 Promise你要么全部 await要么配合自定义重试包装器。4.2 Nightwatch.js配置驱动、贴近旧习惯Nightwatch.js 也保留 WebDriver 协议但它更进一步把配置驱动思想贯彻得比较彻底。你可以把它理解成“长得像 Selenium 的测试框架 一个内置的 webdriver 服务管理器”。它最吸引人的地方是结构清晰。你只需要一个.nightwatch.json配置文件指定浏览器、测试目录剩下的事情框架来处理{ src_folders: [test/e2e], webdriver: { start_process: true, server_path: node_modules/.bin/chromedriver }, test_settings: { default: { desiredCapabilities: { browserName: chrome } } } }写测试用例也很简洁describe(首页冒烟测试, function() { it(验证标题, function(browser) { browser .url(https://example.com) .assert.titleContains(Example) .end(); }); });看到这个结构和 Selenium 时代 JUnit/TestNG 代码相似老测试开发几乎没有学习成本。甚至可以把现有 Selenium 测试用例逐步搬过来用相同的 WebDriver 能力但统一了框架层。需要客观说的是Nightwatch 的生态规模、插件丰富度不如 WebdriverIO 和 Playwright。如果你需要非常复杂的测试编排比如多平台并发、复杂的超时策略、自研一步断言那它稍微有点力不从心。它更适合中小团队、结构简单的 Web 项目。5. Taiko 与 Katalon给不想写选择器的人的第二条路如果你已经开始厌倦 CSS 选择器、XPath、各种定位策略的维护这个分类里的思路会让你眼前一亮它们把“用什么选择器”这件事尽量消解掉。5.1 Taiko让脚本口语化Taiko 是 ThoughtWorks 开源的自动化库它最大的特点就是“你像跟人类说话一样告诉浏览器做什么”。const { open, goto, write, click, close, text } require(taiko); (async () { try { await open(browser); await goto(https://example.com/login); await write(testuser, into(textBox({ placeholder: 用户名 }))); await write(password, into(textBox({ placeholder: 密码 }))); await click(button(登录)); await assert.text(欢迎回来).exists(); } catch (error) { console.error(error); } finally { await close(); } })();注意看这里的选择器textBox({ placeholder: 用户名 })、button(登录)、text(欢迎回来)。它通过无障碍树和实际可见文本来定位元素而不是依靠 class 名或 XPath。这意味着前端的 class 怎么改只要页面上还显示“用户名”这个提示词脚本就不用动。Taiko 最大的价值在于自动化脚本的可读性。你甚至可以把它当作文档用产品经理、业务人员也能看懂这个脚本在做什么。这一点在团队协作和审计场景下优势明显。它同样基于 CDP 与浏览器通信速度和稳定性都有保障和 Gauge 这个 BDD 框架配合尤其好。缺点是它主要照顾 Node.js 生态且社区资料相对少遇到冷门问题你可能要自己去翻源码。5.2 Katalon低代码与团队协作Katalon Studio 不是纯编码工具它的定位是“测试平台”。你可以手动写脚本但更常见的工作流是录制回放、关键字驱动、和 BDD 描述。Katalon 特别适合两类场景一类是团队里有不擅长编程的测试人员想把业务人员带入自动化流另一类是需要管理和跟踪大量测试用例的企业环境。它有测试套件管理、执行历史、测试报告、与 JIRA 集成基本就是一套开箱即用的测试管理系统。它的操作方式一般是打开 Record 功能人工操作一遍被测系统Katalon 自动录制关键字然后你可以调整测试数据、加上断言再放进 CI 跑。整个过程不需要手写一行 CSS/XPath。需要提醒一句Katalon 有免费和商业授权之分商业团队使用时一定要去确认清楚版本条款特别是把免费版用于企业项目时授权边界需要弄明白。低代码工具经常会踩这种坑签合同或合规审查时不太好看。6. 八大工具横评与选型参考到了需要拍板的时候光看单个工具的优点没有意义还是要放在你自己的场景里比。6.1 横评对照表工具底层技术自动等待多浏览器主要语言最适合场景上手难度PlaywrightCDP原生完整Chromium/Firefox/WebKitJavaScript/TypeScript/Python团队级 Web UI 自动化中等PuppeteerCDP基础支持Chromium 为主JavaScript爬虫、页面处理简单Cypress进程内驱动原生完整仅浏览器环境JavaScript/TypeScript前端应用端到端测试简单TestCafe代理服务器原生完整多浏览器JavaScript/TypeScript内网环境、浏览器兼容简单WebdriverIOWebDriver / CDP显式隐式多浏览器JavaScript/TypeScript从 Selenium 迁移过渡中等Nightwatch.jsWebDriver可配置多浏览器JavaScript结构化团队测试低TaikoCDP原生完整Chromium/EdgeJavaScript/TypeScript追求低维护的运营自动化低KatalonWebDriver 内核平台有多浏览器低代码 / Groovy低代码团队协作低整体管理成本较高6.2 选型看这四件事第一件事团队代码栈。前端团队会用 JavaScript那 Cypress 和 Playwright 都非常契合后端团队用 PythonPlaywright 虽然原生支持 Python但整体生态和示例更多的还是 JS需要做好心理建设如果是纯测试团队且以后要维护大量用例Katalon 这种低代码平台可降低门槛。第二件事你被 Selenium 的哪个痛点逼疯的。如果是等待上 Playwright/Cypress 这类自动等待原生完整的如果是驱动管理选 Playwright 和 Puppeteer如果是现有资产太重走 WebdriverIO 逐步替换。第三件事跨浏览器到底是不是硬需求。我说过很多次“多浏览器”但大部分项目实际是 Chrome-first 的做兼容性回归可能只是每个季度手动点一轮。为了这种频率去搭建跨浏览器自动化维护成本反而高过手工。确认不了需求时先锁定 Chromium跑通了再说。第四件事你的部署环境。内网环境、没有外网下载权限的情况下TestCafe 这种无驱动依赖的最省事CI 环境用 Playwright 要提前把浏览器二进制装好不然每次全新容器都会卡在下载那一步。7. 从 Selenium 迁移过来最容易被忽略的差异点很多团队选好新工具之后其实最难的不是写新用例而是把老用例和团队习惯迁过去。这里我踩过不少坑给大家拆几个最关键的差异。7.1 等待机制不是同一个物种在 Selenium 里你的脚本思路是我要找这个元素找不到就等一下等不到就报错。几乎所有的时间都耗在“等待”上。而 Playwright/Cypress/TestCafe 这类工具的等待是内建在每一次交互里的点击、输入、断言都会在一个超时窗口内持续检查条件。这带来一个迁移时的陷阱老代码里的time.sleep(3)或WebDriverWait(...).until(...)如果直接迁移过去新工具反而会因为额外等待拖慢执行速度。迁移到 Playwright 时最正确的做法是把所有 sleep 删干净让内置动作自己判断。7.2 定位器思维要换老代码里的By.ID、By.XPATH不是不能用但你会白白丢掉新工具的价值。以 Playwright 为例getByRole()和getByLabel()这种语义化定位是它相对 Selenium 的降维优势。迁移时尽量做一次“定位器重写”而不是把老的 XPath 原样搬过来。有一种很实际的做法行业规范标注。我遇到过前端负责人直接把页面元素全部加上可访问性标记然后用 Playwright 的 role locator测试脚本维护成本一下子下降很多。如果你想顺利换工具最好同步推动前端做可访问性支持。7.3 多标签页、网络拦截、调试工具全是新世界Selenium 处理新标签页要driver.switch_to.windowPlaywright 直接通过 context 管理页面同一个会话里的多页面天然隔离。Selenium 想拦截网络请求得配置 BrowserMob 代理而 Cypress 里一条cy.intercept就解决了Playwright 的page.route也能做到。如果你之前没接触过这些能力它们会颠覆你对自动化工具的认知。7.4 现有用例的迁移顺序务实一点不要追求一次性全部迁移。我建议的顺序是先挑 5 条高频、最不稳定的核心链路用例做 Pilot用来评估新工具在你们项目里的真实体验跑通之后再处理维护成本最高、等待逻辑最复杂的存量用例最后才考虑拆老框架。迁移过程中有一个容易忽略的点CI 配置和部署环境。Playwright 的浏览器二进制要重新做镜像Cypress 对 Node 环境版本有要求Katalon 要在 CI 节点上装客户端。换工具从来不只是换一个依赖包是整个基础设施链路都要跟着升级这个成本要提前算进去。8. 最后一点建议工具始终是“术”自动化体系才是“道”。我这几年换了好几轮自动化工具最大的体会是没有一个工具能解决所有问题但选对工具能省掉大量无意义的时间。Playwright 适合大多数新启动的项目Cypress 适合前端驱动型的团队WebdriverIO 适合对 Selenium 资产有依赖的过渡阶段。如果你现在还在 Selenium 边缘徘徊不用急着把全部历史代码推倒重来。先选一个你真正感兴趣的替代工具拿一个平时最容易崩但不算复杂的场景练手亲自观察一下它的自动等待、调试体验、报错信息这三个维度相信你很快就能感受到差距。最后提醒一句自动化的本质是服务于业务价值不是工具越新越好。一个稳定的 Selenium 项目永远好过一个三天两头换框架的项目。但如果现状已经痛到影响交付了那这 8 款工具里一定有一款是能帮你把事情做得更省力的。
返回列表