大数跨境

Postman与Playwright集成:把UI和API放在一起测

Postman与Playwright集成:把UI和API放在一起测 51Testing软件测试网
2026-11-10
5
导读:Postman Application Inventory把Playwright UI测试和API契约校验接在一起,基于真实API调用分析UI行为,揪出契约漂移、静默报错、覆盖缺口。

测一个现代应用,你既要验证用户在浏览器里看到的东西,也得管住背后 API 到底在干什么。

但这里有个我踩过无数次的坑:UI 测试全绿,API 契约却在背地里悄悄崩了;或者 API 测试一切正常,前端压根就调错了接口。

这篇文章里,我会带你把 Postman 新上线的 Application Inventory 走一遍——它把 Playwright 的 UI 测试和 Postman 的 API 契约校验接在了一起,正好补上这个缺口。

你会看到怎么基于真实的 API 调用来分析 UI 的实际行为,把传统测试方式漏掉的问题揪出来。

示例应用:用户权限管理

我用一个简单的用户权限管理应用来演示整套流程,它负责用户访问控制相关的 CRUD 操作。这个应用管四类核心权限:

— Read —— 查看用户数据和权限
— Write —— 新建用户并分配权限
— Update —— 修改已有用户的权限
— Delete —— 删除用户、回收权限

前端是常见的 React/JavaScript 技术栈,通过调用 REST API 来管理这些权限。

前置条件:

请先确认你的应用已经关联到某个 workspace。

第一步:用 Agent Mode 生成 Playwright 测试

这一步就是 Postman 的 Agent Mode 真正好用的地方。你完全不用从零手写 Playwright 测试,Agent Mode 可以直接照着你的前端代码帮你生成。

我的用户权限 collection 已经在 Postman 里建好了,于是我打开 Agent Mode,敲了这么一句提示词:

Generate Playwright UI tests based off my frontend code.

Agent Mode 给我生成的东西:

import { test as baseTest, expect } from '@playwright/test';
import { attachNetworkCapture } from 'postman-playwright';

const test = attachNetworkCapture(baseTest);

/**
 * UI tests for managing a user's permissions end-to-end.
 *
 * Validates that an admin can:
 *   - Select a user and view their currently granted permissions.
 *   - Toggle permissions on and off.
 *   - Save the new permission set and see a success notification.
 */

test.describe('User Permissions management UI', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/');

    const userCards = page.locator('.user-card');
    await expect(userCards.first()).toBeVisible();
    await userCards.first().click();

    await expect(page.locator('.permission-item').first()).toBeVisible();
  });

  test('reflects the selected user in the permissions header', async ({ page }) => {
    const userName = (await page
      .locator('.user-card.selected .user-name')
      .first()
      .textContent())?.trim();
    expect(userName?.length ?? 0).toBeGreaterThan(0);

    await expect(
      page.getByRole('heading', { name: new RegExp(`Permissions for ${userName}`, 'i') })
    ).toBeVisible();
  });

  test('toggling a permission and saving shows a success notification', async ({ page }) => {
    const firstToggle = page.locator('.toggle-switch').first();
    await firstToggle.click();

    const saveBtn = page.getByRole('button', { name: /Save Permissions/i });
    await expect(saveBtn).toBeEnabled();
    await saveBtn.click();

    // Wait for the save button to return to normal state (indicating save completed)
    await expect(saveBtn).toContainText('Save Permissions', { timeout: 10000 });
    await expect(saveBtn).not.toBeDisabled();
  });
这里的关键点在于:Agent Mode 读得懂你的代码,生成出来的 UI 测试跑的用户流程,正好就是我这些 API 支持的流程。UI 测试和 API 契约能这样对齐,后面的步骤才真正有价值。
第二步:用 postman app init 初始化

Playwright 测试生成好了,接下来我跑 Postman CLI 的初始化命令:

postman app init

这条命令会一路问我几个配置问题:

选择 Collection:
? Which collections should we validate against?
❯ ✓ User Management API
选择环境:
? Select the default environment? 
  Local Development
❯ User Permissions API - Local 1  
  Production
测试脚本配置:
? What command runs your UI tests?
❯ npx playwright test
  Custom command...

CLI 自己识别到了我的 package.json,然后建议我用 npx playwright test。

输出配置:
✓ Application Inventory initialized successfully!
✓ Created postman.config.cjs
✓ Added postman-playwright plugin to package.json
✓ Environment variables configured

初始化过程生成了一个 postman.config.cjs 文件,上面这些信息全写在里面:

 // The command to run before analysis (e.g. your test suite).
    command: 'npx playwright test',

    // Targets define which collections and environment to use for analysis.
    targets: {
        default: {
            environment: 'User Permissions API - Local 1',
            collections: ['User Permissions API-1'],
        }
第三步:用 postman application test 跑测试

好戏就在这儿。Postman CLI 不是把 Playwright 测试单独跑一遍,而是把 UI 测试和 API 校验一起编排起来:
CI=true postman application test

CI=true 这个标志告诉 Postman 以持续集成模式运行,结果不光打到终端,还会存进 Application Inventory。

终端里我看到的输出:
talia.kohan@postman.com@PM-L2Y6LJPHFX user-permissions % CI=true postman application test[app:test] Loading local collection: /Users/talia.kohan@postman.com/Postman/user-permissions/postman/collections/User Permissions API-1[app:test] Loading local environment: /Users/talia.kohan@postman.com/Postman/user-permissions/postman/environments/User Permissions API - Local 1.environment.yaml[app:test] Starting command(primary task): npx playwright testRunning 4 tests using 1 worker  ✓  1 …s:28:3 › User Permissions management UI › reflects the selected user in the permissions header (932ms)  ✓  2 … User Permissions management UI › toggling a permission and saving shows a success notification (1.6s)  ✓  3 ….spec.ts:87:3 › User Permissions management UI › Save button shows a loading state while saving (2.2s)4 passed (10.4s)[app:test] Command finished. Running test tasks...→ Running Postman tests against 43 captured requests (20 deduplicated)  ┌ chrome › user-permissions.spec.ts › User Permissions management UI › reflects the selected user in the permissions header  │ UI Test: passed  |  duration: 773ms  └ 5 matched ★ 0 not matched ★ 5 total  ┌ chrome › user-permissions.spec.ts › User Permissions management UI › toggling a permission and saving shows a success notification  │ UI Test: passed  |  duration: 1496ms  └ 6 matched ★ 0 not matched ★ 6 total  ┌ chrome › user-permissions.spec.ts › User Permissions management UI › Save button shows a loading state while saving  │ UI Test: passed  |  duration: 2091ms  └ 6 matched ★ 0 not matched ★ 6 total┌────────────────────┬────────────────────────────────────┐│        collections │  1                                 │├────────────────────┼────────────────────────────────────┤│              tests │  4                                 │├────────────────────┼────────────────────────────────────┤│  requests captured │  43                                │├────────────────────┼────────────────────────────────────┤│   requests matched │  23 matched  ★  0 not matched      │├────────────────────┼────────────────────────────────────┤│         assertions │  23 total  ★  0 passed  ★ 0 failed │└────────────────────┴────────────────────────────────────┘[app:test:analytics] remote ingest finished✓ Run results were stored in Postman.

浏览器窗口里,我的 Playwright 测试实时跑着;同时 Postman 在旁边把这些 UI 交互过程中发出的每一次 API 调用都抓下来、校验掉。

第四步:Application Inventory —— 全局视角

真正的威力在 Application Inventory 的统一看板上。测试跑完之后,这次 CI/CD 的结果我能一眼看全。
CI/CD 测试结果
— 测试执行:Playwright 测试全部通过
— API 调用:23 个
— 浏览器覆盖:测试在 Chrome 中运行(按配置来)

每次代码变更触发流水线,我都能拿到:

— 通过 Playwright 完成的自动化 UI 测试
— 通过 Postman collection 完成的 API 契约校验
— 显示哪些接口被跑到的覆盖率报告
— UI 行为偏离文档化 API 时的漂移检测
为什么这套打法管用

我的经验是,这种一体化测试能抓住三类传统测试抓不到的问题:
契约漂移

API 文档说的是一套,UI 干的又是另一套。前端代码调了没写进文档的接口,或者请求格式跟预期对不上,Application Inventory 都能发现。

后端静默报错

只要 DOM 元素还在,哪怕 API 返回的是错误响应,你的 UI 测试也可能照样通过。在 UI 测试过程中顺手校验 API 响应,这类静默失败就跑不掉了。

API 覆盖缺口

你的 API 测试可能很全,但只出现在某些特定 UI 流程里的边界场景,它照样漏。这套方法能保证 API 测试覆盖的是真实使用模式。

契约测试的一次升级

Postman 和 Playwright 的这次集成,是契约测试的一次重要演进。传统契约测试验证的是 API 是否符合文档中声明的规范,但它通常是脱离真实用户流程、孤立进行的。

我们照样跑你的契约,只是校验和 Playwright 测试同时发生。 API 测试(Postman collection 断言)加上 UI 测试(Playwright 测试),两边合起来校验的是真实使用模式,而不是理论上应该发生的 API 调用。
接下来你可以怎么做

UI 测试和 API 校验打通,意味着测试思路在往更贴近真实的方向走。不再孤立地测单个组件,而是验证完整的用户旅程——从浏览器交互一路管到后端响应。

拿你自己的应用试一遍:
— 给一条关键用户流程写个简单的 Playwright 测试
— 把这条流程用到的 API 在 Postman collection 里写好
— 跑 postman app init 把两边接起来
— 执行 postman application test,然后看结果

你多半会发现:前端偷偷调了一些你根本不知道的接口,或者文档化的 API 和实际用法之间对不上。

E N D

【声明】内容源于网络
0
0
51Testing软件测试网
博为峰51Testing软件测试网提供各种线上招聘、线上课程等网络服务,出版软件测试系列丛书及电子杂志,组织线上技术交流活动;同时还举办多种线下公益活动,如软件测试沙龙、软件测试专场招聘会等。
内容 3996
粉丝 0
51Testing软件测试网 博为峰51Testing软件测试网提供各种线上招聘、线上课程等网络服务,出版软件测试系列丛书及电子杂志,组织线上技术交流活动;同时还举办多种线下公益活动,如软件测试沙龙、软件测试专场招聘会等。
总阅读12.7k
粉丝0
内容4.0k