编写测试
介绍
Playwright
测试非常简单,它们:
-
执行操作,并
-
对照期望断言状态。
在执行操作之前无需等待任何内容:Playwright
会自动等待一系列的 【可操作性】 检查通过,然后才执行每个操作。
在进行检查时,也无需担心竞争条件——Playwright
的断言被设计成能够描述需要最终满足的期望。
就是这么简单!这些设计选择使得 Playwright
用户完全不必担心不稳定的超时和竞态检查。
你将学到:
-
如何编写第一个测试
-
如何执行操作
-
如何使用断言
-
如何在隔离环境中运行测试
-
如何使用测试钩子
第一个测试
请查看以下示例,了解如何编写测试。
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 时,在每个测试文件的开头添加 |
操作
导航
大多数测试将从导航页面到 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)
并选择反映期望的匹配器。
有许多通用的匹配器,如 toEqual
、toContain
、toBeTruthy
等,可以用来断言任何条件。
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.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.dev/'); }); test('main navigation', async ({ page }) => { // Assertions use the expect API. await expect(page).toHaveURL('https://playwright.dev/'); }); });
typescript