返回 AI Coding 培训
实操 09/11

Playwright UI 自动化测试实操:只验证关键行为,不测试整个页面

5 分钟
AI编程AI工具效率方法

第四天下午,我让同学们给 FizzBuzz 页面补 UI 自动化。有人一上来就验证页面标题、背景色、每一个按钮和几十组输入,最后用例比页面代码还长。这个场景很适合说明:UI 测试不是把整个页面重新描述一遍,而是从用户视角守住最值得保护的行为。

对于只有输入、计算、结果三个元素的课堂页面,一条主流程冒烟测试已经能证明页面与计算模块连通。真实商城当然不一定只有一条,它还可能需要注册登录、下单和权限等关键链路。数量由风险决定,不由口诀决定。

前置条件

  • 页面已经能通过固定命令启动,并知道实际访问地址。
  • 纯计算规则已经有单元测试,不把几十组逻辑组合搬到浏览器层。
  • 当前代码已提交 Git,测试改动可以单独比较。
  • Node.js 与项目包管理器可用。

在项目中初始化 Playwright:

pnpm create playwright

选择 TypeScript 或 JavaScript,并安装浏览器。初始化后先运行示例命令,确认环境本身可用:

pnpm exec playwright test

第一步:让测试访问真实运行页面

测试目标应该是 HTTP 地址,而不是直接打开本地 HTML 文件。可以先手工启动项目,也可以在 Playwright 配置中使用 webServer,让测试命令启动开发服务器并等待地址可用。

开始前确认三件事:启动命令、终端实际端口、测试使用的 baseURL。课堂里大量“元素找不到”并不是定位器问题,而是测试访问了旧端口、旧进程或错误页面。

第二步:把用例写成准备、执行、验证

一个 FizzBuzz 关键行为可以这样表达:

import { expect, test } from "@playwright/test"

test("用户输入 15 后看到 fizz buzz", async ({ page }) => {
  await page.goto("/")
  await page.getByLabel("请输入数字").fill("15")
  await page.getByRole("button", { name: "计算" }).click()
  await expect(page.getByRole("status")).toHaveText("fizz buzz")
})

进入页面并准备输入,是准备;填写和点击,是执行;检查用户可见结果,是验证。用例名称也直接表达业务行为,失败时不用先读实现才能理解。

第三步:优先选择用户可见的定位方式

Playwright 官方建议优先使用角色、名称、标签和测试标识等稳定契约。不要依赖长 CSS 路径或 DOM 层级,因为样式重构会让测试在行为没变时也失败。

推荐顺序可以是:

  1. 按角色和可访问名称定位按钮、标题、对话框。
  2. 按标签定位输入框。
  3. 按用户可见文字定位稳定内容。
  4. 在没有合适语义时增加明确的 test id。

好的 UI 测试会反过来推动页面具备更清楚的标签和可访问名称。

第四步:保持用例隔离

每条测试都应该能够独立运行,不依赖上一条留下的登录状态、订单或页面顺序。Playwright 会为测试创建隔离的浏览器上下文,但应用数据仍需要你管理。

如果用例会写入后端,使用独立测试账号、唯一数据前缀、fixture 或专用测试环境。不要清空共享数据库,更不能让自动化连接生产数据。清理动作只处理本用例创建的记录。

第五步:先调试一条,再扩展回归

开发时可以使用 headed 或 UI 模式观察浏览器行为;提交前再用无头模式运行固定命令。失败时先看报错中的定位器、截图和 trace,确认页面真实状态,再决定是否改测试或代码。

Agent 临时打开浏览器并告诉你“已经验证”,只是一轮探索。只有测试文件、配置和命令进入仓库,下一位同学或下一次修改才能重复得到同样证据。

成功标准

  • 一条命令可以启动或连接正确页面并运行测试。
  • 用例按准备、执行、验证组织,名称能说明业务行为。
  • 定位器优先使用角色、标签或稳定测试标识。
  • 纯逻辑组合留在单元测试,UI 只保护关键用户链路。
  • 每条用例可独立运行,不依赖执行顺序。
  • 失败时保存了足以定位问题的截图或 trace。

常见报错与处理

页面无法访问

先核对启动命令、实际端口和 baseURL。确认旧服务是否占用端口,再检查 webServer 等待的 URL 是否与页面一致。

strict mode 提示匹配多个元素

说明定位条件不够明确。补充正确的可访问名称或缩小到稳定容器,不要用 nth 暂时掩盖页面语义问题。

本地通过,批量运行失败

重点检查共享账号、残留数据、时间依赖和测试顺序。让单条用例重复运行,并为测试数据增加唯一标识。

页面样式一改测试全坏

如果用例依赖 CSS 类和 DOM 层级,改用角色、标签或 test id。测试应耦合用户行为,而不是视觉实现细节。

课后练习

为自己的项目选择一条真正影响交付的主流程,写成一条 Playwright 测试。故意改坏按钮名称、计算结果和访问端口,分别观察失败信息能否指出页面契约、业务结果和环境配置问题。最后写一句说明:这条测试保护了什么风险,为什么值得长期保留。

官方资料

AI编程AI工具效率方法