首页 / Playwright 入门教程 / 网络监听与响应断言

Playwright 入门教程

网络监听与响应断言

本教程共 59 篇 · 第 32 篇 · 更新于 2026-08-04 · 约 10 分钟阅读

Playwright网络监听responsewaitForResponse响应断言请求日志

本节目标:学完能监听到页面发出的每个请求和响应,并针对接口返回写断言,验证前后端是否配合正确。

前两章我们都在「拦」请求。这一章反过来:不拦,就静静看着请求来来回回,然后对它做断言。这在测前后端协作时特别有用——明明点了一下按钮,后台到底返回了啥?

监听请求与响应

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。

一个完整思路

假设你要测「提交表单后,后台正确记了一笔」。步骤是这样:

  1. waitForResponse 盯住提交接口。
  2. 填表单、点提交。
  3. 等响应回来,断言状态码和返回数据。
  4. 再回到页面,断言界面上也显示了这条记录。

这样前后端两边都验到了,比只点界面踏实得多。

什么时候用监听

我的经验: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 拦截。

网络这块到这儿讲完了。下一章解决另一个高频痛点:每条测试都要重新登录,太慢。