Previous
Day 01 · Getting Started with Playwright
Next
Day 03 · Recording Scripts with Codegen
入门基础
Day 0260-120 minutesPlaywright QA hands-on drill

第 02 天:理解测试文件结构

今日目标

  • 看懂 Playwright 的测试语法。
  • 理解 testexpectpage 的关系。
  • 能写第一个自己的测试。

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

时间模块做什么
0-20 分钟核心概念与词汇读概念表,重点理解 test、expect、fixture、async/await 四个词。
20-45 分钟官方文档阅读读 Writing tests 的 test structure 部分,对照昨天的 example.spec.ts。
45-75 分钟实操练习创建 tests/day02-basic.spec.ts,完成 3 条测试。
75-105 分钟示例代码改写把示例 URL 换成自己的练习网站,补充第 4、5 条测试。
105-120 分钟复盘与作业完成今日问题,逐行解释自己写的测试。

核心概念与词汇

English中文场景用法
test()定义测试用例用于说明该术语在 Playwright 测试中的使用场景。
expect()断言用于说明该术语在 Playwright 测试中的使用场景。
fixture测试夹具用于说明该术语在 Playwright 测试中的使用场景。
page页面对象用于说明该术语在 Playwright 测试中的使用场景。
async / await异步等待用于说明该术语在 Playwright 测试中的使用场景。
spec file测试文件用于说明该术语在 Playwright 测试中的使用场景。
assertion断言用于说明该术语在 Playwright 测试中的使用场景。
locator定位器用于说明该术语在 Playwright 测试中的使用场景。
page.goto()打开页面用于说明该术语在 Playwright 测试中的使用场景。
toHaveTitle()标题断言用于说明该术语在 Playwright 测试中的使用场景。
toHaveURL()URL 断言用于说明该术语在 Playwright 测试中的使用场景。
readable name可读的用例名用于说明该术语在 Playwright 测试中的使用场景。

学习材料

  • 必读:[Writing tests](https://playwright.dev/docs/writing-tests)(First test 与 Test structure 部分)
  • 必读:[Assertions](https://playwright.dev/docs/test-assertions) 的开头部分
  • 选读:[Test isolation](https://playwright.dev/docs/browser-contexts) 中关于 BrowserContext 的说明

重点理解

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

test('has title', async ({ page }) => {
  await page.goto('https://playwright.dev/');
  await expect(page).toHaveTitle(/Playwright/);
});

概念解释:

  • test():定义一个测试用例。
  • async / await:等待异步浏览器操作完成。
  • { page }:Playwright 内置 fixture,每个测试拿到独立的页面。
  • page.goto():打开页面。
  • expect():断言。
  • toHaveTitle():页面标题断言,支持正则表达式。

实操步骤

创建文件:

tests/day02-basic.spec.ts

写 3 个测试:

  1. 打开 Playwright 官网,断言 title。
  2. 查找 Get started 链接。
  3. 点击 Get started 后断言 URL 包含 /docs/intro

示例代码

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

test('open Playwright homepage', async ({ page }) => {
  await page.goto('https://playwright.dev/');
  await expect(page).toHaveTitle(/Playwright/);
});

test('get started link is visible', async ({ page }) => {
  await page.goto('https://playwright.dev/');
  await expect(page.getByRole('link', { name: 'Get started' })).toBeVisible();
});

test('navigate to docs', async ({ page }) => {
  await page.goto('https://playwright.dev/');
  await page.getByRole('link', { name: 'Get started' }).click();
  await expect(page).toHaveURL(/.*docs\/intro/);
});

常见坑

  • 忘记 await,浏览器操作在断言前还没执行完。
  • page 理解成整个浏览器——它只代表一个标签页,浏览器是 browser,上下文是 context
  • expect(await locator.textContent()).toBe(...) 代替 web-first assertion,丢失自动重试。
  • 测试名写得太技术化(如 test case 3),报告里看不出业务意图。
  • 一个测试塞进 10 个断言,失败时定位不了是哪一步出了问题。

今日产出

  • 一个包含 3 条测试用例的 spec 文件。
  • 能解释每一行代码的作用。

今日问题

  1. 为什么 Playwright 的 API 大量使用 await
  2. page 是浏览器页面还是浏览器本身?
  3. expect(page).toHaveURL() 和手动读取 URL 后比较有什么区别?
  4. 测试文件命名为什么常用 .spec.ts
  5. 一个测试用例应该验证几个目标?

复盘要点

  • 测试文件 = test() + expect() + fixture,这是未来 30 天的全部语法基础。
  • 从今天开始,每写一行代码都问自己:这一行在模拟用户做什么?
  • toHaveTitletoHaveURLtoBeVisible 三个断言记成你的第一批武器。

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

新增概念

English中文
code completion代码补全
AI code reviewAI 代码审查
assertion quality断言质量
test intent测试意图

适用场景

让 AI 解释你写的测试每一行做了什么,或者让 AI 检查你的测试缺少哪些断言。注意:AI 解释语法很可靠,但判断业务是否该这样断言时,你需要自己把关。

可复用表达 / 提示词

逐行解释下面这段 Playwright 测试在做什么,并指出哪一行最容易失败。
我的测试目标是「验证用户能从首页跳到文档页」,请检查我的断言是否真正验证了这个目标。

追问加练

  • AI 说“这条断言是多余的”,你会用什么标准判断它说得对不对?
  • 测试意图不清会导致什么维护问题?
  • 哪类断言 AI 无法替你判断正确性?

今日作业

  • 把 3 条测试复制一份,换成任意练习网站(如 TodoMVC)再跑通。
  • 给每条测试写上注释:它在模拟哪个用户动作、验证哪个业务结果。
  • 让 AI 逐行解释你的测试,找出并修正你理解错误的行。

自检清单

Previous
Day 01 · Getting Started with Playwright
Next
Day 03 · Recording Scripts with Codegen