Playwright 测试
Playwright Test 提供了 test
函数来声明测试和 expect
函数来编写断言。
¥Playwright Test provides a test
function to declare tests and expect
function to write assertions.
import { test, expect } from '@playwright/test';
test('basic test', async ({ page }) => {
await page.goto('https://playwright.nodejs.cn/');
const name = await page.innerText('.navbar__title');
expect(name).toBe('Playwright');
});
方法
¥Methods
test
Added in: v1.10宣布进行测试。
¥Declares a test.
-
test(title, body)
-
test(title, details, body)
用法
¥Usage
import { test, expect } from '@playwright/test';
test('basic test', async ({ page }) => {
await page.goto('https://playwright.nodejs.cn/');
// ...
});
标签
¥Tags
你可以通过提供其他测试详细信息来标记测试。或者,你可以在测试标题中包含标签。请注意,每个标签必须以 @
符号开头。
¥You can tag tests by providing additional test details. Alternatively, you can include tags in the test title. Note that each tag must start with @
symbol.
import { test, expect } from '@playwright/test';
test('basic test', {
tag: '@smoke',
}, async ({ page }) => {
await page.goto('https://playwright.nodejs.cn/');
// ...
});
test('another test @smoke', async ({ page }) => {
await page.goto('https://playwright.nodejs.cn/');
// ...
});
测试标签显示在测试报告中,并可供自定义报告者通过 TestCase.tags
属性使用。
¥Test tags are displayed in the test report, and are available to a custom reporter via TestCase.tags
property.
你还可以在测试执行期间按标签过滤测试:
¥You can also filter tests by their tags during test execution:
-
在 命令行;
¥in the command line;
-
在配置中包含 testConfig.grep 和 testProject.grep;
¥in the config with testConfig.grep and testProject.grep;
了解有关 tagging 的更多信息。
¥Learn more about tagging.
注释
¥Annotations
你可以通过提供额外的测试详细信息来注释测试。
¥You can annotate tests by providing additional test details.
import { test, expect } from '@playwright/test';
test('basic test', {
annotation: {
type: 'issue',
description: 'https://github.com/microsoft/playwright/issues/23180',
},
}, async ({ page }) => {
await page.goto('https://playwright.nodejs.cn/');
// ...
});
测试注释显示在测试报告中,并可通过 TestCase.annotations
属性提供给自定义报告者。
¥Test annotations are displayed in the test report, and are available to a custom reporter via TestCase.annotations
property.
你还可以通过操作 testInfo.annotations 在运行时添加注释。
¥You can also add annotations during runtime by manipulating testInfo.annotations.
了解有关 测试注释 的更多信息。
¥Learn more about test annotations.
参数
¥Arguments
测试标题。
¥Test title.
注释类型,例如 'issue'
。
¥Annotation type, for example 'issue'
.
description
string (optional)
可选注释描述,例如问题 url。
¥Optional annotation description, for example an issue url.
额外的测试细节。
¥Additional test details.
带有一个或两个参数的测试主体:带有夹具和可选 TestInfo 的对象。
¥Test body that takes one or two arguments: an object with fixtures and optional TestInfo.
test.afterAll
Added in: v1.10声明一个 afterAll
钩子,在所有测试后每个工作线程执行一次。
¥Declares an afterAll
hook that is executed once per worker after all tests.
在测试文件范围内调用时,在文件中的所有测试之后运行。当在 test.describe() 组内调用时,在组中的所有测试之后运行。
¥When called in the scope of a test file, runs after all tests in the file. When called inside a test.describe() group, runs after all tests in the group.
用法
¥Usage
test.afterAll(async () => {
console.log('Done with tests');
// ...
});
或者,你可以声明带有标题的钩子。
¥Alternatively, you can declare a hook with a title.
test.afterAll('Teardown', async () => {
console.log('Done with tests');
// ...
});
参数
¥Arguments
钩子标题。
¥Hook title.
带有一个或两个参数的钩子函数:带有工作线程夹具和可选 TestInfo 的对象。
¥Hook function that takes one or two arguments: an object with worker fixtures and optional TestInfo.
细节
¥Details
当添加多个 afterAll
钩子时,它们将按照注册的顺序运行。
¥When multiple afterAll
hooks are added, they will run in the order of their registration.
请注意,工作进程在测试失败时重新启动,并且 afterAll
钩子在新工作进程中再次运行。了解有关 工作线程和失败 的更多信息。
¥Note that worker process is restarted on test failures, and afterAll
hook runs again in the new worker. Learn more about workers and failures.
Playwright 将继续运行所有适用的钩子,即使其中一些钩子失败。
¥Playwright will continue running all applicable hooks even if some of them have failed.
-
test.afterAll(hookFunction)
-
test.afterAll(title, hookFunction)
test.afterEach
Added in: v1.10声明每次测试后执行的 afterEach
钩子。
¥Declares an afterEach
hook that is executed after each test.
在测试文件范围内调用时,在文件中的每个测试之后运行。当在 test.describe() 组内调用时,在组中的每个测试之后运行。
¥When called in the scope of a test file, runs after each test in the file. When called inside a test.describe() group, runs after each test in the group.
你可以访问与测试主体本身相同的所有 夹具,以及提供大量有用信息的 TestInfo 对象。例如,你可以检查测试是否成功或失败。
¥You can access all the same Fixtures as the test body itself, and also the TestInfo object that gives a lot of useful information. For example, you can check whether the test succeeded or failed.
-
test.afterEach(hookFunction)
-
test.afterEach(title, hookFunction)
用法
¥Usage
import { test, expect } from '@playwright/test';
test.afterEach(async ({ page }) => {
console.log(`Finished ${test.info().title} with status ${test.info().status}`);
if (test.info().status !== test.info().expectedStatus)
console.log(`Did not run as expected, ended up at ${page.url()}`);
});
test('my test', async ({ page }) => {
// ...
});
或者,你可以声明带有标题的钩子。
¥Alternatively, you can declare a hook with a title.
test.afterEach('Status check', async ({ page }) => {
if (test.info().status !== test.info().expectedStatus)
console.log(`Did not run as expected, ended up at ${page.url()}`);
});
参数
¥Arguments
钩子标题。
¥Hook title.
带有一个或两个参数的钩子函数:带有夹具和可选 TestInfo 的对象。
¥Hook function that takes one or two arguments: an object with fixtures and optional TestInfo.
细节
¥Details
当添加多个 afterEach
钩子时,它们将按照注册的顺序运行。
¥When multiple afterEach
hooks are added, they will run in the order of their registration.
Playwright 将继续运行所有适用的钩子,即使其中一些钩子失败。
¥Playwright will continue running all applicable hooks even if some of them have failed.
test.beforeAll
Added in: v1.10声明一个 beforeAll
钩子,在所有测试之前每个工作进程执行一次。
¥Declares a beforeAll
hook that is executed once per worker process before all tests.
在测试文件范围内调用时,在文件中的所有测试之前运行。当在 test.describe() 组内调用时,在组中的所有测试之前运行。
¥When called in the scope of a test file, runs before all tests in the file. When called inside a test.describe() group, runs before all tests in the group.
你可以使用 test.afterAll() 拆除 beforeAll
中设置的任何资源。
¥You can use test.afterAll() to teardown any resources set up in beforeAll
.
-
test.beforeAll(hookFunction)
-
test.beforeAll(title, hookFunction)
用法
¥Usage
import { test, expect } from '@playwright/test';
test.beforeAll(async () => {
console.log('Before tests');
});
test.afterAll(async () => {
console.log('After tests');
});
test('my test', async ({ page }) => {
// ...
});
或者,你可以声明带有标题的钩子。
¥Alternatively, you can declare a hook with a title.
test.beforeAll('Setup', async () => {
console.log('Before tests');
});
参数
¥Arguments
钩子标题。
¥Hook title.
带有一个或两个参数的钩子函数:带有工作线程夹具和可选 TestInfo 的对象。
¥Hook function that takes one or two arguments: an object with worker fixtures and optional TestInfo.
细节
¥Details
当添加多个 beforeAll
钩子时,它们将按照注册的顺序运行。
¥When multiple beforeAll
hooks are added, they will run in the order of their registration.
请注意,工作进程在测试失败时重新启动,并且 beforeAll
钩子在新工作进程中再次运行。了解有关 工作线程和失败 的更多信息。
¥Note that worker process is restarted on test failures, and beforeAll
hook runs again in the new worker. Learn more about workers and failures.
Playwright 将继续运行所有适用的钩子,即使其中一些钩子失败。
¥Playwright will continue running all applicable hooks even if some of them have failed.
test.beforeEach
Added in: v1.10声明在每次测试之前执行的 beforeEach
钩子。
¥Declares a beforeEach
hook that is executed before each test.
在测试文件范围内调用时,在文件中的每个测试之前运行。当在 test.describe() 组内调用时,在组中的每个测试之前运行。
¥When called in the scope of a test file, runs before each test in the file. When called inside a test.describe() group, runs before each test in the group.
你可以访问与测试主体本身相同的所有 夹具,以及提供大量有用信息的 TestInfo 对象。例如,你可以在开始测试之前导航页面。
¥You can access all the same Fixtures as the test body itself, and also the TestInfo object that gives a lot of useful information. For example, you can navigate the page before starting the test.
你可以使用 test.afterEach() 拆除 beforeEach
中设置的任何资源。
¥You can use test.afterEach() to teardown any resources set up in beforeEach
.
-
test.beforeEach(hookFunction)
-
test.beforeEach(title, hookFunction)
用法
¥Usage
import { test, expect } from '@playwright/test';
test.beforeEach(async ({ page }) => {
console.log(`Running ${test.info().title}`);
await page.goto('https://my.start.url/');
});
test('my test', async ({ page }) => {
expect(page.url()).toBe('https://my.start.url/');
});
或者,你可以声明带有标题的钩子。
¥Alternatively, you can declare a hook with a title.
test.beforeEach('Open start URL', async ({ page }) => {
console.log(`Running ${test.info().title}`);
await page.goto('https://my.start.url/');
});
参数
¥Arguments
钩子标题。
¥Hook title.
带有一个或两个参数的钩子函数:带有夹具和可选 TestInfo 的对象。
¥Hook function that takes one or two arguments: an object with fixtures and optional TestInfo.
细节
¥Details
当添加多个 beforeEach
钩子时,它们将按照注册的顺序运行。
¥When multiple beforeEach
hooks are added, they will run in the order of their registration.
Playwright 将继续运行所有适用的钩子,即使其中一些钩子失败。
¥Playwright will continue running all applicable hooks even if some of them have failed.
test.describe
Added in: v1.10声明一组测试。
¥Declares a group of tests.
-
test.describe(title, callback)
-
test.describe(callback)
-
test.describe(title, details, callback)
用法
¥Usage
你可以声明一组带有标题的测试。该标题将作为每个测试标题的一部分显示在测试报告中。
¥You can declare a group of tests with a title. The title will be visible in the test report as a part of each test's title.
test.describe('two tests', () => {
test('one', async ({ page }) => {
// ...
});
test('two', async ({ page }) => {
// ...
});
});
匿名群组
¥Anonymous group
你还可以声明一个没有标题的测试组。这样可以方便地为一组测试提供 test.use() 的通用选项。
¥You can also declare a test group without a title. This is convenient to give a group of tests a common option with test.use().
test.describe(() => {
test.use({ colorScheme: 'dark' });
test('one', async ({ page }) => {
// ...
});
test('two', async ({ page }) => {
// ...
});
});
标签
¥Tags
你可以通过提供附加详细信息来标记组中的所有测试。请注意,每个标签必须以 @
符号开头。
¥You can tag all tests in a group by providing additional details. Note that each tag must start with @
symbol.
import { test, expect } from '@playwright/test';
test.describe('two tagged tests', {
tag: '@smoke',
}, () => {
test('one', async ({ page }) => {
// ...
});
test('two', async ({ page }) => {
// ...
});
});
了解有关 tagging 的更多信息。
¥Learn more about tagging.
注释
¥Annotations
你可以通过提供附加详细信息来注释组中的所有测试。
¥You can annotate all tests in a group by providing additional details.
import { test, expect } from '@playwright/test';
test.describe('two annotated tests', {
annotation: {
type: 'issue',
description: 'https://github.com/microsoft/playwright/issues/23180',
},
}, () => {
test('one', async ({ page }) => {
// ...
});
test('two', async ({ page }) => {
// ...
});
});
了解有关 测试注释 的更多信息。
¥Learn more about test annotations.
参数
¥Arguments
组标题。
¥Group title.
该组中所有测试的其他详细信息。
¥Additional details for all tests in the group.
调用 test.describe() 时立即运行的回调。此回调中声明的任何测试都将属于该组。
¥A callback that is run immediately when calling test.describe(). Any tests declared in this callback will belong to the group.
test.describe.configure
Added in: v1.10配置封闭范围。可以在顶层或在描述内执行。配置适用于整个范围,无论它是在测试声明之前还是之后运行。
¥Configures the enclosing scope. Can be executed either on the top level or inside a describe. Configuration applies to the entire scope, regardless of whether it run before or after the test declaration.
了解有关执行模式 此处 的更多信息。
¥Learn more about the execution modes here.
用法
¥Usage
-
并行运行测试。
¥Running tests in parallel.
// Run all the tests in the file concurrently using parallel workers.
test.describe.configure({ mode: 'parallel' });
test('runs in parallel 1', async ({ page }) => {});
test('runs in parallel 2', async ({ page }) => {}); -
连续运行测试,从头开始重试。
¥Running tests serially, retrying from the start.
注意不建议串行运行。通常最好将测试隔离起来,这样它们就可以独立运行。:::
¥Running serially is not recommended. It is usually better to make your tests isolated, so they can be run independently.
// Annotate tests as inter-dependent.
test.describe.configure({ mode: 'serial' });
test('runs first', async ({ page }) => {});
test('runs second', async ({ page }) => {}); -
为每个测试配置重试和超时。
¥Configuring retries and timeout for each test.
// Each test in the file will be retried twice and have a timeout of 20 seconds.
test.describe.configure({ retries: 2, timeout: 20_000 });
test('runs first', async ({ page }) => {});
test('runs second', async ({ page }) => {}); -
并行运行多个描述,但每个描述内的测试按顺序进行。
¥Run multiple describes in parallel, but tests inside each describe in order.
test.describe.configure({ mode: 'parallel' });
test.describe('A, runs in parallel with B', () => {
test.describe.configure({ mode: 'default' });
test('in order A1', async ({ page }) => {});
test('in order A2', async ({ page }) => {});
});
test.describe('B, runs in parallel with A', () => {
test.describe.configure({ mode: 'default' });
test('in order B1', async ({ page }) => {});
test('in order B2', async ({ page }) => {});
});
参数
¥Arguments
options
Object (optional)
-
mode
"default" | "parallel" | "serial"(可选)#¥
mode
"default" | "parallel" | "serial" (optional)#执行模式。了解有关执行模式 此处 的更多信息。
¥Execution mode. Learn more about the execution modes here.
每次测试的重试次数。
¥The number of retries for each test.
每个测试的超时时间(以毫秒为单位)。覆盖 testProject.timeout 和 testConfig.timeout。
¥Timeout for each test in milliseconds. Overrides testProject.timeout and testConfig.timeout.
test.describe.fixme
Added in: v1.25与 test.describe() 类似地声明一个测试组。该组中的测试被标记为 "fixme" 并且不会被执行。
¥Declares a test group similarly to test.describe(). Tests in this group are marked as "fixme" and will not be executed.
-
test.describe.fixme(title, callback)
-
test.describe.fixme(callback)
-
test.describe.fixme(title, details, callback)
用法
¥Usage
test.describe.fixme('broken tests that should be fixed', () => {
test('example', async ({ page }) => {
// This test will not run
});
});
你也可以省略标题。
¥You can also omit the title.
test.describe.fixme(() => {
// ...
});
参数
¥Arguments
组标题。
¥Group title.
详细说明见 test.describe()。
¥See test.describe() for details description.
调用 test.describe.fixme() 时立即运行的回调。此回调中添加的任何测试都将属于该组,并且不会运行。
¥A callback that is run immediately when calling test.describe.fixme(). Any tests added in this callback will belong to the group, and will not be run.
test.describe.only
Added in: v1.10声明一组重点测试。如果有一些重点测试或套件,那么所有这些测试或套件都将运行,但不会运行其他测试。
¥Declares a focused group of tests. If there are some focused tests or suites, all of them will be run but nothing else.
-
test.describe.only(title, callback)
-
test.describe.only(callback)
-
test.describe.only(title, details, callback)
用法
¥Usage
test.describe.only('focused group', () => {
test('in the focused group', async ({ page }) => {
// This test will run
});
});
test('not in the focused group', async ({ page }) => {
// This test will not run
});
你也可以省略标题。
¥You can also omit the title.
test.describe.only(() => {
// ...
});
参数
¥Arguments
组标题。
¥Group title.
详细说明见 test.describe()。
¥See test.describe() for details description.
调用 test.describe.only() 时立即运行的回调。此回调中添加的任何测试都将属于该组。
¥A callback that is run immediately when calling test.describe.only(). Any tests added in this callback will belong to the group.
test.describe.skip
Added in: v1.10声明一个跳过的测试组,类似于 test.describe()。跳过组中的测试永远不会运行。
¥Declares a skipped test group, similarly to test.describe(). Tests in the skipped group are never run.
-
test.describe.skip(title, callback)
-
test.describe.skip(title)
-
test.describe.skip(title, details, callback)
用法
¥Usage
test.describe.skip('skipped group', () => {
test('example', async ({ page }) => {
// This test will not run
});
});
你也可以省略标题。
¥You can also omit the title.
test.describe.skip(() => {
// ...
});
参数
¥Arguments
组标题。
¥Group title.
详细说明见 test.describe()。
¥See test.describe() for details description.
调用 test.describe.skip() 时立即运行的回调。此回调中添加的任何测试都将属于该组,并且不会运行。
¥A callback that is run immediately when calling test.describe.skip(). Any tests added in this callback will belong to the group, and will not be run.
test.extend
Added in: v1.10通过定义可在测试中使用的夹具和/或选项来扩展 test
对象。
¥Extends the test
object by defining fixtures and/or options that can be used in the tests.
用法
¥Usage
首先定义一个夹具和/或一个选项。
¥First define a fixture and/or an option.
- TypeScript
- JavaScript
import { test as base } from '@playwright/test';
import { TodoPage } from './todo-page';
export type Options = { defaultItem: string };
// Extend basic test by providing a "defaultItem" option and a "todoPage" fixture.
export const test = base.extend<Options & { todoPage: TodoPage }>({
// Define an option and provide a default value.
// We can later override it in the config.
defaultItem: ['Do stuff', { option: true }],
// Define a fixture. Note that it can use built-in fixture "page"
// and a new option "defaultItem".
todoPage: async ({ page, defaultItem }, use) => {
const todoPage = new TodoPage(page);
await todoPage.goto();
await todoPage.addToDo(defaultItem);
await use(todoPage);
await todoPage.removeAll();
},
});
const base = require('@playwright/test');
const { TodoPage } = require('./todo-page');
// Extend basic test by providing a "defaultItem" option and a "todoPage" fixture.
exports.test = base.test.extend({
// Define an option and provide a default value.
// We can later override it in the config.
defaultItem: ['Do stuff', { option: true }],
// Define a fixture. Note that it can use built-in fixture "page"
// and a new option "defaultItem".
todoPage: async ({ page, defaultItem }, use) => {
const todoPage = new TodoPage(page);
await todoPage.goto();
await todoPage.addToDo(defaultItem);
await use(todoPage);
await todoPage.removeAll();
},
});
然后在测试中使用夹具。
¥Then use the fixture in the test.
import { test } from './my-test';
test('test 1', async ({ todoPage }) => {
await todoPage.addToDo('my todo');
// ...
});
配置配置文件中的选项。
¥Configure the option in config file.
- TypeScript
- JavaScript
import { defineConfig } from '@playwright/test';
import type { Options } from './my-test';
export default defineConfig<Options>({
projects: [
{
name: 'shopping',
use: { defaultItem: 'Buy milk' },
},
{
name: 'wellbeing',
use: { defaultItem: 'Exercise!' },
},
]
});
// @ts-check
module.exports = defineConfig({
projects: [
{
name: 'shopping',
use: { defaultItem: 'Buy milk' },
},
{
name: 'wellbeing',
use: { defaultItem: 'Exercise!' },
},
]
});
¥Learn more about fixtures and parametrizing tests.
参数
¥Arguments
包含装置和/或选项的对象。了解有关 赛程格式 的更多信息。
¥An object containing fixtures and/or options. Learn more about fixtures format.
返回
¥Returns
test.fail
Added in: v1.10将测试标记为 "应该失败"。Playwright 运行此测试并确保它确实失败。这对于文档目的很有用,可以确认某些功能在修复之前已损坏。
¥Marks a test as "should fail". Playwright runs this test and ensures that it is actually failing. This is useful for documentation purposes to acknowledge that some functionality is broken until it is fixed.
声明 "failing" 测试:
¥To declare a "failing" test:
-
test.fail(title, body)
-
test.fail(title, details, body)
要在运行时将测试注释为 "failing":
¥To annotate test as "failing" at runtime:
-
test.fail(condition, description)
-
test.fail(callback, description)
-
test.fail()
用法
¥Usage
你可以将测试声明为失败,以便 Playwright 确保它确实失败。
¥You can declare a test as failing, so that Playwright ensures it actually fails.
import { test, expect } from '@playwright/test';
test.fail('not yet ready', async ({ page }) => {
// ...
});
如果你的测试在某些配置(但不是全部)中失败,你可以根据某些条件在测试主体内将测试标记为失败。我们建议在这种情况下传递 description
参数。
¥If your test fails in some configurations, but not all, you can mark the test as failing inside the test body based on some condition. We recommend passing a description
argument in this case.
import { test, expect } from '@playwright/test';
test('fail in WebKit', async ({ page, browserName }) => {
test.fail(browserName === 'webkit', 'This feature is not implemented for Mac yet');
// ...
});
你可以根据某些条件,使用单个 test.fail(callback, description)
调用将文件或 test.describe() 组中的所有测试标记为 "应该失败"。
¥You can mark all tests in a file or test.describe() group as "should fail" based on some condition with a single test.fail(callback, description)
call.
import { test, expect } from '@playwright/test';
test.fail(({ browserName }) => browserName === 'webkit', 'not implemented yet');
test('fail in WebKit 1', async ({ page }) => {
// ...
});
test('fail in WebKit 2', async ({ page }) => {
// ...
});
你还可以在测试主体内调用不带参数的 test.fail()
,以始终将测试标记为失败。我们建议改为使用 test.fail(title, body)
来声明失败的测试。
¥You can also call test.fail()
without arguments inside the test body to always mark the test as failed. We recommend declaring a failing test with test.fail(title, body)
instead.
import { test, expect } from '@playwright/test';
test('less readable', async ({ page }) => {
test.fail();
// ...
});
参数
¥Arguments
测试标题。
¥Test title.
测试详细说明参见 test()。
¥See test() for test details description.
带有一个或两个参数的测试主体:带有夹具和可选 TestInfo 的对象。
¥Test body that takes one or two arguments: an object with fixtures and optional TestInfo.
当条件为 true
时,测试标记为 "应该失败"。
¥Test is marked as "should fail" when the condition is true
.
一个函数,根据测试夹具返回是否标记为 "应该失败"。当返回值为 true
时,一个或多个测试被标记为 "应该失败"。
¥A function that returns whether to mark as "should fail", based on test fixtures. Test or tests are marked as "should fail" when the return value is true
.
将反映在测试报告中的可选描述。
¥Optional description that will be reflected in a test report.
test.fixme
Added in: v1.10将测试标记为 "fixme",旨在修复它。Playwright 将不会在 test.fixme()
调用之后运行测试。
¥Mark a test as "fixme", with the intention to fix it. Playwright will not run the test past the test.fixme()
call.
声明 "fixme" 测试:
¥To declare a "fixme" test:
-
test.fixme(title, body)
-
test.fixme(title, details, body)
要在运行时将测试注释为 "fixme":
¥To annotate test as "fixme" at runtime:
-
test.fixme(condition, description)
-
test.fixme(callback, description)
-
test.fixme()
用法
¥Usage
你可以声明一个测试已修复,而 Playwright 不会运行它。
¥You can declare a test as to be fixed, and Playwright will not run it.
import { test, expect } from '@playwright/test';
test.fixme('to be fixed', async ({ page }) => {
// ...
});
如果你的测试应该在某些配置(但不是全部)中修复,你可以根据某些条件在测试主体内将测试标记为 "fixme"。我们建议在这种情况下传递 description
参数。Playwright 将运行测试,但在 test.fixme
调用后立即中止它。
¥If your test should be fixed in some configurations, but not all, you can mark the test as "fixme" inside the test body based on some condition. We recommend passing a description
argument in this case. Playwright will run the test, but abort it immediately after the test.fixme
call.
import { test, expect } from '@playwright/test';
test('to be fixed in Safari', async ({ page, browserName }) => {
test.fixme(browserName === 'webkit', 'This feature breaks in Safari for some reason');
// ...
});
你可以根据某些条件,使用单个 test.fixme(callback, description)
调用将文件或 test.describe() 组中的所有测试标记为 "fixme"。
¥You can mark all tests in a file or test.describe() group as "fixme" based on some condition with a single test.fixme(callback, description)
call.
import { test, expect } from '@playwright/test';
test.fixme(({ browserName }) => browserName === 'webkit', 'Should figure out the issue');
test('to be fixed in Safari 1', async ({ page }) => {
// ...
});
test('to be fixed in Safari 2', async ({ page }) => {
// ...
});
你还可以在测试主体内调用不带参数的 test.fixme()
,以始终将测试标记为失败。我们建议使用 test.fixme(title, body)
。
¥You can also call test.fixme()
without arguments inside the test body to always mark the test as failed. We recommend using test.fixme(title, body)
instead.
import { test, expect } from '@playwright/test';
test('less readable', async ({ page }) => {
test.fixme();
// ...
});
参数
¥Arguments
测试标题。
¥Test title.
测试详细说明参见 test()。
¥See test() for test details description.
带有一个或两个参数的测试主体:带有夹具和可选 TestInfo 的对象。
¥Test body that takes one or two arguments: an object with fixtures and optional TestInfo.
当条件为 true
时,测试标记为 "应该失败"。
¥Test is marked as "should fail" when the condition is true
.
一个函数,根据测试夹具返回是否标记为 "应该失败"。当返回值为 true
时,一个或多个测试被标记为 "应该失败"。
¥A function that returns whether to mark as "should fail", based on test fixtures. Test or tests are marked as "should fail" when the return value is true
.
将反映在测试报告中的可选描述。
¥Optional description that will be reflected in a test report.
test.info
Added in: v1.10返回有关当前正在运行的测试的信息。该方法只能在测试执行期间调用,否则会抛出异常。
¥Returns information about the currently running test. This method can only be called during the test execution, otherwise it throws.
用法
¥Usage
test('example test', async ({ page }) => {
// ...
await test.info().attach('screenshot', {
body: await page.screenshot(),
contentType: 'image/png',
});
});
返回
¥Returns
test.only
Added in: v1.10宣布进行重点测试。如果有一些重点测试或套件,那么所有这些测试或套件都将运行,但不会运行其他测试。
¥Declares a focused test. If there are some focused tests or suites, all of them will be run but nothing else.
-
test.only(title, body)
-
test.only(title, details, body)
用法
¥Usage
test.only('focus this test', async ({ page }) => {
// Run only focused tests in the entire project.
});
参数
¥Arguments
测试标题。
¥Test title.
测试详细说明参见 test()。
¥See test() for test details description.
带有一个或两个参数的测试主体:带有夹具和可选 TestInfo 的对象。
¥Test body that takes one or two arguments: an object with fixtures and optional TestInfo.
test.setTimeout
Added in: v1.10更改测试的超时。零意味着没有超时。了解有关 各种超时 的更多信息。
¥Changes the timeout for the test. Zero means no timeout. Learn more about various timeouts.
当前正在运行的测试的超时可通过 testInfo.timeout 获得。
¥Timeout for the currently running test is available through testInfo.timeout.
用法
¥Usage
-
更改测试超时。
¥Changing test timeout.
test('very slow test', async ({ page }) => {
test.setTimeout(120000);
// ...
}); -
更改慢速
beforeEach
或afterEach
钩子的超时。请注意,这会影响与beforeEach
/afterEach
钩子共享的测试超时。¥Changing timeout from a slow
beforeEach
orafterEach
hook. Note that this affects the test timeout that is shared withbeforeEach
/afterEach
hooks.test.beforeEach(async ({ page }, testInfo) => {
// Extend timeout for all tests running this hook by 30 seconds.
test.setTimeout(testInfo.timeout + 30000);
}); -
更改
beforeAll
或afterAll
钩子的超时。请注意,这会影响钩子的超时,而不是测试超时。¥Changing timeout for a
beforeAll
orafterAll
hook. Note this affects the hook's timeout, not the test timeout.test.beforeAll(async () => {
// Set timeout for this hook.
test.setTimeout(60000);
}); -
更改 test.describe() 组中所有测试的超时。
¥Changing timeout for all tests in a test.describe() group.
test.describe('group', () => {
// Applies to all tests in this group.
test.describe.configure({ timeout: 60000 });
test('test one', async () => { /* ... */ });
test('test two', async () => { /* ... */ });
test('test three', async () => { /* ... */ });
});
参数
¥Arguments
超时(以毫秒为单位)。
¥Timeout in milliseconds.
test.skip
Added in: v1.10跳过测试。Playwright 将不会在 test.skip()
调用之后运行测试。
¥Skip a test. Playwright will not run the test past the test.skip()
call.
跳过的测试不应该运行。如果你打算修复测试,请改用 test.fixme()。
¥Skipped tests are not supposed to be ever run. If you intent to fix the test, use test.fixme() instead.
要声明跳过的测试:
¥To declare a skipped test:
-
test.skip(title, body)
-
test.skip(title, details, body)
要在运行时跳过测试:
¥To skip a test at runtime:
-
test.skip(condition, description)
-
test.skip(callback, description)
-
test.skip()
用法
¥Usage
你可以声明跳过的测试,Playwright 将不会运行它。
¥You can declare a skipped test, and Playwright will not run it.
import { test, expect } from '@playwright/test';
test.skip('never run', async ({ page }) => {
// ...
});
如果你的测试应该在某些配置中跳过,但不是全部,你可以根据某些条件跳过测试主体内的测试。我们建议在这种情况下传递 description
参数。Playwright 将运行测试,但在 test.skip
调用后立即中止它。
¥If your test should be skipped in some configurations, but not all, you can skip the test inside the test body based on some condition. We recommend passing a description
argument in this case. Playwright will run the test, but abort it immediately after the test.skip
call.
import { test, expect } from '@playwright/test';
test('Safari-only test', async ({ page, browserName }) => {
test.skip(browserName !== 'webkit', 'This feature is Safari-only');
// ...
});
你可以根据某些条件,使用单个 test.skip(callback, description)
调用跳过文件或 test.describe() 组中的所有测试。
¥You can skip all tests in a file or test.describe() group based on some condition with a single test.skip(callback, description)
call.
import { test, expect } from '@playwright/test';
test.skip(({ browserName }) => browserName !== 'webkit', 'Safari-only');
test('Safari-only test 1', async ({ page }) => {
// ...
});
test('Safari-only test 2', async ({ page }) => {
// ...
});
你还可以在测试主体内调用不带参数的 test.skip()
,以始终将测试标记为失败。我们建议使用 test.skip(title, body)
。
¥You can also call test.skip()
without arguments inside the test body to always mark the test as failed. We recommend using test.skip(title, body)
instead.
import { test, expect } from '@playwright/test';
test('less readable', async ({ page }) => {
test.skip();
// ...
});
参数
¥Arguments
测试标题。
¥Test title.
测试详细说明参见 test()。
¥See test() for test details description.
带有一个或两个参数的测试主体:带有夹具和可选 TestInfo 的对象。
¥Test body that takes one or two arguments: an object with fixtures and optional TestInfo.
当条件为 true
时,测试标记为 "应该失败"。
¥Test is marked as "should fail" when the condition is true
.
一个函数,根据测试夹具返回是否标记为 "应该失败"。当返回值为 true
时,一个或多个测试被标记为 "应该失败"。
¥A function that returns whether to mark as "should fail", based on test fixtures. Test or tests are marked as "should fail" when the return value is true
.
将反映在测试报告中的可选描述。
¥Optional description that will be reflected in a test report.
test.slow
Added in: v1.10将测试标记为 "slow"。慢速测试将给予默认超时的三倍。
¥Marks a test as "slow". Slow test will be given triple the default timeout.
请注意,test.slow() 不能在 beforeAll
或 afterAll
钩子中使用。请改用 test.setTimeout()。
¥Note that test.slow() cannot be used in a beforeAll
or afterAll
hook. Use test.setTimeout() instead.
-
test.slow()
-
test.slow(condition, description)
-
test.slow(callback, description)
用法
¥Usage
你可以通过在测试主体内调用 test.slow()
将测试标记为慢。
¥You can mark a test as slow by calling test.slow()
inside the test body.
import { test, expect } from '@playwright/test';
test('slow test', async ({ page }) => {
test.slow();
// ...
});
如果你的测试在某些配置(但不是全部)中运行缓慢,你可以根据条件将其标记为运行缓慢。我们建议在这种情况下传递 description
参数。
¥If your test is slow in some configurations, but not all, you can mark it as slow based on a condition. We recommend passing a description
argument in this case.
import { test, expect } from '@playwright/test';
test('slow in Safari', async ({ page, browserName }) => {
test.slow(browserName === 'webkit', 'This feature is slow in Safari');
// ...
});
你可以通过传递回调根据某些条件将文件或 test.describe() 组中的所有测试标记为 "slow"。
¥You can mark all tests in a file or test.describe() group as "slow" based on some condition by passing a callback.
import { test, expect } from '@playwright/test';
test.slow(({ browserName }) => browserName === 'webkit', 'all tests are slow in Safari');
test('slow in Safari 1', async ({ page }) => {
// ...
});
test('fail in Safari 2', async ({ page }) => {
// ...
});
参数
¥Arguments
当条件为 true
时,测试标记为 "slow"。
¥Test is marked as "slow" when the condition is true
.
一个函数,根据测试夹具返回是否标记为 "slow"。当返回值为 true
时,一个或多个测试被标记为 "slow"。
¥A function that returns whether to mark as "slow", based on test fixtures. Test or tests are marked as "slow" when the return value is true
.
将反映在测试报告中的可选描述。
¥Optional description that will be reflected in a test report.
test.step
Added in: v1.10声明报告中显示的测试步骤。
¥Declares a test step that is shown in the report.
用法
¥Usage
import { test, expect } from '@playwright/test';
test('test', async ({ page }) => {
await test.step('Log in', async () => {
// ...
});
await test.step('Outer step', async () => {
// ...
// You can nest steps inside each other.
await test.step('Inner step', async () => {
// ...
});
});
});
参数
¥Arguments
步骤名称。
¥Step name.
步体。
¥Step body.
是否在报告中对步骤进行框选。默认为 false
。当步骤被装箱时,从步骤内部抛出的错误指向步骤调用站点。请参阅下面的更多细节。
¥Whether to box the step in the report. Defaults to false
. When the step is boxed, errors thrown from the step internals point to the step call site. See below for more details.
为要在测试报告和跟踪查看器中显示的步骤指定自定义位置。默认情况下,会显示 test.step() 调用的位置。
¥Specifies a custom location for the step to be shown in test reports and trace viewer. By default, location of the test.step() call is shown.
返回
¥Returns
细节
¥Details
该方法返回步骤回调返回的值。
¥The method returns the value returned by the step callback.
import { test, expect } from '@playwright/test';
test('test', async ({ page }) => {
const user = await test.step('Log in', async () => {
// ...
return 'john';
});
expect(user).toBe('john');
});
装饰器
¥Decorator
你可以使用 TypeScript 方法装饰器将方法转变为步骤。对修饰方法的每次调用都将显示为报告中的一个步骤。
¥You can use TypeScript method decorators to turn a method into a step. Each call to the decorated method will show up as a step in the report.
function step(target: Function, context: ClassMethodDecoratorContext) {
return function replacementMethod(...args: any) {
const name = this.constructor.name + '.' + (context.name as string);
return test.step(name, async () => {
return await target.call(this, ...args);
});
};
}
class LoginPage {
constructor(readonly page: Page) {}
@step
async login() {
const account = { username: 'Alice', password: 's3cr3t' };
await this.page.getByLabel('Username or email address').fill(account.username);
await this.page.getByLabel('Password').fill(account.password);
await this.page.getByRole('button', { name: 'Sign in' }).click();
await expect(this.page.getByRole('button', { name: 'View profile and more' })).toBeVisible();
}
}
test('example', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.login();
});
装入盒中
¥Boxing
当步骤内的某些内容失败时,你通常会看到错误指向失败的确切操作。例如,考虑以下登录步骤:
¥When something inside a step fails, you would usually see the error pointing to the exact action that failed. For example, consider the following login step:
async function login(page) {
await test.step('login', async () => {
const account = { username: 'Alice', password: 's3cr3t' };
await page.getByLabel('Username or email address').fill(account.username);
await page.getByLabel('Password').fill(account.password);
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page.getByRole('button', { name: 'View profile and more' })).toBeVisible();
});
}
test('example', async ({ page }) => {
await page.goto('https://github.com/login');
await login(page);
});
Error: Timed out 5000ms waiting for expect(locator).toBeVisible()
... error details omitted ...
8 | await page.getByRole('button', { name: 'Sign in' }).click();
> 9 | await expect(page.getByRole('button', { name: 'View profile and more' })).toBeVisible();
| ^
10 | });
正如我们在上面看到的,测试可能会失败,并出现指向步骤内部的错误。如果你希望错误高亮 "login" 步骤而不是其内部,请使用 box
选项。装箱步骤内的错误指向步骤调用站点。
¥As we see above, the test may fail with an error pointing inside the step. If you would like the error to highlight the "login" step instead of its internals, use the box
option. An error inside a boxed step points to the step call site.
async function login(page) {
await test.step('login', async () => {
// ...
}, { box: true }); // Note the "box" option here.
}
Error: Timed out 5000ms waiting for expect(locator).toBeVisible()
... error details omitted ...
14 | await page.goto('https://github.com/login');
> 15 | await login(page);
| ^
16 | });
你还可以为盒装步骤创建 TypeScript 装饰器,类似于上面的常规步骤装饰器:
¥You can also create a TypeScript decorator for a boxed step, similar to a regular step decorator above:
function boxedStep(target: Function, context: ClassMethodDecoratorContext) {
return function replacementMethod(...args: any) {
const name = this.constructor.name + '.' + (context.name as string);
return test.step(name, async () => {
return await target.call(this, ...args);
}, { box: true }); // Note the "box" option here.
};
}
class LoginPage {
constructor(readonly page: Page) {}
@boxedStep
async login() {
// ....
}
}
test('example', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.login(); // <-- Error will be reported on this line.
});
test.use
Added in: v1.10指定要在单个测试文件或 test.describe() 组中使用的选项或装置。最有用的是设置一个选项,例如设置 locale
来配置 context
夹具。
¥Specifies options or fixtures to use in a single test file or a test.describe() group. Most useful to set an option, for example set locale
to configure context
fixture.
用法
¥Usage
import { test, expect } from '@playwright/test';
test.use({ locale: 'en-US' });
test('test with locale', async ({ page }) => {
// Default context and page have locale as specified
});
参数
¥Arguments
options
TestOptions#
具有本地选项的对象。
¥An object with local options.
细节
¥Details
test.use
可以在全局作用域内调用,也可以在 test.describe
内部调用。在 beforeEach
或 beforeAll
内调用是错误的。
¥test.use
can be called either in the global scope or inside test.describe
. It is an error to call it within beforeEach
or beforeAll
.
还可以通过提供函数来覆盖夹具。
¥It is also possible to override a fixture by providing a function.
import { test, expect } from '@playwright/test';
test.use({
locale: async ({}, use) => {
// Read locale from some configuration file.
const locale = await fs.promises.readFile('test-locale', 'utf-8');
await use(locale);
},
});
test('test with locale', async ({ page }) => {
// Default context and page have locale as specified
});
属性
¥Properties
test.expect
Added in: v1.10expect
函数可用于创建测试断言。了解有关 测试断言 的更多信息。
¥expect
function can be used to create test assertions. Read more about test assertions.
用法
¥Usage
test('example', async ({ page }) => {
await test.expect(page).toHaveTitle('Title');
});
类型
¥Type
已弃用
¥Deprecated
test.describe.parallel
Added in: v1.10请参阅 test.describe.configure() 了解配置执行模式的首选方法。
¥See test.describe.configure() for the preferred way of configuring the execution mode.
声明一组可以并行运行的测试。默认情况下,单个测试文件中的测试依次运行,但使用 test.describe.parallel() 允许它们并行运行。
¥Declares a group of tests that could be run in parallel. By default, tests in a single test file run one after another, but using test.describe.parallel() allows them to run in parallel.
-
test.describe.parallel(title, callback)
-
test.describe.parallel(callback)
-
test.describe.parallel(title, details, callback)
用法
¥Usage
test.describe.parallel('group', () => {
test('runs in parallel 1', async ({ page }) => {});
test('runs in parallel 2', async ({ page }) => {});
});
请注意,并行测试在单独的进程中执行,不能共享任何状态或全局变量。每个并行测试都会执行所有相关的钩子。
¥Note that parallel tests are executed in separate processes and cannot share any state or global variables. Each of the parallel tests executes all relevant hooks.
你也可以省略标题。
¥You can also omit the title.
test.describe.parallel(() => {
// ...
});
参数
¥Arguments
组标题。
¥Group title.
详细说明见 test.describe()。
¥See test.describe() for details description.
调用 test.describe.parallel() 时立即运行的回调。此回调中添加的任何测试都将属于该组。
¥A callback that is run immediately when calling test.describe.parallel(). Any tests added in this callback will belong to the group.
test.describe.parallel.only
Added in: v1.10请参阅 test.describe.configure() 了解配置执行模式的首选方法。
¥See test.describe.configure() for the preferred way of configuring the execution mode.
声明一组可以并行运行的重点测试。这与 test.describe.parallel() 类似,但以群体为重点。如果有一些重点测试或套件,那么所有这些测试或套件都将运行,但不会运行其他测试。
¥Declares a focused group of tests that could be run in parallel. This is similar to test.describe.parallel(), but focuses the group. If there are some focused tests or suites, all of them will be run but nothing else.
-
test.describe.parallel.only(title, callback)
-
test.describe.parallel.only(callback)
-
test.describe.parallel.only(title, details, callback)
用法
¥Usage
test.describe.parallel.only('group', () => {
test('runs in parallel 1', async ({ page }) => {});
test('runs in parallel 2', async ({ page }) => {});
});
你也可以省略标题。
¥You can also omit the title.
test.describe.parallel.only(() => {
// ...
});
参数
¥Arguments
组标题。
¥Group title.
详细说明见 test.describe()。
¥See test.describe() for details description.
调用 test.describe.parallel.only() 时立即运行的回调。此回调中添加的任何测试都将属于该组。
¥A callback that is run immediately when calling test.describe.parallel.only(). Any tests added in this callback will belong to the group.
test.describe.serial
Added in: v1.10请参阅 test.describe.configure() 了解配置执行模式的首选方法。
¥See test.describe.configure() for the preferred way of configuring the execution mode.
声明一组应始终串行运行的测试。如果其中一项测试失败,则跳过所有后续测试。一组中的所有测试都会一起重试。
¥Declares a group of tests that should always be run serially. If one of the tests fails, all subsequent tests are skipped. All tests in a group are retried together.
不建议使用串口。通常最好将测试隔离起来,这样它们就可以独立运行。
¥Using serial is not recommended. It is usually better to make your tests isolated, so they can be run independently.
-
test.describe.serial(title, callback)
-
test.describe.serial(title)
-
test.describe.serial(title, details, callback)
用法
¥Usage
test.describe.serial('group', () => {
test('runs first', async ({ page }) => {});
test('runs second', async ({ page }) => {});
});
你也可以省略标题。
¥You can also omit the title.
test.describe.serial(() => {
// ...
});
参数
¥Arguments
组标题。
¥Group title.
详细说明见 test.describe()。
¥See test.describe() for details description.
调用 test.describe.serial() 时立即运行的回调。此回调中添加的任何测试都将属于该组。
¥A callback that is run immediately when calling test.describe.serial(). Any tests added in this callback will belong to the group.
test.describe.serial.only
Added in: v1.10请参阅 test.describe.configure() 了解配置执行模式的首选方法。
¥See test.describe.configure() for the preferred way of configuring the execution mode.
声明一组应始终连续运行的重点测试。如果其中一项测试失败,则跳过所有后续测试。一组中的所有测试都会一起重试。如果有一些重点测试或套件,那么所有这些测试或套件都将运行,但不会运行其他测试。
¥Declares a focused group of tests that should always be run serially. If one of the tests fails, all subsequent tests are skipped. All tests in a group are retried together. If there are some focused tests or suites, all of them will be run but nothing else.
不建议使用串口。通常最好将测试隔离起来,这样它们就可以独立运行。
¥Using serial is not recommended. It is usually better to make your tests isolated, so they can be run independently.
-
test.describe.serial.only(title, callback)
-
test.describe.serial.only(title)
-
test.describe.serial.only(title, details, callback)
用法
¥Usage
test.describe.serial.only('group', () => {
test('runs first', async ({ page }) => {
});
test('runs second', async ({ page }) => {
});
});
你也可以省略标题。
¥You can also omit the title.
test.describe.serial.only(() => {
// ...
});
参数
¥Arguments
组标题。
¥Group title.
详细说明见 test.describe()。
¥See test.describe() for details description.
调用 test.describe.serial.only() 时立即运行的回调。此回调中添加的任何测试都将属于该组。
¥A callback that is run immediately when calling test.describe.serial.only(). Any tests added in this callback will belong to the group.