Глобальная настройка и завершение
Введение
Существует два способа настройки глобальной инициализации и завершения: использование глобального файла настройки и установка в конфигурации через globalSetup
или использование зависимостей проекта. С помощью зависимостей проекта вы определяете проект, который запускается перед всеми другими проектами. Это рекомендуемый способ настройки глобальной инициализации, так как с зависимостями проекта ваш HTML-отчет будет показывать глобальную настройку, средство просмотра трассировки будет записывать трассировку настройки, и можно использовать фикстуры.
Вариант 1: Зависимости проекта
Зависимости проекта — это список проектов, которые должны быть выполнены перед запуском тестов в другом проекте. Они могут быть полезны для настройки глобальных действий, чтобы один проект зависел от выполнения другого. Использование зависимостей позволяет глобальной настройке создавать трассировки и другие артефакты.
Настройка
Сначала мы добавляем новый проект с именем '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/,
},
// {
// другой проект
// }
]
});
Затем мы добавляем свойство 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...');
// Инициализация базы данных
});
import { test, expect } from '@playwright/test';
test('menu', async ({ page }) => {
// Ваш тест, который зависит от базы данных
});
Завершение
Вы можете завершить настройку, добавив свойство testProject.teardown к вашему проекту настройки. Это будет выполнено после того, как все зависимые проекты будут выполнены.
Сначала мы добавляем свойство testProject.teardown к нашему проекту настройки с именем 'cleanup db', которое мы дали нашему проекту завершения на предыдущем шаге:
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...');
// Удаление базы данных
});
Больше примеров
Для более подробных примеров ознакомьтесь с:
- нашим руководством по аутентификации
- нашим блогом Лучший глобальный сетап в Playwright с повторным использованием входа с зависимостями проекта
- видео о выпуске v1.31, чтобы увидеть демонстрацию
Вариант 2: Настройка globalSetup и globalTeardown
Вы можете использовать опцию globalSetup
в файле конфигурации, чтобы настроить что-то один раз перед запуском всех тестов. Глобальный файл настройки должен экспортировать одну функцию, которая принимает объект конфигурации. Эта функция будет выполнена один раз перед всеми тестами.
Аналогично, используйте globalTeardown
, чтобы выполнить что-то один раз после всех тестов. В качестве альтернативы, пусть globalSetup
возвращает функцию, которая будет использоваться как глобальное завершение. Вы можете передавать данные, такие как номер порта, токены аутентификации и т.д., из вашей глобальной настройки в ваши тесты, используя переменные окружения.
Будьте осторожны с ограничениями globalSetup
и globalTeardown
:
- Эти методы не будут создавать трассировки или артефакты, если они не включены явно, как описано в разделе Захват трассировки ошибок во время глобальной настройки.
- Опции, такие как
headless
илиtestIdAttribute
, указанные в файле конфигурации, не применяются. - Необработанное исключение, выброшенное в
globalSetup
, предотвратит выполнение тестов Playwright, и результаты тестов не появятся в отчетах.
Рассмотрите возможность использования зависимостей проекта, чтобы создавать трассировки, артефакты, учитывать параметры конфигурации и получать результаты тестов в отчетах даже в случае сбоя настройки.
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('/');
// Вы вошли в систему!
});
Вы можете сделать произвольные данные доступными в ваших тестах из вашего файла глобальной настройки, установив их как переменные окружения через process.env
.
import type { FullConfig } from '@playwright/test';
async function globalSetup(config: FullConfig) {
process.env.FOO = 'some data';
// Или более сложная структура данных в формате JSON:
process.env.BAR = JSON.stringify({ some: 'data' });
}
export default globalSetup;
Тесты имеют доступ к свойствам process.env
, установленным в глобальной настройке.
import { test } from '@playwright/test';
test('test', async ({ page }) => {
// переменные окружения, которые установлены в globalSetup, доступны только внутри test().
const { FOO, BAR } = process.env;
// Свойства FOO и BAR заполнены.
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;