网络监听与响应断言
本教程共 59 篇 · 第 32 篇 · 更新于 2026-08-04 · 约 10 分钟阅读
本节目标:学完能监听到页面发出的每个请求和响应,并针对接口返回写断言,验证前后端是否配合正确。
前两章我们都在「拦」请求。这一章反过来:不拦,就静静看着请求来来回回,然后对它做断言。这在测前后端协作时特别有用——明明点了一下按钮,后台到底返回了啥?
监听请求与响应
Playwright 用事件机制让你订阅网络。page.on('request') 拿到发出的请求,page.on('response') 拿到回来的响应。
// 订阅请求事件,打印方法和地址
page.on('request', request => console.log('>>', request.method(), request.url()));
// 订阅响应事件,打印状态码和地址
page.on('response', response => console.log('<<', response.status(), response.url()));
await page.goto('https://example.com');
Note
request(请求)和response(响应)都是 Playwright 里的对象,能读出方法、URL、状态码、请求头、响应体等信息。
等一个特定的响应
点击按钮后异步发请求,你不知道它啥时候回来。用 page.waitForResponse() 等它,写法有个细节:先拿 Promise,再点按钮,最后 await。
// 注意:这里不写 await,先拿到一个「等待中的承诺」
const responsePromise = page.waitForResponse('**/api/fetch_data');
await page.getByText('Update').click();
// 点完按钮再等它真正回来
const response = await responsePromise;
匹配规则可以是字符串、正则,也可以是一个接收 response 的判断函数:
// 用正则匹配 .jpeg
const p1 = page.waitForResponse(/\.jpeg$/);
// 用函数判断 URL 含某个 token
const p2 = page.waitForResponse(resp => resp.url().includes(token));
Tip先取 Promise 再触发动作,顺序别反。反了就可能错过已经发出的响应,Promise 永远等不到。
对响应做断言
光看到不够,要验证它是对的。下面断言接口状态码是 200,并且返回体里包含预期字段。
import { test, expect } from '@playwright/test';
test('点击后接口返回正确数据', async ({ page }) => {
const responsePromise = page.waitForResponse('**/api/fetch_data');
await page.getByText('Update').click();
const response = await responsePromise;
// 状态码应该是 200
expect(response.status()).toBe(200);
// ok() 更宽松,2xx 都算通过
expect(response.ok()).toBeTruthy();
// 响应体里应该包含预期内容
const body = await response.json();
expect(body).toHaveProperty('name', 'Playwright');
});
Note
status()卡死一个具体状态码,ok()只要求落在 2xx 区间。接口可能返回 200 也可能返回 201 时,用ok()更省心。
在拦截里顺手断言
如果你同时在用 page.route(),也可以在 fulfill 之前读原响应做检查。注意要先 fetch() 把真实响应取回来:
await page.route('**/api/profile', async route => {
const response = await route.fetch(); // 取回真实响应
const json = await response.json();
// 在放行之前先验一遍后端返回
expect(response.status()).toBe(200);
expect(json).toHaveProperty('userId');
await route.fulfill({ response }); // 原样交给页面
});
这种写法适合「既想验接口,又不想改页面行为」的场景:断言归断言,页面拿到的还是真数据。
Warning监听只是「旁观」,不会改动任何请求。想改请求要走上一章的
route拦截。两者可以配合:一边监听做断言,一边拦截做 Mock。
一个完整思路
假设你要测「提交表单后,后台正确记了一笔」。步骤是这样:
- 用
waitForResponse盯住提交接口。 - 填表单、点提交。
- 等响应回来,断言状态码和返回数据。
- 再回到页面,断言界面上也显示了这条记录。
这样前后端两边都验到了,比只点界面踏实得多。
什么时候用监听
我的经验:Mock 用来「造世界」,监听用来「看世界」。
当你怀疑是后端返回错了、而不是界面渲染错了,就打开响应监听,把真实返回打出来看一眼,十有八九能定位问题。
小结
page.on('request')/page.on('response')长期监听所有网络往来,适合排查。- 等特定响应用
page.waitForResponse():先拿 Promise,再触发动作,最后 await,顺序反了就等不到。 - 匹配规则支持 glob 字符串、正则,以及接收 Response 的判断函数。
- 断言状态码用
status()(卡死具体值)或ok()(2xx 都算过)。 - 想验响应体,
await response.json()之后照常用expect断言。 - 在
route里也能断言:route.fetch()取回真响应,验完再fulfill({ response })原样放行。 - 监听只旁观、不改动;要改请求得回到第 30 章的
route拦截。
网络这块到这儿讲完了。下一章解决另一个高频痛点:每条测试都要重新登录,太慢。