当前位置: 首页 > news >正文

一小时上手Playwright:跨浏览器自动化测试从零到CI/CD集成

1. 项目概述:为什么是Playwright?

如果你正在为网页应用在不同浏览器上的表现不一致而头疼,或者厌倦了为Chrome、Firefox、Safari分别维护一套自动化测试脚本,那么今天聊的这个工具,可能就是你的“解药”。我说的就是Playwright,一个由微软开源的现代化端到端(E2E)测试与浏览器自动化库。它的核心卖点非常直接:用一个统一的API,控制所有主流浏览器(Chromium、Firefox、WebKit),实现真正意义上的跨浏览器自动化

这听起来可能和Selenium有点像,但Playwright是站在巨人肩膀上的一次“降维打击”。它诞生于2019年,设计之初就瞄准了现代Web应用(单页应用SPA、PWA等)的测试痛点。我最初接触它是因为一个紧急的兼容性验证需求,客户要求我们的H5活动页必须在Chrome、Edge、Safari(iOS)和Firefox上表现完美。当时用Selenium和Puppeteer的组合,光是环境配置和脚本适配就折腾了两天。后来尝试Playwright,从安装到写出第一个能在四个浏览器上运行的测试用例,真的只用了不到一小时。这种“开箱即用”的畅快感,让我决定把它作为团队UI自动化测试的首选工具。

它特别适合这几类人:前端开发者,想快速验证自己页面的兼容性;测试工程师,希望提升自动化测试的稳定性和编写效率;爬虫工程师或RPA开发者,需要一个更稳定、功能更强的浏览器自动化工具。即使你没有任何自动化测试经验,跟着本文的步骤,也能在一小时内搭建起可用的跨浏览器测试环境并跑通第一个脚本。

2. 环境准备与极速安装

工欲善其事,必先利其器。Playwright的安装过程是其“用户体验”优秀的第一体现。它极力追求简化,甚至内置了浏览器,避免了传统工具需要单独下载、匹配浏览器驱动版本的噩梦。

2.1 核心依赖:Node.js与包管理器

Playwright主要支持Node.js(也支持Python、Java、.NET,但Node.js生态最活跃)。因此,第一步是确保你的系统安装了Node.js(版本14或以上)。

  • 检查安装:打开终端(Windows的CMD/PowerShell,Mac/Linux的Terminal),输入node -vnpm -v,如果能显示版本号,说明已安装。
  • 若无安装:直接访问 Node.js 官网,下载LTS(长期支持版)安装包,像安装普通软件一样完成即可。安装Node.js时会自动包含npm(Node包管理器)。

我个人更推荐使用yarnpnpm作为包管理器,它们在依赖管理和安装速度上通常优于npm。你可以通过npm install -g yarnnpm install -g pnpm来全局安装它们。

2.2 一键安装Playwright

这是最爽的一步。在你的项目目录下,打开终端,执行以下命令:

# 使用 npm npm init playwright@latest # 或使用 yarn yarn create playwright # 或使用 pnpm pnpm create playwright

这个命令会启动一个交互式的安装向导。它会问你几个问题:

  1. 选择测试语言:TypeScript 或 JavaScript?对于新手,我建议选JavaScript,门槛更低。有前端经验的可以选TypeScript,能获得更好的类型提示。
  2. 选择测试文件夹名称:默认是testse2e,直接回车就行。
  3. 是否添加GitHub Actions工作流:如果你是新手,可以先选“false”,后续再研究。
  4. 是否安装Playwright浏览器一定要选“true”!这是Playwright的核心优势,它会自动下载Chromium、Firefox和WebKit浏览器,确保测试环境的一致性。

安装过程可能会持续几分钟,因为它需要下载三个浏览器(总计约300-400MB)。如果遇到网络问题导致下载缓慢或失败,可以尝试设置镜像源。例如,在安装前设置环境变量(仅针对Playwright的下载):

# Linux/macOS export PLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright # Windows (PowerShell) $env:PLAYWRIGHT_DOWNLOAD_HOST="https://npmmirror.com/mirrors/playwright" # 然后再运行安装命令 npm init playwright@latest

注意:安装向导完成后,你的项目目录下会生成一些关键文件:playwright.config.js(配置文件)、tests/(测试用例目录)、package.json(项目依赖)。同时,node_modules目录下会有一个.playwright文件夹,里面就存放着刚下载的浏览器。

2.3 验证安装与内置工具

安装完成后,立刻验证一下。运行Playwright自带的测试样例:

npx playwright test

这个命令会运行tests/目录下生成的示例测试,并在终端以无头模式(不打开浏览器UI)运行。如果看到所有测试通过(绿色对勾),恭喜你,环境搭建成功!

此外,Playwright还提供了两个极其好用的命令行工具:

  • npx playwright codegen:录制工具。运行后会自动打开浏览器,你在浏览器里的所有操作(点击、输入、导航)都会被实时转换成Playwright代码。这是零基础入门的神器,能让你直观地理解API。
  • npx playwright show-report:打开最后一次测试运行的HTML报告。这个报告非常美观,包含了测试时长、截图、追踪信息(Trace),对于排查问题至关重要。

3. 核心概念与API快速上手

Playwright的API设计非常直观,核心对象只有几个。理解了它们,你就能写出绝大部分自动化脚本。

3.1 核心对象关系图(概念)

想象一下操作浏览器的过程:

  1. 你需要启动一个浏览器实例(Browser)。
  2. 在浏览器里打开一个标签页,即上下文(BrowserContext)。上下文可以隔离Cookie、本地存储等,模拟不同的用户会话。
  3. 在上下文里打开具体的页面(Page)。我们绝大部分操作都与Page对象交互。
  4. 在页面上找到元素(Locator),然后对它进行操作(点击、输入等)。

它们的层级关系是:Browser->BrowserContext->Page->Locator

3.2 第一个脚本:打开百度并搜索

让我们跳过复杂的理论,直接写一个能跑的脚本。在项目根目录创建一个demo.js文件:

// 导入playwright库 const { chromium, firefox, webkit } = require('playwright'); (async () => { // 1. 启动浏览器(这里以Chromium为例,可替换为 firefox 或 webkit) const browser = await chromium.launch({ headless: false // 设置为false,让我们能看到浏览器操作 }); // 2. 创建一个新的浏览器上下文(类似于无痕模式) const context = await browser.newContext(); // 3. 打开一个新页面 const page = await context.newPage(); // 4. 导航到百度 await page.goto('https://www.baidu.com'); // 5. 定位搜索框,输入“Playwright” // 这里使用了CSS选择器 #kw 来定位百度搜索框 await page.locator('#kw').fill('Playwright'); // 6. 定位搜索按钮并点击 await page.locator('#su').click(); // 7. 等待页面导航完成(搜索结果页加载) await page.waitForLoadState('networkidle'); // 8. 截图保存结果(可选) await page.screenshot({ path: 'baidu-search.png' }); // 9. 等待3秒,方便我们观察 await page.waitForTimeout(3000); // 10. 关闭浏览器 await browser.close(); })();

保存文件,在终端运行:

node demo.js

你会看到一个Chromium浏览器自动打开,访问百度,输入“Playwright”并搜索,然后截图保存,最后关闭。这就是一个最基础的自动化流程。

3.3 关键API详解与最佳实践

1. 浏览器启动(Launch)chromium.launch()是最常用的启动方式。关键参数:

  • headless:true(默认,无界面)用于CI/CD环境;false用于调试。
  • slowMo: 数字,例如500,表示每个操作后慢放500毫秒,方便调试时看清过程。
  • args: 传递额外的浏览器启动参数,如['--start-maximized']最大化窗口。

2. 元素定位器(Locator)这是Playwright最强大的部分之一。page.locator(selector)返回一个Locator对象,它代表一个或一组元素。Playwright推荐使用“用户可见”的定位策略

  • 文本定位page.locator('text=登录')查找包含“登录”文本的元素。这是最接近用户行为的定位方式。
  • CSS选择器page.locator('#submit-btn')page.locator('.btn.primary')。通用,但可能随前端样式变化而失效。
  • XPathpage.locator('//button[@id="submit"]')。功能强大但可读性差,尽量作为备选。
  • 组合定位page.locator('article').locator('button').first()先找到文章,再找里面的第一个按钮。

实操心得:优先使用text=role=(ARIA角色)定位,它们最稳定。尽量避免使用依赖于样式类名或复杂DOM结构的CSS选择器,因为前端重构时这些最容易变。使用codegen录制时,可以观察它生成的定位器,学习最佳实践。

3. 等待(Wait)现代Web应用大量使用异步加载,等待是自动化脚本稳定的关键。Playwright提供了智能的“自动等待”机制。

  • 导航等待page.goto(url, { waitUntil: 'networkidle' })会等待页面基本没有网络请求时才认为加载完成。
  • 元素等待page.locator('button').click()本身就会自动等待该按钮可点击(可见、启用、稳定)。你也可以显式等待:await page.locator('.toast').waitFor({ state: 'visible' })
  • 自定义等待page.waitForTimeout(3000)是固定的硬等待,应尽量避免。使用page.waitForSelector()page.waitForFunction()进行条件等待更佳。

4. 处理弹窗与多页面

  • 弹窗(Dialog):监听dialog事件来处理alert,confirm,prompt
    page.on('dialog', async dialog => { console.log(dialog.message()); await dialog.accept(); // 点击“确定” // await dialog.dismiss(); // 点击“取消” });
  • 新标签页:监听popup事件。
    const [newPage] = await Promise.all([ page.waitForEvent('popup'), page.locator('a[target="_blank"]').click() // 点击一个打开新窗口的链接 ]); await newPage.bringToFront(); // 切换到新页面

4. 实现跨浏览器测试套件

单浏览器运行只是热身,Playwright的真正威力在于轻松实现跨浏览器测试。我们不需要为每个浏览器重写脚本,只需要在配置和运行时指定浏览器即可。

4.1 配置多浏览器项目

Playwright的核心配置文件是playwright.config.js。安装时生成的默认配置已经为我们搭好了多浏览器的架子。我们来解读和优化一下关键部分:

// playwright.config.js const { defineConfig, devices } = require('@playwright/test'); module.exports = defineConfig({ // 测试目录,默认是 'tests' 或 'e2e' testDir: './tests', // 全局超时时间 timeout: 30 * 1000, // 期望(断言)的超时时间 expect: { timeout: 5000 }, // 并行运行测试(可以显著缩短总耗时) fullyParallel: true, // 每个测试文件默认重试次数(用于处理偶发性失败) retries: process.env.CI ? 2 : 0, // 在CI环境中重试2次,本地不重试 // 工作进程数,通常设置为CPU核心数 workers: process.env.CI ? 1 : undefined, // CI环境设为1保证稳定,本地用默认值 // 报告生成器 reporter: [ ['html', { outputFolder: 'playwright-report' }], // 生成HTML报告 ['list'] // 在控制台输出简洁列表 ], // 全局配置,对所有项目生效 use: { // 每个测试的基础URL,这样测试中可以用相对路径 // baseURL: 'http://localhost:3000', // 自动录制失败测试的视频 video: 'retain-on-failure', // 自动录制失败测试的追踪信息(Trace),用于详细调试 trace: 'retain-on-failure', // 全局截图选项:仅在测试失败时截图 screenshot: 'only-on-failure', }, // 定义多个“项目”,每个项目对应一种浏览器或设备配置 projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] }, // 使用预定义的桌面Chrome设备配置 }, { name: 'firefox', use: { ...devices['Desktop Firefox'] }, }, { name: 'webkit', use: { ...devices['Desktop Safari'] }, }, // 移动端测试示例(需要时可取消注释) // { // name: 'Mobile Chrome', // use: { ...devices['Pixel 5'] }, // }, // { // name: 'Mobile Safari', // use: { ...devices['iPhone 12'] }, // }, ], });

这个配置定义了三套并行的测试环境:Chromium(模拟Chrome)、Firefox和WebKit(模拟Safari)。当你运行测试时,Playwright Test 运行器会自动为每个项目启动对应的浏览器并运行测试。

4.2 编写跨浏览器兼容的测试用例

现在,在tests目录下创建一个真正的测试文件,比如search.spec.js。Playwright Test框架(@playwright/test)提供了类似Jest的测试语法。

// tests/search.spec.js const { test, expect } = require('@playwright/test'); // 这个测试会在配置文件中定义的所有浏览器项目中运行 test('百度搜索功能跨浏览器测试', async ({ page }) => { // 1. 导航到百度 await page.goto('https://www.baidu.com'); // 2. 断言:页面标题包含“百度” await expect(page).toHaveTitle(/百度/); // 3. 定位搜索框并输入关键词 const searchBox = page.locator('#kw'); await searchBox.fill('Playwright 自动化'); await expect(searchBox).toHaveValue('Playwright 自动化'); // 断言输入值正确 // 4. 点击搜索按钮 await page.locator('#su').click(); // 5. 等待搜索结果出现,并断言结果页包含相关文本 await page.waitForURL('**/s?**'); // 等待URL变成搜索结果页模式 const firstResult = page.locator('#content_left >> .result >> nth=0'); await expect(firstResult).toBeVisible(); await expect(page.locator('text=微软开源')).toBeVisible({ timeout: 10000 }); // 期望结果中出现“微软开源” }); // 另一个测试用例:测试页面元素在不同浏览器下的渲染 test('百度首页核心元素可见性', async ({ page, browserName }) => { await page.goto('https://www.baidu.com'); // 使用 browserName 可以针对特定浏览器做差异化断言或操作 // 例如,某些元素可能在Safari上样式不同 const logo = page.locator('#lg'); await expect(logo).toBeVisible(); const newsLink = page.locator('text=新闻'); await expect(newsLink).toBeVisible(); // 截图用于视觉对比(可归档) await page.screenshot({ path: `homepage-${browserName}.png` }); });

4.3 运行与查看跨浏览器测试结果

编写完成后,运行测试:

# 运行所有测试,在所有浏览器上 npx playwright test # 运行特定文件 npx playwright test search.spec.js # 在特定浏览器上运行(项目名来自配置文件) npx playwright test --project=chromium npx playwright test --project=firefox --project=webkit # 以UI模式运行(交互式,可调试) npx playwright test --ui

运行npx playwright test后,你会看到控制台输出类似如下信息,清晰地展示了每个浏览器项目的测试结果:

Running 4 tests using 4 workers ✓ [chromium] › search.spec.js:3:1 › 百度搜索功能跨浏览器测试 (5.1s) ✓ [firefox] › search.spec.js:3:1 › 百度搜索功能跨浏览器测试 (6.3s) ✓ [webkit] › search.spec.js:3:1 › 百度搜索功能跨浏览器测试 (7.8s) ✓ [chromium] › search.spec.js:18:1 › 百度首页核心元素可见性 (2.1s) ...

测试完成后,生成HTML报告:

npx playwright show-report

报告会详细列出每个测试用例在不同浏览器上的通过/失败状态、耗时、截图、执行步骤,甚至视频和追踪文件(如果配置了)。通过对比不同浏览器下的截图和日志,可以快速定位兼容性问题。

5. 高级技巧与实战避坑指南

掌握了基础,我们来看看如何让Playwright脚本更健壮、更高效,以及如何处理那些令人头疼的“坑”。

5.1 处理动态内容与复杂等待

现代前端框架(React, Vue, Angular)渲染的内容往往是动态的。一个常见的坑是:元素在DOM中存在,但可能因为动画或数据未就绪而不可交互。

解决方案1:使用更精准的定位器状态等待不要只等元素出现(toBeVisible),要等它处于可交互状态。

// 不佳:可能点击时按钮仍是disabled状态 await page.locator('button.submit').click(); // 更佳:等待按钮可点击 const submitButton = page.locator('button.submit'); await submitButton.waitFor({ state: 'attached' }); // 确保在DOM中 await submitButton.waitFor({ state: 'visible' }); // 确保可见 await expect(submitButton).toBeEnabled(); // 确保未禁用 await submitButton.click();

Playwright的click()本身内置了这些等待,但对于极端情况,显式等待可以增加稳定性。

解决方案2:等待网络请求很多操作(如提交表单)会触发特定的网络请求。等待请求完成是更可靠的信号。

// 监听特定的API请求 const [response] = await Promise.all([ page.waitForResponse(response => response.url().includes('/api/submit') && response.status() === 200), page.locator('button.submit').click() ]); console.log('提交成功,返回数据:', await response.json());

解决方案3:自定义等待函数对于复杂的渲染逻辑,可以使用page.waitForFunction

// 等待页面某个特定状态出现,例如某个全局变量被设置 await page.waitForFunction(() => window.appState && window.appState.loaded === true); // 等待某个元素内部的文本变为特定值 await page.locator('.status').waitFor({ state: 'visible' }); await page.waitForFunction( selector => document.querySelector(selector).innerText === '加载完成', '.status' );

5.2 认证状态与上下文隔离

测试中经常需要登录。每次测试都走一遍登录流程效率太低。Playwright的BrowserContext可以完美解决这个问题。

方案:复用认证状态

const { test, expect } = require('@playwright/test'); test.describe('已登录用户测试套件', () => { // 在所有测试前,创建一个已登录的上下文 let context; let page; test.beforeAll(async ({ browser }) => { context = await browser.newContext(); page = await context.newPage(); // 执行登录操作 await page.goto('https://example.com/login'); await page.locator('#username').fill('testuser'); await page.locator('#password').fill('password'); await page.locator('button[type="submit"]').click(); // 等待登录成功,例如跳转到首页或出现用户菜单 await expect(page.locator('.user-avatar')).toBeVisible(); // 将登录状态存储到文件,以便后续测试复用 await context.storageState({ path: 'auth-state.json' }); }); test.afterAll(async () => { await context.close(); }); test('测试用户首页', async () => { // 这个page已经是登录状态 await page.goto('https://example.com/dashboard'); await expect(page.locator('text=欢迎回来,testuser')).toBeVisible(); }); // 另一个测试,可以复用同一个context和page,或者新建一个加载了存储状态的context test('测试用户设置页面', async ({ browser }) => { // 新建一个上下文,但加载之前保存的认证状态 const newContext = await browser.newContext({ storageState: 'auth-state.json' }); const newPage = await newContext.newPage(); await newPage.goto('https://example.com/settings'); // ... 进行测试 await newContext.close(); }); });

storageState功能非常强大,它保存了Cookie、LocalStorage等,相当于保存了一个“浏览器指纹”。在CI/CD流水线中,可以先运行一个“登录准备”测试来生成这个文件,后续所有测试都复用,极大提升效率。

5.3 文件上传与下载

文件上传:Playwright处理上传非常优雅,不需要像Selenium那样模拟键盘操作。

// 对于 input[type="file"] 元素 const fileInput = page.locator('input[type="file"]'); await fileInput.setInputFiles(['/path/to/file1.jpg', '/path/to/file2.pdf']); // 如果上传是通过拖拽或复杂组件,可能需要触发事件 await page.dispatchEvent('.drop-zone', 'drop', { dataTransfer: { files: [file1, file2] // 这里需要File对象,可通过其他方式创建 } });

文件下载:监听download事件。

// 开始监听下载事件 const [download] = await Promise.all([ page.waitForEvent('download'), // 等待下载事件触发 page.locator('a#download-link').click() // 触发下载的操作 ]); // 获取下载建议的文件名,并保存到指定路径 const suggestedFilename = download.suggestedFilename(); const savePath = `./downloads/${suggestedFilename}`; await download.saveAs(savePath); console.log(`文件已下载到: ${savePath}`);

5.4 常见问题排查与调试技巧

问题1:元素定位不到,报错TimeoutError: locator.click: Timeout 30000ms exceeded

  • 可能原因1:元素在iframe内。需要先切换到iframe上下文。
    const frame = page.frame({ name: 'iframe-name' }) || page.frame({ url: /.*preview.*/ }); if (frame) { await frame.locator('button').click(); }
  • 可能原因2:元素是动态生成的,选择器不对。使用codegen重新录制,或打开Playwright Inspector (PLAYWRIGHT_DEBUG=1环境变量) 实时查看推荐的选择器。
  • 可能原因3:页面有多个匹配元素。使用nth或更精确的选择器。
    await page.locator('button').nth(2).click(); // 点击第三个按钮 await page.locator('.list-item:has-text("特定文本")').click();

问题2:脚本在CI(如GitHub Actions)上跑不通,本地却正常

  • 检查浏览器安装:CI环境通常是全新的。确保CI脚本中包含了安装浏览器的步骤:npx playwright installnpx playwright install --with-deps
  • 使用无头模式:CI环境没有图形界面,确保配置中headless: true(默认就是)。
  • 增加超时时间:CI服务器可能比本地慢,适当增加timeoutexpect.timeout配置。
  • 查看追踪(Trace)和截图:这是Playwright的杀手锏。在配置中启用trace: 'on-first-retry'trace: 'retain-on-failure'。测试失败后,下载trace.zip文件,使用npx playwright show-trace trace.zip命令打开一个可视化界面,可以一步步回放测试执行过程,查看每个时间点的DOM快照、控制台日志、网络请求,定位问题如同看录像回放。

问题3:如何处理验证码?自动化测试遇到验证码是一个哲学问题。最佳实践是:

  1. 在测试环境关闭验证码:这是最推荐的方式。与开发团队协作,为测试环境提供开关,或使用万能验证码(如“0000”)。
  2. 使用Mock或Stub:拦截验证码接口的请求,直接返回成功的响应。
  3. 第三方服务(不推荐用于核心测试):有付费的OCR识别服务,但成本高、速度慢、不稳定,仅作为最后手段。

调试神器:Playwright Inspector除了codegen,还可以通过以下方式启动带调试器的浏览器:

# 设置环境变量后运行测试 PWDEBUG=1 npx playwright test # 或 PLAYWRIGHT_DEBUG=1 npx playwright test

这会以“调试模式”运行,浏览器会放慢速度,并且会打开一个 Inspector 窗口,你可以单步执行、查看定位器、录制动作等,是学习API和排查复杂交互问题的利器。

6. 集成到CI/CD与生产实践

个人玩转之后,如何让团队共享,并集成到开发流程中,让自动化测试创造价值?

6.1 与GitHub Actions集成

在项目根目录创建.github/workflows/playwright.yml文件:

name: Playwright Tests on: push: branches: [ main, master ] pull_request: branches: [ main, master ] jobs: test: timeout-minutes: 60 runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '18' - name: Install dependencies run: npm ci # 使用ci命令保证依赖锁一致 - name: Install Playwright Browsers run: npx playwright install --with-deps - name: Run Playwright tests run: npx playwright test - uses: actions/upload-artifact@v4 if: always() # 无论测试成功失败,都上传报告 with: name: playwright-report path: playwright-report/ retention-days: 30 - uses: actions/upload-artifact@v4 if: failure() # 仅在失败时上传追踪文件 with: name: playwright-traces path: test-results/ retention-days: 30

这个工作流会在每次推送到主分支或创建Pull Request时,自动在Ubuntu环境下安装依赖、安装浏览器、运行所有测试,并将HTML报告和失败用例的追踪文件打包上传,供开发者下载查看。

6.2 测试策略与目录结构建议

对于真实项目,合理的测试结构能提升维护性。

my-app/ ├── playwright.config.js ├── package.json ├── tests/ │ ├── auth/ # 认证相关测试 │ │ ├── login.spec.js │ │ └── logout.spec.js │ ├── dashboard/ # 仪表盘相关测试 │ │ ├── overview.spec.js │ │ └── widgets.spec.js │ ├── fixtures/ # 测试夹具,如全局的page对象、测试数据 │ │ └── global-setup.js │ ├── pages/ # Page Object模型,封装页面元素和操作 │ │ ├── LoginPage.js │ │ └── DashboardPage.js │ └── utils/ # 工具函数 │ └── helpers.js └── ...

使用Page Object模式:这是中大型项目的标配。将页面的定位器和操作封装成类,使测试用例更清晰,元素变更时只需修改一处。

// tests/pages/LoginPage.js class LoginPage { constructor(page) { this.page = page; this.usernameInput = page.locator('#username'); this.passwordInput = page.locator('#password'); this.submitButton = page.locator('button[type="submit"]'); this.errorMessage = page.locator('.alert-error'); } async navigate() { await this.page.goto('/login'); } async login(username, password) { await this.usernameInput.fill(username); await this.passwordInput.fill(password); await this.submitButton.click(); } } module.exports = LoginPage; // 在测试用例中使用 const LoginPage = require('../pages/LoginPage'); test('登录失败显示错误信息', async ({ page }) => { const loginPage = new LoginPage(page); await loginPage.navigate(); await loginPage.login('wrong', 'wrong'); await expect(loginPage.errorMessage).toBeVisible(); });

6.3 性能与稳定性优化

  • 并行执行:充分利用fullyParallel: trueworkers配置。一台性能不错的机器上,workers可以设置为CPU核心数,让多个测试文件同时跑。
  • 测试隔离:每个测试应该独立,不依赖其他测试的状态。使用test.describe配合test.beforeEach来为每组测试初始化状态,避免污染。
  • 选择性运行
    # 只运行包含“登录”标签的测试 npx playwright test --grep "登录" # 运行指定文件、指定行号的测试 npx playwright test search.spec.js:10 # 运行上次失败的测试 npx playwright test --last-failed
  • 视觉回归测试:Playwright可以集成像@playwright/testexpect(page).toHaveScreenshot()进行截图对比,但更专业的视觉差异检测建议使用如percyapplitools等专门服务。

从环境搭建到编写第一个脚本,再到配置跨浏览器测试、集成CI/CD,Playwright以其一体化的设计和开发者友好的API,确实能让你在极短时间内构建起可靠的自动化测试能力。关键在于动手实践,从一个小脚本开始,逐步扩展到覆盖核心业务流程的测试套件。当你在Pull Request中看到自动运行的跨浏览器测试报告,并自信地点击“合并”时,你会觉得这一小时的投入,实在太值了。

http://www.jsqmd.com/news/1111980/

相关文章:

  • Wagtail CMS安全实战:从漏洞扫描到自动化防护的完整指南
  • JMeter gRPC性能测试插件实战:从原理到CI/CD集成
  • 漏洞利用神器mona.py:Immunity Debugger插件核心功能实战指南
  • JMeter接口测试实战:从核心元件到复杂场景构建
  • MATLAB线性方程组迭代求解工具包:雅可比与高斯-赛德尔双算法实现,支持步数调节与收敛可视化
  • Java Applet版刽子手游戏源码:含完整项目结构、吊杆绘图与胜负逻辑
  • 使用Apache JMeter对RoadRunner PHP应用进行性能测试与调优指南
  • 基于pytest+uiautomation+Allure的Windows桌面应用自动化测试框架搭建指南
  • yuzu模拟器完整指南:如何在PC上高效运行Switch游戏的实用方案
  • Web渗透测试实战指南:从零基础到精通的安全评估全流程
  • 从零搭建JMeter压力测试脚本:核心组件与实战流程详解
  • JMeter性能测试实战:从入门到精通,掌握接口压测与分布式部署
  • PIC18F56K42与DS28EC20的1-Wire EEPROM存储方案详解
  • STM32与PCF8591实现高效数据采集与控制系统
  • 音乐解锁终极指南:3分钟快速解密QQ音乐、网易云加密文件,实现跨平台自由播放
  • 【大模型原理与微调实战08】微调核心通俗精讲:SFT全量微调与LoRA轻量化微调本质区别(小白零基础看懂)
  • AI Agent开发全栈指南:从理论到工程实践
  • JMeter SSE接口自动化测试:流式响应数据提取与断言实战
  • C++实现支持32位和64位进程的模块枚举
  • Frida Native函数Hook实战:精准获取堆栈、参数与返回值
  • JMeter性能测试入门实战:从环境搭建到结果分析全流程指南
  • JMeter CSV参数化实战:数据驱动性能测试配置与并发控制详解
  • AI安全测试与红队评估:从原理到企业落地
  • 告别手动转存:夸克网盘自动化管理终极指南
  • CVE-2023-38646漏洞应急响应:Metabase企业版RCE漏洞检测、修复与验证实战
  • 使用wrk对vLLM OpenAI API进行压力测试与性能调优实战
  • OpenClaw实战:从AI工具到生产力伙伴的转型指南
  • 日志系统——系统的“黑匣子“
  • ChatGPT聊天机器人实战部署:从API密钥配置到对话状态管理,7大核心模块一次性打通
  • Web安全加固:X-Frame-Options与HSTS响应头配置实战指南