Fixtures в Playwright — это механизм подготовки и управления
состоянием окружения для тестов. Они позволяют централизованно
определять объекты, которые могут быть переиспользованы в разных тестах,
управлять жизненным циклом этих объектов и обеспечивать изоляцию тестов.
Playwright поставляется с набором встроенных fixtures, таких как
page, browser, context, но в
реальных проектах часто требуется создавать кастомные fixtures под
конкретные нужды.
Кастомный fixture определяется с помощью метода
test.extend, который позволяет расширить стандартный объект
test собственными объектами. Основные моменты:
use.'test' (по умолчанию) или 'worker'.
test создаёт отдельный экземпляр для каждого теста,
worker создаёт один экземпляр на весь воркер.Пример простого кастомного fixture:
const { test } = require('@playwright/test');
const customTest = test.extend({
userData: async ({}, use) => {
const user = { name: 'John Doe', role: 'admin' };
await use(user); // Передаём объект тесту
}
});
customTest('проверка имени пользователя', async ({ userData }) => {
console.log(userData.name); // John Doe
});
Fixtures часто требуют асинхронной подготовки, например, создание пользователя через API или подключение к базе данных. Playwright поддерживает асинхронные операции внутри fixture:
const customTest = test.extend({
dbConnection: async ({}, use) => {
const connection = await createDatabaseConnection(); // асинхронная инициализация
await use(connection);
await connection.close(); // автоматическое закрытие после теста
}
});
customTest('запрос к базе', async ({ dbConnection }) => {
const result = await dbConnection.query('SELECT * FROM users');
console.log(result);
});
Ключевой момент: всё, что создаётся внутри fixture, должно корректно очищаться после использования, чтобы избежать утечек памяти и конфликтов между тестами.
Fixtures могут зависеть друг от друга. Playwright обеспечивает автоматическое разрешение зависимостей на основе параметров функции:
const customTest = test.extend({
authToken: async ({ dbConnection }, use) => {
const token = await generateTokenFromDB(dbConnection, 'admin');
await use(token);
}
});
customTest('тест с авторизацией', async ({ authToken }) => {
console.log(authToken); // Токен, полученный через зависимый fixture
});
Важно: порядок передачи аргументов в fixture имеет значение, Playwright создаёт зависимости автоматически, но нужно избегать циклических ссылок.
Scope определяет, как часто создаётся объект fixture:
worker), что экономит ресурсы для тяжёлых
объектов.Пример:
const customTest = test.extend({
sharedResource: [
async ({}, use) => {
const resource = await setupHeavyResource();
await use(resource);
await resource.cleanup();
},
{ scope: 'worker' }
]
});
Fixtures можно параметризовать для тестирования с разными конфигурациями:
const customTest = test.extend({
apiUrl: async ({}, use, testInfo) => {
const env = testInfo.project.name; // различие между проектами
const url = env === 'staging' ? 'https://staging.api' : 'https://prod.api';
await use(url);
}
});
customTest('тест API', async ({ apiUrl }) => {
console.log(`API URL: ${apiUrl}`);
});
scope: 'worker' для тяжёлых
объектов: базы данных, внешние сервисы, браузеры.testInfo.project.name для работы с разными
окружениями.const customTest = test.extend({
db: async ({}, use) => {
const connection = await createDatabaseConnection();
await use(connection);
await connection.close();
},
testUser: async ({ db }, use) => {
const user = await db.createUser({ name: 'Alice' });
await use(user);
await db.deleteUser(user.id);
},
authToken: async ({ testUser }, use) => {
const token = await generateToken(testUser);
await use(token);
}
});
customTest('полный сценарий', async ({ authToken, testUser }) => {
console.log(authToken); // Токен для Alice
console.log(testUser.name); // Alice
});
В этом примере:
db создаёт соединение с базой данных и
закрывает его после теста.testUser создаёт временного пользователя и
удаляет его.authToken зависит от testUser и
генерирует токен авторизации.Создание кастомных fixtures позволяет строить масштабируемую, поддерживаемую инфраструктуру тестов, облегчает управление ресурсами и изоляцию тестов. Их грамотное использование критически важно для проектов с большим количеством автоматизированных сценариев.