进阶掌握
Day 27 - Accessibility and User-Behavior Testing
今日目标
- 理解 role-based locator 与可访问性的关系。
- 学会从用户行为角度写测试。
学习时间安排(60–120 分钟)
| 时间 | 模块 | 做什么 |
|---|---|---|
| 0-20 分钟 | 核心概念与词汇 | 读概念表,重点理解 accessibility tree 与测试的关系。 |
| 20-45 分钟 | 官方文档阅读 | 读 Accessibility 相关文档和键盘操作部分。 |
| 45-75 分钟 | 实操练习 | 为表单页完成 5 项用户视角测试。 |
| 75-105 分钟 | 示例代码改写 | 用键盘操作重写一段鼠标点击流程。 |
| 105-120 分钟 | 复盘与作业 | 完成“用户视角测试原则”,完成今日问题。 |
核心概念与词汇
| English | 中文 | 场景用法 |
|---|---|---|
| accessibility tree | 可访问性树 | Use it when you explain where role and accessible name come from. |
| role | 语义角色 | Use it when you describe an element's purpose, like button or navigation. |
| accessible name | 可访问名称 | Use it when you explain what getByRole matches against. |
| aria | 可访问性标注 | Use it when elements need extra semantics for assistive tech. |
| keyboard navigation | 键盘导航 | Use it when you test Tab order and Enter/Space activation. |
| focus | 焦点 | Use it when you verify which element receives keyboard input. |
| axe-core | 可访问性检查引擎 | Use it when you scan pages for accessibility violations. |
| aria snapshot | ARIA 快照 | Use it when you assert the page's accessibility structure directly. |
| user-visible behavior | 用户可见行为 | Use it when tests should verify what users see and do. |
| implementation detail | 实现细节 | Use it when you avoid asserting CSS classes or internal names. |
学习材料
- 必读:[Accessibility testing](https://playwright.dev/docs/accessibility-testing)(了解 Playwright 的能力边界)
- 必读:[Keyboard](https://playwright.dev/docs/api/class-keyboard) 的 press/Tab 部分
- 选读:[aria snapshot](https://playwright.dev/docs/aria-snapshots)(了解结构断言新能力)
重点理解
重点:
getByRole()依赖页面语义。- 好的可访问性结构会让测试更稳定。
- 测试应该验证用户看得见、点得到、理解得到的行为。
- 不要过度测试实现细节。
可扩展工具:
- axe-core。
- aria snapshot。
- 可访问性断言。
- 键盘导航测试。
实操步骤
为一个表单页面写测试:
- 使用 label 定位输入框。
- 使用 role 定位按钮。
- 使用键盘 Tab 操作。
- 验证错误提示。
- 检查必填字段。
示例代码
import { test, expect } from '@playwright/test';
test('form is operable by keyboard', async ({ page }) => {
await page.goto('/signup');
// Tab 依次聚焦表单字段
await page.keyboard.press('Tab');
await expect(page.getByLabel('Email')).toBeFocused();
await page.keyboard.press('Tab');
await expect(page.getByLabel('Password')).toBeFocused();
await page.keyboard.press('Tab');
await expect(page.getByRole('button', { name: 'Sign up' })).toBeFocused();
// 必填校验:直接提交应显示错误
await page.keyboard.press('Enter');
await expect(page.getByText('Email is required')).toBeVisible();
});
常见坑
- 测试 class 名和内部函数名,UI 一改全红,且与用户行为无关。
- 按钮没有 accessible name(只有图标),getByRole 定位不到——这本身就是可访问性缺陷。
- 用
page.locator('body').click()代替真实交互,绕过焦点和键盘行为。 - 忽略键盘路径:鼠标能点的流程,键盘用户可能卡住。
- 把 axe 扫描当成可访问性测试的全部,忽略人工判断的部分。
今日产出
- 一个更贴近用户行为的表单测试。
- 一份“用户视角测试原则”。
今日问题
- 为什么 role-based locator 能提升测试质量?
- 自动化测试和可访问性有什么关系?
- 为什么不推荐测试内部函数名或 CSS class?
- 键盘操作能发现什么问题?
- 用户行为测试和实现细节测试的边界在哪里?
复盘要点
- 一条铁律:测试能看到的东西,用户也能看到;测试在验证的东西,用户也在意。
- role 定位不到元素,往往不是测试的问题,而是页面语义的问题——顺手提一个可访问性缺陷。
- 键盘路径是被忽略的高价值测试:低成本,却能发现真实用户卡点。
AI 时代扩展:AI 辅助 Playwright 测试
新增概念
| English | 中文 |
|---|---|
| semantic testing | 语义化测试 |
| accessibility audit | 可访问性审计 |
| user journey | 用户旅程 |
适用场景
让 AI 审查测试是否在验证用户行为而非实现细节,或者根据页面描述生成键盘导航测试草稿。
可复用表达 / 提示词
请审查我的测试,指出哪些断言在验证实现细节(class、内部结构)而非用户可见行为,并给出替代方案。
我的注册表单有 3 个字段和 1 个按钮,请生成键盘导航测试草稿,覆盖 Tab 顺序和必填校验。
追问加练
- AI 说“断言 button 的 class 更稳定”,为什么这是错的?
- 键盘路径和鼠标路径的测试结果不一致时,意味着什么?
- AI 能帮你发现哪些可访问性缺陷?哪些它发现不了?
今日作业
- 完成表单页 5 项用户视角测试并跑通。
- 完成“用户视角测试原则”笔记:至少 5 条。
- 让 AI 审查你的测试集,找出验证实现细节的地方并修改。