夹具
Playwright 测试基于test fixtures的概念。测试夹具用于为每个测试建立环境,为测试提供所需的一切,而不多也不少。
🌐 Playwright Test is based on the concept of the test fixtures. Test fixtures are used to establish environment for each test, giving the test everything it needs and nothing else.
Playwright 测试会查看每个测试声明,分析测试所需的一组预置条件,并专门为该测试准备这些预置条件。由预置条件准备的值会合并到一个单一对象中,该对象可作为第一个参数提供给 test、钩子、注解和其他预置条件使用。
🌐 Playwright Test looks at each test declaration, analyses the set of fixtures the test needs and prepares those fixtures specifically for the test. Values prepared by the fixtures are merged into a single object that is available to the test, hooks, annotations and other fixtures as a first parameter.
import { test, expect } from '@playwright/test';
test('basic test', async ({ page }) => {
// ...
});
根据上面的测试,Playwright Test 会在运行测试之前设置 page 夹具,并在测试完成后拆除它。page 夹具提供一个 Page 对象,可供测试使用。
🌐 Given the test above, Playwright Test will set up the page fixture before running the test, and tear it down after the test has finished. page fixture provides a Page object that is available to the test.
Playwright 测试自带了如下列出的内置夹具,你也可以添加自己的夹具。Playwright 测试还可以 提供选项 配置 fixtures.browser、fixtures.context 和 fixtures.page。
🌐 Playwright Test comes with builtin fixtures listed below, and you can add your own fixtures as well. Playwright Test also provides options to configure fixtures.browser, fixtures.context and fixtures.page.
方法
🌐 Methods
mount
Added in: v1.62挂载一个组件故事,并返回一个指向故事渲染到的根元素的 Locator。从返回的定位器查询元素时,应该从 component.getByRole('button') 开始,而不是 page.getByRole('button')。
🌐 Mounts a component story and returns a Locator pointing to the root element the story was rendered into. Scope your queries from the returned locator: component.getByRole('button'), not page.getByRole('button').
故事是一个小型的封装组件,它将在一个特定的场景中嵌入正在测试的组件:硬编码的 props、模拟数据、提供者、录制的回调。故事由你实现的 图库 页面渲染,并在 testOptions.baseURL 提供服务。图库公开了 window.mount(params) 和 window.unmount() 函数,用于将故事渲染到它的根元素中。每次调用 fixtures.mount() 都会导航到 testOptions.baseURL 并用故事 ID 和 props 调用 window.mount(),所以测试彼此之间完全隔离。
🌐 A story is a small wrapper component that embeds the component under test in one specific scenario: hard-coded props, mock data, providers, recorded callbacks. Stories are rendered by a gallery page that you implement and serve at testOptions.baseURL. The gallery exposes window.mount(params) and window.unmount() functions that render a story into its root element. Each call to fixtures.mount() navigates to testOptions.baseURL and calls window.mount() with the story id and props, so tests are fully isolated from each other.
用法
test('click should expand', async ({ mount }) => {
const component = await mount('components/Expandable/Stateful');
await component.getByRole('button').click();
await expect(component.getByTestId('expanded')).toHaveValue('true');
});
将故事类型作为模板参数传递以进行 props 类型检查:
🌐 Pass the story type as a template argument to type-check the props:
import type { WithTitle } from './Button.story';
test('renders the title', async ({ mount }) => {
const component = await mount<typeof WithTitle>('Button/WithTitle', { title: 'Hello' });
await expect(component).toContainText('Hello');
});
返回的定位器增加了两种方法:
🌐 The returned locator is augmented with two methods:
update(props)- 在不重新挂载的情况下,用新的 props 重新渲染相同的组件,同时保留组件状态;unmount()- 卸载这个故事。
参数
-
要挂载的故事标识,由图库页面解析确定。通常是故事文件路径加上导出的故事名称,例如
'components/Button/Primary'。 -
可选的普通、可序列化属性传给故事。
返回
属性
🌐 Properties
browser
Added in: v1.10[浏览器] 实例在 相同的 worker 中的所有测试之间共享——这使得测试更高效。然而,每个测试都在一个独立的 [浏览器上下文] 中运行,并获得一个全新的环境。
🌐 Learn how to configure browser and see available options.
用法
test.beforeAll(async ({ browser }) => {
const page = await browser.newPage();
// ...
});
类型
browserName
Added in: v1.10运行测试的浏览器名称。默认为 'chromium'。可用于基于浏览器标注测试。
🌐 Name of the browser that runs tests. Defaults to 'chromium'. Useful to annotate tests based on the browser.
用法
test('skip this test in Firefox', async ({ page, browserName }) => {
test.skip(browserName === 'firefox', 'Still working on it');
// ...
});
类型
- "chromium" | "firefox" | "webkit"
context
Added in: v1.10独立的 BrowserContext 实例,为每个测试创建。由于上下文之间彼此隔离,每个测试都会获得一个全新的环境,即使在单个 Browser 中运行多个测试以实现最大效率时也如此。
🌐 Isolated BrowserContext instance, created for each test. Since contexts are isolated between each other, every test gets a fresh environment, even when multiple tests run in a single Browser for maximum efficiency.
🌐 Learn how to configure context and see available options.
默认 fixtures.page 属于此上下文。
🌐 Default fixtures.page belongs to this context.
用法
test('example test', async ({ page, context }) => {
await context.route('*external.com/*', route => route.abort());
// ...
});
类型
page
Added in: v1.10隔离的 Page 实例,为每个测试创建。由于 fixtures.context 的隔离,测试之间的页面是隔离的。
🌐 Isolated Page instance, created for each test. Pages are isolated between tests due to fixtures.context isolation.
这是测试中最常用的夹具。
🌐 This is the most common fixture used in a test.
用法
import { test, expect } from '@playwright/test';
test('basic test', async ({ page }) => {
await page.goto('/signin');
await page.getByLabel('User Name').fill('user');
await page.getByLabel('Password').fill('password');
await page.getByText('Sign in').click();
// ...
});
类型
request
Added in: v1.10为每个测试隔离的 APIRequestContext 实例。
🌐 Isolated APIRequestContext instance for each test.
用法
import { test, expect } from '@playwright/test';
test('basic test', async ({ request }) => {
await request.post('/signin', {
data: {
username: 'user',
password: 'password'
}
});
// ...
});
类型