Playwright 测试框架:多浏览器自动化与网络拦截
Playwright 自动化浏览器测试入门:多浏览器自动化与网络拦截
Playwright 是一款由微软开源的端到端测试框架,它能够通过单一 API 自动操控 Chromium、Firefox 和 WebKit 浏览器,并且内置了强大的网络拦截与控制能力。本教程将带你从零开始,掌握 Playwright 的多浏览器执行与网络模拟技巧。
为什么选择 Playwright?
- 跨浏览器一致性:一套代码,同时测试 Chrome、Edge、Firefox、Safari。
- 自动等待机制:内置智能等待,无需手动添加
sleep,减少测试不稳定。 - 强大的网络控制:可以拦截、修改、模拟网络请求与响应。
- 移动端模拟:轻松模拟移动设备、地理位置、权限等。
- 多语言支持:JavaScript/TypeScript、Python、C#、Java。
环境准备
首先确保已安装 Node.js(版本 14 以上)。创建项目文件夹并初始化:
mkdir playwright-demo && cd playwright-demo
npm init -y
安装 Playwright 和内置浏览器:
npm install @playwright/test
npx playwright install
npx playwright install 会下载 Chromium、Firefox 和 WebKit 三个浏览器内核,下载一次即可。
编写第一个多浏览器测试
Playwright 的测试模块 @playwright/test 提供了 test 和 expect,并且可以轻松配置多浏览器项目。
创建 tests/example.spec.js:
const { test, expect } = require('@playwright/test');
test('验证页面标题', async ({ page }) => {
await page.goto('https://example.com');
// 自动等待标题变为指定内容
await expect(page).toHaveTitle(/Example Domain/);
});
在项目根目录创建配置文件 playwright.config.js:
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
testDir: './tests',
timeout: 30 * 1000,
retries: 1,
use: {
headless: true,
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
projects: [
{ name: 'Chromium', use: { browserName: 'chromium' } },
{ name: 'Firefox', use: { browserName: 'firefox' } },
{ name: 'WebKit', use: { browserName: 'webkit' } },
],
});
现在运行测试,Playwright 会自动在三个浏览器中执行:
npx playwright test
运行结果会显示每个浏览器的测试通过情况。如果只想在单个浏览器上运行,可以使用 --project 参数:
npx playwright test --project=Chromium
多浏览器中的差异化操作
有时不同浏览器的行为可能不一致,你可以在测试中根据浏览器类型编写条件代码。
test('多浏览器条件执行', async ({ page, browserName }) => {
await page.goto('https://example.com');
if (browserName === 'webkit') {
// 只在 WebKit (Safari) 中执行的逻辑
console.log('Running WebKit specific check');
}
// 通用断言
await expect(page.locator('h1')).toBeVisible();
});
网络拦截基础
Playwright 提供了 page.route() 方法,可以拦截、修改或mock任何网络请求。
拦截并修改请求
假设你想阻止图片加载以加快测试速度:
test('阻止图片加载', async ({ page }) => {
// 拦截所有图片请求,直接返回空响应
await page.route('**/*.{png,jpg,jpeg,gif,svg}', route => route.abort());
await page.goto('https://example.com');
// 页面中的图片都不会加载
});
route.abort() 中止请求,route.fulfill() 可以提供自定义响应。
模拟 API 响应
在测试中,我们经常需要 mock 后端接口返回数据:
test('模拟用户接口数据', async ({ page }) => {
// 拦截 GET 请求 /api/user,返回模拟数据
await page.route('**/api/user', route => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ name: 'Test User', age: 30 })
});
});
await page.goto('https://your-app.com/profile');
// 页面将显示模拟的用户数据
});
route.fulfill 可以自定义状态码、头信息和响应体。
修改请求头
有些场景需要为所有请求添加认证头:
test('为请求添加自定义头', async ({ page }) => {
await page.route('**/*', route => {
const headers = {
...route.request().headers(),
'X-Custom-Token': 'my-secret-token'
};
route.continue({ headers });
});
await page.goto('https://example.com');
// 所有请求都会携带自定义头
});
拦截并修改响应
你可以捕获实际响应,修改内容后再返回给页面:
test('修改响应内容', async ({ page }) => {
await page.route('**/api/data.json', async route => {
const response = await route.fetch();
let body = await response.text();
// 将响应中的 "old" 替换为 "new"
body = body.replace(/old/g, 'new');
route.fulfill({
status: response.status(),
headers: response.headers(),
body
});
});
await page.goto('https://your-app.com');
});
高级网络控制:等待特定网络请求
你可以等待某个特定的网络请求完成,并检查其细节。
test('等待请求并检查数据', async ({ page }) => {
const [response] = await Promise.all([
page.waitForResponse('**/api/products'),
page.goto('https://your-store.com')
]);
const json = await response.json();
expect(json.length).toBeGreaterThan(0);
});
结合网络拦截与等待,可以构建出非常可靠的测试场景。
实战:完整测试示例
假设有一个天气查询页面,我们模拟天气 API 返回固定数据,并测试页面显示。
test('天气查询功能测试', async ({ page }) => {
// 拦截天气 API
await page.route('**/api/weather**', route => {
route.fulfill({
status: 200,
body: JSON.stringify({
city: '北京',
temperature: 28,
condition: '晴朗'
})
});
});
await page.goto('https://weather-app.com');
await page.fill('#city-input', '北京');
await page.click('#search-btn');
// 断言页面显示了模拟的数据
await expect(page.locator('.temperature')).toHaveText('28°C');
await expect(page.locator('.condition')).toHaveText('晴朗');
});
小结
Playwright 提供了开箱即用的多浏览器支持和极其灵活的网络拦截能力。通过本教程,你学会了:
- 配置并运行跨浏览器的自动化测试
- 使用
page.route进行请求拦截、修改和 mock - 结合网络控制构建稳定的端到端测试
你可以将这些技术用于接口模拟、加载优化测试、错误场景复现等众多场景。继续探索 Playwright 的更多高级特性,如生成代码、追踪测试执行、CI/CD 集成等,让你的测试体系更加健壮。
下一步推荐学习:
- Playwright 官方文档
- 使用 Playwright Test Runner 组织大型测试套件
- 截图与视频录制的高级配置