Previous
Day 07 · Advanced Locators: Filtering and Chaining
Next
Day 09 · Auto-waiting and Timeouts
定位断言
Day 0860-120 minutesPlaywright QA hands-on drill

第 08 天:断言 Assertions

今日目标

  • 掌握常用 web-first assertions。
  • 知道什么时候断言页面、元素、URL、文本、数量。

学习时间安排(60–120 分钟)

时间模块做什么
0-20 分钟核心概念与词汇读概念表,区分页面断言、元素断言、数量断言。
20-45 分钟官方文档阅读读 Assertions 文档的通用断言和 locator 断言部分。
45-75 分钟实操练习给 Day 5 的 smoke tests 增加 8 种断言。
75-105 分钟示例代码改写把普通断言替换成 web-first assertion 并说明差异。
105-120 分钟复盘与作业记录最常用的 3 个断言,完成今日问题。

核心概念与词汇

English中文场景用法
web-first assertion网页优先断言用于说明该术语在 Playwright 测试中的使用场景。
toBeVisible()可见断言用于说明该术语在 Playwright 测试中的使用场景。
toBeEnabled()可用断言用于说明该术语在 Playwright 测试中的使用场景。
toHaveText()文本全等断言用于说明该术语在 Playwright 测试中的使用场景。
toContainText()包含文本断言用于说明该术语在 Playwright 测试中的使用场景。
toHaveCount()数量断言用于说明该术语在 Playwright 测试中的使用场景。
toHaveAttribute()属性断言用于说明该术语在 Playwright 测试中的使用场景。
toHaveURL()URL 断言用于说明该术语在 Playwright 测试中的使用场景。
toHaveTitle()标题断言用于说明该术语在 Playwright 测试中的使用场景。
auto-retry自动重试用于说明该术语在 Playwright 测试中的使用场景。
positive assertion正向断言用于说明该术语在 Playwright 测试中的使用场景。
negative assertion反向断言用于说明该术语在 Playwright 测试中的使用场景。

学习材料

  • 必读:[Assertions](https://playwright.dev/docs/test-assertions)
  • 必读:[Auto-waiting](https://playwright.dev/docs/actionability) 中关于断言重试的说明
  • 选读:[Expect API](https://playwright.dev/docs/api/class-playwrightassertions)(浏览一遍可用断言清单)

重点理解

常用断言:

await expect(page).toHaveTitle(/Playwright/);
await expect(page).toHaveURL(/.*intro/);
await expect(locator).toBeVisible();
await expect(locator).toBeEnabled();
await expect(locator).toHaveText('Success');
await expect(locator).toContainText('Success');
await expect(locator).toHaveCount(3);
await expect(locator).toHaveAttribute('href', '/docs/intro');

注意:

  • Playwright 的 web-first assertions 会自动重试。
  • 不要用 expect(await locator.textContent()).toBe(...) 替代 web-first assertion,除非有明确原因。
  • 断言应该表达业务期望,而不是实现细节。

实操步骤

为 Day 5 的 smoke tests 增加断言:

  • 标题断言。
  • URL 断言。
  • 按钮可见断言。
  • 文本断言。
  • 列表数量断言。

示例代码

import { test, expect } from '@playwright/test';

test('order page shows correct summary', async ({ page }) => {
  await page.goto('/orders/42');
  await expect(page).toHaveTitle(/Order #42/);
  await expect(page).toHaveURL(/\/orders\/42/);

  const status = page.getByRole('status');
  await expect(status).toBeVisible();
  await expect(status).toContainText('Paid');

  await expect(page.getByRole('listitem')).toHaveCount(3);
  await expect(page.getByRole('button', { name: 'Ship' })).toBeEnabled();
});

常见坑

  • expect(await locator.textContent()).toBe('Success') 手动取值比较,丢掉自动重试,遇到慢加载就 flaky。
  • toBeTruthy() 类断言包着 isVisible(),报错信息看不出页面状态。
  • toHaveTexttoContainText 混用:完整校验用前者,部分匹配用后者。
  • 断言写实现细节(如 class 名、DOM 结构),UI 重构后全红。
  • 只写操作不写断言,测试“跑通”却什么都没验证。

今日产出

  • 至少 8 个不同断言示例。
  • 记录哪个断言最常用。

今日问题

  1. Web-first assertion 和普通 assertion 有什么区别?
  2. 为什么 toBeVisible() 比检查 CSS class 更好?
  3. toHaveTexttoContainText 有什么区别?
  4. toHaveCount 适合哪些场景?
  5. 断言过多和过少分别有什么问题?

复盘要点

  • 断言是测试的“价值部分”:没有断言的测试只是操作脚本。
  • 好的断言描述用户看到的结果(可见、可点、文案正确、数量正确),而不是 DOM 长相。
  • 记住自动重试机制:断言失败前会持续重试到超时,这是 Playwright 稳定性的根基之一。

AI 时代扩展:AI 辅助 Playwright 测试

新增概念

English中文
assertion coverage断言覆盖
expected result预期结果
over-assertion过度断言
assertion strategy断言策略

适用场景

让 AI 检查你的测试“操作了很多但验证了什么”,或者根据需求描述生成候选断言。注意:哪些业务结果是关键验证点,必须由 QA 自己判断。

可复用表达 / 提示词

我的测试只做了点击和填写,请根据「提交后应显示成功提示并跳转到列表页」这个预期,补充最少且必要的断言。
下面这条断言验证的是实现细节还是用户可见结果?请给出理由和替代方案。

追问加练

  • AI 建议断言某个 class 名,你会接受吗?为什么?
  • 一条测试里 10 个断言和 2 个断言,哪个更难维护?
  • AI 无法替你判断的断言是什么类型的?

今日作业

  • 给 Day 5 的 smoke.spec.ts 每条测试补充至少 2 个业务断言。
  • 整理“断言速查表”:8 个常用断言 + 场景 + 一个反面例子。
  • 让 AI 审查你的断言,找出验证实现细节的地方并修改。

自检清单

Previous
Day 07 · Advanced Locators: Filtering and Chaining
Next
Day 09 · Auto-waiting and Timeouts