编写测试

介绍

Playwright 测试非常简单,它们:

  • 执行操作,并

  • 对照期望断言状态。

在执行操作之前无需等待任何内容:Playwright 会自动等待一系列的 【可操作性】 检查通过,然后才执行每个操作。

在进行检查时,也无需担心竞争条件——Playwright 的断言被设计成能够描述需要最终满足的期望。

就是这么简单!这些设计选择使得 Playwright 用户完全不必担心不稳定的超时和竞态检查。

你将学到:

  • 如何编写第一个测试

  • 如何执行操作

  • 如何使用断言

  • 如何在隔离环境中运行测试

  • 如何使用测试钩子

第一个测试

请查看以下示例,了解如何编写测试。

tests/example.spec.ts
import { test, expect } from '@playwright/test';

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

  // Expect a title "to contain" a substring.
  await expect(page).toHaveTitle(/Playwright/);
});

test('get started link', async ({ page }) => {
  await page.goto('https://playwright.dev/');

  // Click the get started link.
  await page.getByRole('link', { name: 'Get started' }).click();

  // Expects page to have a heading with the name of Installation.
  await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible();
});
typescript

在 VS Code 中使用 JavaScript 时,在每个测试文件的开头添加 // @ts-check 以启用自动类型检查。

操作

导航

大多数测试将从导航页面到 URL 开始。之后,测试就可以与页面元素进行交互。

await page.goto('https://playwright.dev/');
typescript

Playwright 会等待页面达到加载状态后再继续。了解更多关于 page.goto() 的选项。

交互

执行操作从定位元素开始。Playwright 使用 Locator API 来进行元素定位。Locator 代表了一种在任何时刻查找页面元素的方式,了解更多关于可用的 【不同类型】 定位器。Playwright 会在执行操作前等待元素 【可操作】,因此无需等待元素变得可用。

// Create a locator.
const getStarted = page.getByRole('link', { name: 'Get started' });

// Click it.
await getStarted.click();
typescript

在大多数情况下,可以简化为一行代码:

await page.getByRole('link', { name: 'Get started' }).click();
typescript

基本操作

这是 Playwright 中最常见操作的列表。请注意,还有很多其他操作,确保查看 Locator API 部分,了解更多内容。

操作 描述

locator.check()

勾选输入框

locator.click()

点击元素

locator.uncheck()

取消勾选输入框

locator.hover()

将鼠标悬停在元素上

locator.fill()

填充表单字段,输入文本

locator.focus()

聚焦元素

locator.press()

按下单个键

locator.setInputFiles()

选择要上传的文件

locator.selectOption()

选择下拉框中的选项

断言

Playwright 包含以 expect 函数形式提供的 【测试断言】。要进行断言,调用 expect(value) 并选择反映期望的匹配器。

有许多通用的匹配器,如 toEqualtoContaintoBeTruthy 等,可以用来断言任何条件。

expect(success).toBeTruthy();
typescript

Playwright 还包括 async 匹配器,它们会等待直到满足期望的条件。使用这些匹配器可以使测试更稳定和可靠。例如,下面的代码会等待直到页面的标题包含 "Playwright":

await expect(page).toHaveTitle(/Playwright/);
typescript

以下是最常用的异步断言列表。请注意,还有【更多】可以学习的断言:

断言 描述

expect(locator).toBeChecked()

输入框已被勾选

expect(locator).toBeEnabled()

控件已启用

expect(locator).toBeVisible()

元素可见

expect(locator).toContainText()

元素包含文本

expect(locator).toHaveAttribute()

元素具有某个属性

expect(locator).toHaveCount()

元素列表具有指定长度

expect(locator).toHaveText()

元素匹配文本

expect(locator).toHaveValue()

输入元素具有值

expect(page).toHaveTitle()

页面有指定标题

expect(locator).toHaveValue()

页面有指定 URL

测试隔离

Playwright Test 基于 【测试夹具】 的概念,例如 【内置的 page 夹具】,它会传递到你的测试中。由于浏览器上下文的存在,【页面在测试之间是隔离的】,浏览器上下文相当于一个全新的浏览器配置文件,每个测试都有一个全新的环境,即使多个测试在同一个浏览器中运行。

// tests/example.spec.ts
import { test } from '@playwright/test';

test('example test', async ({ page }) => {
  // "page" 属于为这个特定测试创建的独立 BrowserContext。
});

test('another test', async ({ page }) => {
  // 这个第二个测试中的 "page" 完全与第一个测试隔离。
});
go

使用测试钩子

你可以使用各种 【测试钩子】,如 test.describe 来声明一组测试,test.beforeEachtest.afterEach 会在每个测试之前/之后执行。其他钩子包括 test.beforeAlltest.afterAll,它们在每个工作线程开始前/结束后只执行一次。

tests/example.spec.ts
import { test, expect } from '@playwright/test';

test.describe('navigation', () => {
  test.beforeEach(async ({ page }) => {
    // Go to the starting url before each test.
    await page.goto('https://playwright.dev/');
  });

  test('main navigation', async ({ page }) => {
    // Assertions use the expect API.
    await expect(page).toHaveURL('https://playwright.dev/');
  });
});
typescript

接下来做什么

  • 运行单个测试、多重测试、有头模式测试

  • 使用 Codegen 生成测试

  • 查看你的测试追踪

  • 探索 UI 模式

  • 在 CI 环境中使用 GitHub Actions 运行测试