Фикстуры Playwright и параметризация
В этой главе рассказывается о механизме фикстур Playwright, о том, как создавать собственные фикстуры, и о приёмах параметризованного тестирования.
Что такое фикстура
Фикстура — это механизм внедрения зависимостей для параметров тестовых функций Playwright.
Каждый тест получает необходимые фикстуры путём деструктуризации параметров (например,{ page }), а Playwright управляет созданием и очисткой.
Пример
test('Использование встроенных фикстур', async ({ page, context }) => {
// Playwright автоматически создаёт page и context
// Автоматически очищается после завершения теста
await page.goto('https://www.example.com/');
});
Краткий справочник по встроенным фикстурам
| Фикстура | Type | Описание |
|---|---|---|
page | Page | Независимая вкладка браузера |
context | BrowserContext | Контекст браузера |
browser | Браузер | Экземпляр браузера |
browserName | string | Имя текущего браузера |
request | APIRequestContext | Клиент HTTP-запросов |
Пользовательские фикстуры
Черезtest.extend()Создавайте пользовательские фикстуры, чтобы внедрять дополнительные зависимости или переопределять встроенные фикстуры.
Пример
import { test as base, expect } from '@playwright/test';
// Определите тип пользовательской фикстуры
type MyFixtures = {
todoPage: { goto: () => Promise<void>; addTodo: (text: string) => Promise<void> };
authenticatedPage: any;
};
export const test = base.extend<MyFixtures>({
// Пользовательская фикстура: объект страницы Todo
todoPage: async ({ page }, use) => {
// Создать
const todoPage = {
goto: async () => {
await page.goto('https://demo.playwright.dev/todomvc');
},
addTodo: async (text: string) => {
await page.getByPlaceholder('Что нужно сделать?').fill(text);
await page.keyboard.press('Enter');
},
};
// Внедрить в тест
await use(todoPage);
// Логика очистки (при необходимости)
},
// Пользовательская фикстура: аутентифицированная страница
authenticatedPage: async ({ browser }, use) => {
const context = await browser.newContext({
storageState: 'playwright/.auth/user.json',
});
const page = await context.newPage();
await use(page);
await context.close();
},
});
export { expect };
Использование пользовательских фикстур
Пример
import { test, expect } from './fixtures';
test('Add Todo', async ({ todoPage }) => {
await todoPage.goto();
await todoPage.addTodo('Learn Playwright');
await todoPage.addTodo('Master Fixtures');
// Проверить...
});
Области действия фикстур
Фикстуры имеют три области действия, управляемые с помощьюscopeпараметр.
| Область действия | Значение | Жизненный цикл |
|---|---|---|
| Уровень теста (по умолчанию) | scope: 'test' | Создаётся один раз для каждого теста |
| Уровень воркера | scope: 'worker' | Создаётся один раз для каждого процесса воркера и используется всеми тестами в одном воркере |
Пример
const test = base.extend({
sharedResource: [async ({}, use) => {
const resource = await createExpensiveResource();
await use(resource);
await resource.dispose();
}, { scope: 'worker' }], // Обратите внимание на синтаксис массива
});
Фикстуры уровня Worker являются общими для нескольких тестов в рамках одного процесса Worker и подходят для ресурсов с высокими накладными расходами на создание, таких как подключения к базе данных.
Переопределение встроенных фикстур
Вы можете переопределить встроенные фикстуры, чтобы изменить поведение по умолчанию.
Пример
// Переопределите встроенную фикстуру page, чтобы изменить область просмотра по умолчанию
page: async ({ baseURL, page }, use) => {
await page.setViewportSize({ width: 1920, height: 1080 });
await use(page);
},
// Переопределить storageState
storageState: 'playwright/.auth/admin.json',
});
Автоматическая очистка фикстуры
Логика очистки фикстуры выполняется послеuse()вызова, аналогично эффектуafterEach.
Пример
tempUser: async ({ request }, use) => {
// Создать временного пользователя
const resp = await request.post('/api/users', {
data: { name: 'temp_' + Date.now() },
});
const user = await resp.json();
// Внедрить в тест
await use(user);
// Автоматическая очистка: удалить временного пользователя
await request.delete(`/api/users/${user.id}`);
},
});
Параметризованные тесты
Playwright не имеет встроенного механизма параметризации, но тесты можно динамически генерировать с помощью циклов.
Пример
const testCases = [
{ username: 'admin', password: 'admin123', expected: 'Панель управления' },
{ username: 'user', password: 'user123', expected: 'Личный кабинет' },
{ username: 'guest', password: 'guest123', expected: 'Страница посетителя' },
];
for (const { username, password, expected } of testCases) {
test(`Пользователь ${username}видит $ после входа в систему{expected}`, async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Username').fill(username);
await page.getByLabel('Password').fill(password);
await page.getByRole('button', { name: 'Login' }).click();
await expect(page.getByText(expected)).toBeVisible();
});
}
Аннотации тестов
Аннотации используются для добавления метаданных к тестам, которые можно просматривать и фильтровать в репортере.
Пример
// Добавить аннотацию (внутри тела тестовой функции)
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/example/bug/123',
});
test.info().annotations.push({
type: 'description',
description: 'Этот тест покрывает все ветки процесса входа',
});
// Логика теста...
});
// Использование тега (в имени теста)
test('Быстрый дымовой тест @smoke @critical', async ({ page }) => {
// Вы можете запустить только этот тест с помощью npx playwright test --grep "@smoke"
});