全局设置和拆卸
简介
There are two ways to configure global setup and teardown: using a global setup file and setting it in the config under globalSetup or using project dependencies. With project dependencies, you define a project that runs before all other projects. This is the recommended way to configure global setup as with Project dependencies your HTML report will show the global setup, trace viewer will record a trace of the setup and fixtures can be used.
选项1:项目依赖项
Project dependencies 项目依赖项是指在另一个项目中的测试运行之前需要先运行的项目列表。它们可用于配置全局设置操作,使一个项目依赖于首先运行的这些操作。使用依赖项可以让全局设置生成跟踪记录和其他产物。
设置
首先我们添加一个名为'setup db'的新项目。然后我们给它一个testProject.testMatch属性,以便匹配名为global.setup.ts的文件:
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
// ...
projects: [
{
name: 'setup db',
testMatch: /global\.setup\.ts/,
},
// {
// other project
// }
]
});
然后我们在依赖设置项目的项目中添加testProject.dependencies属性,并将我们在上一步中定义的依赖项目名称传入数组:
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()函数定义为常规测试):
import { test as setup } from '@playwright/test';
setup('create new database', async ({ }) => {
console.log('creating new database...');
// Initialize the database
});
import { test, expect } from '@playwright/test';
test('menu', async ({ page }) => {
// Your test that depends on the database
});
拆卸
您可以通过在设置项目中添加testProject.teardown属性来拆除您的设置。这将在所有依赖项目运行后执行。
首先我们在设置项目中添加名为'cleanup db'的testProject.teardown属性,这个名称是我们在上一步中为清理项目所命名的:
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'],
},
]
});
然后我们在项目的测试目录中创建一个global.teardown.ts文件。这将在所有测试运行完毕后用于从数据库中删除数据。
import { test as teardown } from '@playwright/test';
teardown('delete database', async ({ }) => {
console.log('deleting test database...');
// Delete the database
});
更多示例
更多详细示例请查看:
- 我们的authentication指南
- 我们的博客文章 在Playwright中通过项目依赖重用登录实现更好的全局设置
- v1.31 发布视频 查看演示
选项2:配置globalSetup和globalTeardown
您可以在配置文件中使用globalSetup选项,以便在运行所有测试前一次性设置某些内容。全局设置文件必须导出一个接收配置对象的函数。该函数将在所有测试运行前执行一次。
同样地,使用globalTeardown在所有测试完成后运行某些操作。或者,让globalSetup返回一个函数作为全局拆卸操作。您可以通过环境变量将端口号、认证令牌等数据从全局设置传递到测试中。
注意globalSetup和globalTeardown的注意事项:
- 除非明确启用,否则这些方法不会生成跟踪记录或产物,如Capturing trace of failures during global setup中所述。
- 配置文件中指定的选项如
headless或testIdAttribute不会被应用。 - 在
globalSetup中抛出的未捕获异常将阻止Playwright运行测试,并且报告中不会显示任何测试结果。
考虑使用project dependencies来生成跟踪记录、产物、遵守配置选项,并在设置失败的情况下也能在报告中获取测试结果。
import { defineConfig } from '@playwright/test';
export default defineConfig({
globalSetup: require.resolve('./global-setup'),
globalTeardown: require.resolve('./global-teardown'),
});
示例
这是一个全局设置示例,它进行一次身份验证并在测试中重复使用认证状态。它使用了配置文件中的baseURL和storageState选项。
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;
在配置文件中指定 globalSetup、baseURL 和 storageState。
import { defineConfig } from '@playwright/test';
export default defineConfig({
globalSetup: require.resolve('./global-setup'),
use: {
baseURL: 'http://localhost:3000/',
storageState: 'state.json',
},
});
测试开始时已经通过身份验证,因为我们指定了由全局设置填充的storageState。
import { test } from '@playwright/test';
test('test', async ({ page }) => {
await page.goto('/');
// You are signed in!
});
你可以通过在全局设置文件中将任意数据设置为process.env环境变量,使其在测试中可用。
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块中来实现。下面是一个扩展全局设置示例以捕获跟踪的示例。
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;