跳转到主内容

编写测试

引言

Playwright 测试很简单,它们会

  • 执行操作,并且
  • 根据预期断言状态

在执行操作之前,无需等待任何内容:Playwright 会自动等待各种可操作性检查通过后,再执行每个操作。

在执行检查时也无需处理竞态条件 - Playwright 断言的设计方式使其能够描述最终需要满足的预期。

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

您将学习

第一个测试

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

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

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

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

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

// 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();
});
注意

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

操作

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

await page.goto('https://playwright.net.cn/');

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

交互

执行操作从定位元素开始。Playwright 为此使用了 定位器 API。定位器表示在任何时刻查找页面上元素的方法,了解更多关于可用的不同类型定位器的信息。Playwright 会等待元素变得可操作后再执行操作,因此无需等待它变得可用。

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

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

大多数情况下,可以写在一行

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

基本操作

这是最常用的 Playwright 操作列表。请注意,还有更多操作,请务必查看 定位器 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();

Playwright 还包括异步匹配器,它们会一直等待直到满足预期条件。使用这些匹配器可以使测试稳定且有弹性。例如,这段代码将等待页面获取包含“Playwright”的标题。

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

以下是最常用的异步断言列表。请注意,还有更多断言需要熟悉。

断言描述
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(page).toHaveURL()页面有 URL

测试隔离

Playwright Test 基于测试夹具的概念,例如传递到测试中的内置页面夹具。页面通过浏览器上下文在测试之间隔离,这等同于一个全新的浏览器配置文件,每个测试都会获得一个全新的环境,即使在单个浏览器中运行多个测试也是如此。

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

test('example test', async ({ page }) => {
// "page" belongs to an isolated BrowserContext, created for this specific test.
});

test('another test', async ({ page }) => {
// "page" in this second test is completely isolated from the first test.
});

使用测试钩子

您可以使用各种测试钩子,例如 test.describe 来声明一组测试,以及 test.beforeEachtest.afterEach,它们分别在每个测试运行之前和之后执行。其他钩子包括 test.beforeAlltest.afterAll,它们在每个 worker 中所有测试运行之前和之后执行一次。

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.net.cn/');
});

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

下一步