Playwright 网络监控与 API 测试
本章介绍如何监控浏览器网络流量,以及使用 Playwright 进行独立的 API 测试。
监听网络请求与响应
page.on('request') 监听请求
实例
test('监控网络请求', async ({ page }) => {
const requests = [];
// 监听所有请求
page.on('request', request => {
requests.push({
url: request.url(),
method: request.method(),
postData: request.postData(),
});
});
await page.goto('https://www.runoob.com/');
// 打印所有请求
console.log('页面共发起了', requests.length, '个请求');
requests.forEach(r => console.log(r.method, r.url));
});
const requests = [];
// 监听所有请求
page.on('request', request => {
requests.push({
url: request.url(),
method: request.method(),
postData: request.postData(),
});
});
await page.goto('https://www.runoob.com/');
// 打印所有请求
console.log('页面共发起了', requests.length, '个请求');
requests.forEach(r => console.log(r.method, r.url));
});
page.on('response') 监听响应
实例
test('监控网络响应', async ({ page }) => {
page.on('response', async response => {
// 只关注 API 响应
if (response.url().includes('/api/')) {
console.log('API 状态码:', response.status());
console.log('API URL:', response.url());
}
});
await page.goto('https://www.runoob.com/');
});
page.on('response', async response => {
// 只关注 API 响应
if (response.url().includes('/api/')) {
console.log('API 状态码:', response.status());
console.log('API URL:', response.url());
}
});
await page.goto('https://www.runoob.com/');
});
page.waitForResponse() 等待特定响应
实例
test('等待 API 响应完成', async ({ page }) => {
// 点击按钮前先准备监听 API 响应
const responsePromise = page.waitForResponse(
response => response.url().includes('/api/search') && response.status() === 200
);
// 触发搜索
await page.getByPlaceholder('搜索RUNOOB教程').fill('Playwright');
await page.keyboard.press('Enter');
// 等待 API 响应
const response = await responsePromise;
const data = await response.json();
// 验证 API 返回的数据
expect(data.results.length).toBeGreaterThan(0);
});
// 点击按钮前先准备监听 API 响应
const responsePromise = page.waitForResponse(
response => response.url().includes('/api/search') && response.status() === 200
);
// 触发搜索
await page.getByPlaceholder('搜索RUNOOB教程').fill('Playwright');
await page.keyboard.press('Enter');
// 等待 API 响应
const response = await responsePromise;
const data = await response.json();
// 验证 API 返回的数据
expect(data.results.length).toBeGreaterThan(0);
});
Console 消息监听
实例
test('监听控制台错误', async ({ page }) => {
const consoleErrors = [];
// 监听 console 消息
page.on('console', msg => {
if (msg.type() === 'error') {
consoleErrors.push(msg.text());
}
});
await page.goto('https://www.runoob.com/');
// 断言页面没有 JavaScript 错误
expect(consoleErrors).toHaveLength(0);
});
const consoleErrors = [];
// 监听 console 消息
page.on('console', msg => {
if (msg.type() === 'error') {
consoleErrors.push(msg.text());
}
});
await page.goto('https://www.runoob.com/');
// 断言页面没有 JavaScript 错误
expect(consoleErrors).toHaveLength(0);
});
ConsoleMessage 类型
| 类型 | 对应方法 |
|---|---|
'log' | console.log() |
'error' | console.error() |
'warning' | console.warn() |
'info' | console.info() |
'debug' | console.debug() |
API 测试(request fixture)
Playwright 的 request fixture 允许你不通过浏览器直接发送 HTTP 请求。
这非常适合在测试前后准备或清理服务端状态。
发送 GET 请求
实例
test('API GET 请求', async ({ request }) => {
const response = await request.get('https://jsonplaceholder.typicode.com/posts/1');
// 验证响应状态
expect(response.status()).toBe(200);
// 获取 JSON 数据
const data = await response.json();
expect(data.id).toBe(1);
expect(data).toHaveProperty('title');
});
const response = await request.get('https://jsonplaceholder.typicode.com/posts/1');
// 验证响应状态
expect(response.status()).toBe(200);
// 获取 JSON 数据
const data = await response.json();
expect(data.id).toBe(1);
expect(data).toHaveProperty('title');
});
发送 POST 请求
实例
test('API POST 请求', async ({ request }) => {
const response = await request.post('https://jsonplaceholder.typicode.com/posts', {
data: {
title: 'RUNOOB 教程',
body: 'Playwright API 测试示例',
userId: 1,
},
});
expect(response.status()).toBe(201);
const data = await response.json();
expect(data.title).toBe('RUNOOB 教程');
});
const response = await request.post('https://jsonplaceholder.typicode.com/posts', {
data: {
title: 'RUNOOB 教程',
body: 'Playwright API 测试示例',
userId: 1,
},
});
expect(response.status()).toBe(201);
const data = await response.json();
expect(data.title).toBe('RUNOOB 教程');
});
配置 baseURL 和认证头
实例
// 文件路径:playwright.config.ts
export default defineConfig({
use: {
// API 请求的基础 URL
baseURL: 'https://api.runoob.com',
// 默认请求头
extraHTTPHeaders: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
},
});
export default defineConfig({
use: {
// API 请求的基础 URL
baseURL: 'https://api.runoob.com',
// 默认请求头
extraHTTPHeaders: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json',
},
},
});
API + 浏览器组合测试
在实际项目中,常常在操作浏览器前后使用 API 进行状态管理。
实例
test('API 准备数据 + 浏览器验证', async ({ request, page }) => {
// 步骤 1:通过 API 创建一条测试数据
const response = await request.post('/api/todos', {
data: { title: 'RUNOOB 测试任务', completed: false },
});
const todo = await response.json();
// 步骤 2:在浏览器中验证数据已显示
await page.goto('/todos');
await expect(page.getByText('RUNOOB 测试任务')).toBeVisible();
// 步骤 3:通过 API 清理数据
await request.delete(`/api/todos/${todo.id}`);
});
// 步骤 1:通过 API 创建一条测试数据
const response = await request.post('/api/todos', {
data: { title: 'RUNOOB 测试任务', completed: false },
});
const todo = await response.json();
// 步骤 2:在浏览器中验证数据已显示
await page.goto('/todos');
await expect(page.getByText('RUNOOB 测试任务')).toBeVisible();
// 步骤 3:通过 API 清理数据
await request.delete(`/api/todos/${todo.id}`);
});
API 测试比浏览器操作快得多,适合用于数据准备和清理。将 API 和浏览器操作结合使用,可以大大提高测试的效率和可靠性。
