编写测试
简介
Playwright 测试很简单:它们执行操作并根据预期断言状态。
Playwright 会在执行每个操作之前自动等待可操作性检查通过。您无需添加手动等待或处理竞态条件。Playwright 断言旨在描述最终会满足的预期,从而消除不稳定的超时和竞态检查。
您将学到
第一个测试
请看以下示例,了解如何编写测试。
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)
并选择一个反映预期的匹配器。
Playwright 包含异步匹配器,它们会一直等待直到满足预期条件。使用这些匹配器可以使测试变得稳定且健壮。例如,这段代码会等待页面获取包含“Playwright”的标题
await expect(page).toHaveTitle(/Playwright/);
以下是最常用的异步断言。有关完整列表,请参阅断言指南
Playwright 还包含通用匹配器,例如 toEqual
、toContain
、toBeTruthy
,它们可用于断言任何条件。这些断言不使用 await
关键字,因为它们对已经可用的值执行即时同步检查。
expect(success).toBeTruthy();
测试隔离
Playwright Test 基于测试夹具的概念,例如传递到测试中的内置页面夹具。由于浏览器上下文(相当于全新的浏览器配置文件),页面在测试之间是隔离的。即使在单个浏览器中运行多个测试,每个测试也会获得一个全新的环境。
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.beforeEach
和 test.afterEach
,它们在每个测试之前/之后执行。其他钩子包括 test.beforeAll
和 test.afterAll
,它们在所有测试之前/之后每个工作器执行一次。
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/');
});
});