为什么选择 Playwright?
在开始之前,你可能想知道为什么选择 Playwright 而不是其他测试框架。我最初接触 Playwright 是因为它出色的跨浏览器支持——它同时支持 Chromium、Firefox 和 WebKit 内核,这意味着你可以用一套代码测试 Chrome、Firefox 和 Safari。更重要的是,它的自动等待机制让测试脚本更加稳定,不需要像以前那样到处添加 sleep 语句。
我使用 Playwright 已经有一年多时间,在实际项目中它确实大大减少了因页面加载时间不稳定导致的测试失败。下面我将带你从零开始搭建环境,并编写第一个真正的测试脚本。
环境搭建:一步步来
1. 安装 Node.js
Playwright 基于 Node.js,所以首先需要安装 Node.js 环境。我建议使用 Node.js 16 或更高版本。
# 检查Node.js是否安装node --version
# 如果未安装,访问Node.js官网下载安装包# https://nodejs.org/
复制代码
安装完成后,我习惯创建一个专门的目录来管理测试项目:
mkdir playwright-tutorialcd playwright-tutorial
复制代码
2. 初始化项目并安装 Playwright
# 初始化npm项目(一路按回车使用默认值即可)npm init -y
# 安装Playwrightnpm install playwright
# 或者如果你想要TypeScript支持npm install playwright @types/node @typescript-eslint/eslint-plugin --save-dev
复制代码
安装过程可能需要几分钟,因为 Playwright 会下载它需要的浏览器二进制文件。我建议喝杯咖啡等待一下——第一次安装时它会下载三个浏览器(Chromium、Firefox 和 WebKit),大约需要 200-300MB 磁盘空间。
3. 验证安装
创建一个简单的验证脚本 check-installation.js:
const { chromium } = require('playwright');
(async () => { const browser = await chromium.launch({ headless: false }); const page = await browser.newPage(); await page.goto('https://www.example.com'); console.log('页面标题:', await page.title()); await new Promise(resolve => setTimeout(resolve, 3000)); // 等待3秒查看效果 await browser.close();})();
复制代码
运行这个脚本:
node check-installation.js
复制代码
如果你看到一个浏览器窗口打开并显示 example.com,恭喜你!环境搭建成功。
配置编辑器(可选但推荐)
我个人使用 VS Code,并且推荐安装这些扩展:
在项目根目录创建 .vscode/launch.json 文件可以方便调试:
{ "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "运行Playwright测试", "program": "${workspaceFolder}/node_modules/.bin/jest", "args": ["--runInBand"] } ]}
复制代码
编写第一个真正的测试脚本
现在进入有趣的部分!让我们编写一个实际的测试场景:测试百度搜索功能。
创建文件 first-test.js:
const { chromium } = require('playwright');
describe('百度搜索测试', () => { let browser; let page;
// 每个测试用例之前运行 beforeEach(async () => { browser = await chromium.launch({ headless: false, // 设置为true可以在后台运行 slowMo: 500 // 放慢操作速度,方便观察 }); page = await browser.newPage(); await page.goto('https://www.baidu.com'); });
// 每个测试用例之后运行 afterEach(async () => { await browser.close(); });
it('应该能够搜索关键词并显示结果', async () => { // 定位搜索框并输入内容 const searchInput = await page.$('#kw'); await searchInput.type('Playwright自动化测试'); // 点击搜索按钮 const searchButton = await page.$('#su'); await searchButton.click(); // 等待搜索结果加载 await page.waitForSelector('.result'); // 获取第一个结果标题 const firstResult = await page.$('.c-container h3 a'); const title = await firstResult.textContent(); console.log('第一个搜索结果:', title); // 简单的断言 expect(title).toContain('Playwright'); });
it('应该能够处理无结果的情况', async () => { // 输入一个不太可能存在的搜索词 const searchInput = await page.$('#kw'); await searchInput.type('asdfghjkl1234567890特殊测试词'); const searchButton = await page.$('#su'); await searchButton.click(); // 等待无结果提示出现 await page.waitForSelector('.content_none'); const noResultText = await page.textContent('.content_none'); expect(noResultText).toContain('没有找到'); });});
// 运行测试(async () => { const { runTests } = require('./test-runner'); await runTests();})();
复制代码
让测试更健壮:最佳实践
1. 使用选择器的最佳方式
我刚开始用 Playwright 时,犯过过度依赖 CSS 选择器的错误。实际上,Playwright 提供了更好的定位方式:
// 不推荐 - 过于脆弱await page.click('#main > div > form > input.submit');
// 推荐 - 使用文本内容await page.click('text=搜索');
// 推荐 - 使用data-testid属性(需要在开发时添加)await page.click('[data-testid="search-button"]');
// 推荐 - 使用角色定位await page.click('button:has-text("Submit")');
复制代码
2. 处理弹窗和导航
实际测试中经常遇到弹窗和页面跳转:
// 处理弹窗page.on('dialog', async dialog => { console.log(`弹窗消息: ${dialog.message()}`); await dialog.accept(); // 或 dialog.dismiss()});
// 等待新窗口打开const [newPage] = await Promise.all([ page.waitForEvent('popup'), page.click('a[target="_blank"]')]);
// 处理iframeconst frame = page.frame({ name: 'login-frame' });await frame.fill('#username', 'testuser');
复制代码
3. 添加截图和视频功能
调试时截图非常有用:
it('失败时截图', async () => { try { // 测试代码... } catch (error) { // 保存截图和HTML await page.screenshot({ path: 'error-screenshot.png', fullPage: true }); await page.content().then(html => { require('fs').writeFileSync('error-page.html', html); }); throw error; }});
复制代码
常见问题解决
在我使用 Playwright 的过程中,遇到过这些问题:
浏览器启动失败:通常是因为杀毒软件阻止,尝试关闭杀毒软件或添加到白名单。
元素找不到:最常见的问题。使用 page.waitForSelector() 或 page.waitForFunction() 等待元素出现。
跨域问题:Playwright 默认禁用 Web 安全,但如果仍有问题,可以尝试:
await page.goto('https://example.com', { waitUntil: 'networkidle'});
复制代码
中文输入问题:使用 page.type() 而不是 page.fill() 来输入中文。
进阶:整合测试框架
虽然我们可以自己写测试运行逻辑,但使用成熟的测试框架更方便。我推荐 Jest 或 Playwright Test(Playwright 自带的测试运行器)。
安装 Playwright Test:
npm install @playwright/test
复制代码
然后创建 tests/example.spec.js:
const { test, expect } = require('@playwright/test');
test('基础测试', async ({ page }) => { await page.goto('https://www.baidu.com'); await page.type('#kw', 'Playwright'); await page.click('#su'); await page.waitForSelector('.result'); const title = await page.title(); expect(title).toContain('Playwright');});
复制代码
运行测试:
总结
到现在为止,你已经成功搭建了 Playwright 测试环境,并编写了第一个自动化测试脚本。我建议从简单的页面开始练习,逐步尝试更复杂的交互场景。
记住,好的自动化测试不仅仅是让脚本运行起来,还要考虑可维护性、稳定性和可读性。给选择器起有意义的名称,添加清晰的注释,处理好等待和异常——这些习惯会让你的测试代码更加健壮。
当你在实际项目中应用时,可能会遇到我没提到的问题。这时不要灰心,Playwright 有相当完善的官方文档和活跃的社区。祝你测试愉快!
学习资源
下一步,你可以尝试:
测试一个登录流程
处理文件上传下载
模拟移动设备
集成到 CI/CD 流程中
每个步骤都会让你对 Playwright 有更深的理解。开始你的自动化测试之旅吧!
评论