跳转到主要内容

全局设置和清理

简介

有两种方法配置全局设置和清理:使用全局设置文件并在配置中的 globalSetup 中设置,或者使用 项目依赖。 使用项目依赖,您可以定义一个在所有其他项目之前运行的项目。 这是配置全局设置的推荐方式,因为使用项目依赖,您的 HTML 报告将显示全局设置,trace viewer 将记录设置的跟踪,并且可以使用 fixtures。

选项 1:项目依赖

项目依赖是需要在另一个项目中的测试运行之前运行的项目列表。 它们对于配置全局设置操作非常有用,以便一个项目依赖于首先运行的项目。 使用依赖关系允许全局设置生成跟踪和其他工件。

设置

首先,我们添加一个名为 “setup db” 的新项目。 然后,我们为其提供一个 testProject.testMatch 属性,以便匹配名为 global.setup.ts 的文件

playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
testDir: './tests',
// ...
projects: [
{
name: 'setup db',
testMatch: /global\.setup\.ts/,
},
// {
// other project
// }
]
});

然后,我们将 testProject.dependencies 属性添加到依赖于设置项目的项目中,并将我们在上一步中定义的依赖项目名称传递到数组中

playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
testDir: './tests',
// ...
projects: [
{
name: 'setup db',
testMatch: /global\.setup\.ts/,
},
{
name: 'chromium with db',
use: { ...devices['Desktop Chrome'] },
dependencies: ['setup db'],
},
]
});

在本示例中,“chromium with db” 项目依赖于 “setup db” 项目。 然后,我们创建一个设置测试,存储在项目的根级别(请注意,设置和清理代码必须通过调用 test() 函数定义为常规测试)

tests/global.setup.ts
import { test as setup } from '@playwright/test';

setup('create new database', async ({ }) => {
console.log('creating new database...');
// Initialize the database
});
tests/menu.spec.ts
import { test, expect } from '@playwright/test';

test('menu', async ({ page }) => {
// Your test that depends on the database
});

清理

您可以通过将 testProject.teardown 属性添加到您的设置项目来清理您的设置。 这将在所有依赖项目运行后运行。

首先,我们将 testProject.teardown 属性添加到我们的设置项目,名称为 “cleanup db”,这是我们在上一步中为清理项目提供的名称

playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
testDir: './tests',
// ...
projects: [
{
name: 'setup db',
testMatch: /global\.setup\.ts/,
teardown: 'cleanup db',
},
{
name: 'cleanup db',
testMatch: /global\.teardown\.ts/,
},
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
dependencies: ['setup db'],
},
]
});

然后,我们在项目的 tests 目录中创建一个 global.teardown.ts 文件。 这将用于在所有测试运行后从数据库中删除数据。

tests/global.teardown.ts
import { test as teardown } from '@playwright/test';

teardown('delete database', async ({ }) => {
console.log('deleting test database...');
// Delete the database
});

更多示例

有关更详细的示例,请查看

选项 2:配置 globalSetup 和 globalTeardown

您可以使用 配置文件 中的 globalSetup 选项来在运行所有测试之前设置一次内容。 全局设置文件必须导出一个接受配置对象的单个函数。 此函数将在所有测试之前运行一次。

类似地,使用 globalTeardown 在所有测试之后运行一次内容。 或者,让 globalSetup 返回一个将用作全局清理的函数。 您可以使用环境变量将端口号、身份验证令牌等数据从全局设置传递到您的测试。

注意

注意 globalSetupglobalTeardown 的注意事项

  • 除非显式启用,否则这些方法不会生成跟踪或工件,如 捕获全局设置期间的故障跟踪 中所述。
  • 配置文件中指定的诸如 headlesstestIdAttribute 等选项不适用,
  • globalSetup 中抛出的未捕获异常将阻止 Playwright 运行测试,并且报告器中不会显示任何测试结果。

考虑使用 项目依赖 来生成跟踪、工件,遵守配置选项,并在即使在设置失败的情况下也能在报告器中获得测试结果。

playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
globalSetup: require.resolve('./global-setup'),
globalTeardown: require.resolve('./global-teardown'),
});

示例

这是一个全局设置示例,该示例进行一次身份验证并在测试中重用身份验证状态。 它使用配置文件中的 baseURLstorageState 选项。

global-setup.ts
import { chromium, type FullConfig } from '@playwright/test';

async function globalSetup(config: FullConfig) {
const { baseURL, storageState } = config.projects[0].use;
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(baseURL!);
await page.getByLabel('User Name').fill('user');
await page.getByLabel('Password').fill('password');
await page.getByText('Sign in').click();
await page.context().storageState({ path: storageState as string });
await browser.close();
}

export default globalSetup;

在配置文件中指定 globalSetupbaseURLstorageState

playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
globalSetup: require.resolve('./global-setup'),
use: {
baseURL: 'https://127.0.0.1:3000/',
storageState: 'state.json',
},
});

测试已启动并已通过身份验证,因为我们指定了由全局设置填充的 storageState

import { test } from '@playwright/test';

test('test', async ({ page }) => {
await page.goto('/');
// You are signed in!
});

您可以通过将任意数据通过 process.env 设置为环境变量,从而使其在全局设置文件中的测试中可用。

global-setup.ts
import type { FullConfig } from '@playwright/test';

async function globalSetup(config: FullConfig) {
process.env.FOO = 'some data';
// Or a more complicated data structure as JSON:
process.env.BAR = JSON.stringify({ some: 'data' });
}

export default globalSetup;

测试可以访问在全局设置中设置的 process.env 属性。

import { test } from '@playwright/test';

test('test', async ({ page }) => {
// environment variables which are set in globalSetup are only available inside test().
const { FOO, BAR } = process.env;

// FOO and BAR properties are populated.
expect(FOO).toEqual('some data');

const complexData = JSON.parse(BAR);
expect(BAR).toEqual({ some: 'data' });
});

捕获全局设置期间的故障跟踪

在某些情况下,捕获全局设置期间遇到的故障跟踪可能很有用。 为了做到这一点,您必须在设置中 开始跟踪,并且您必须确保在抛出错误之前 停止跟踪(如果发生错误)。 这可以通过将您的设置包装在 try...catch 块中来实现。 这是一个扩展全局设置示例以捕获跟踪的示例。

global-setup.ts
import { chromium, type FullConfig } from '@playwright/test';

async function globalSetup(config: FullConfig) {
const { baseURL, storageState } = config.projects[0].use;
const browser = await chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();
try {
await context.tracing.start({ screenshots: true, snapshots: true });
await page.goto(baseURL!);
await page.getByLabel('User Name').fill('user');
await page.getByLabel('Password').fill('password');
await page.getByText('Sign in').click();
await context.storageState({ path: storageState as string });
await context.tracing.stop({
path: './test-results/setup-trace.zip',
});
await browser.close();
} catch (error) {
await context.tracing.stop({
path: './test-results/failed-setup-trace.zip',
});
await browser.close();
throw error;
}
}

export default globalSetup;