Тестирование веб-приложений с использованием Playwright требует обеспечения независимости тестов от данных, что играет ключевую роль в поддержке стабильности и надежности тестов. Каждый тест должен быть изолирован и не зависеть от результатов выполнения других тестов или состояния данных на сервере. Важно, чтобы данные, используемые в тестах, были контролируемыми и предсказуемыми, а сама среда была подготовлена так, чтобы исключить влияние изменений в базе данных, которые могут привести к ошибкам или нестабильности тестов.
При неправильном подходе к изоляции тестов и данных, возникают следующие проблемы:
Для того чтобы избежать этих проблем, необходимо придерживаться принципов, обеспечивающих независимость тестов от данных.
Моки (mocks) и стабы (stubs) — это искусственные объекты, которые заменяют реальные зависимости в тестах. Они позволяют контролировать ответы, которые тестируемое приложение получает от внешних сервисов или базы данных. Мокирование внешних сервисов и API помогает изолировать тесты от реальных данных и делает их воспроизводимыми и независимыми.
Пример использования моков в Playwright:
import { test, expect } from '@playwright/test';
test('Тест с моком API', async ({ page }) => {
await page.route('https://api.example.com/data', (route) => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ key: 'value' })
});
});
await page.goto('https://example.com');
const result = await page.textContent('.result');
expect(result).toBe('value');
});
Для обеспечения консистентности данных можно использовать базу данных, специально подготовленную для тестов. Она должна быть изолированной от основной базы данных, и в ней должны содержаться только те данные, которые необходимы для тестов. Обычно это достигается с помощью автоматического сброса данных в базу перед каждым тестом.
Это можно сделать через механизмы, такие как:
Пример с использованием тестовой базы данных:
import { test, expect } from '@playwright/test';
import { resetTestDatabase, seedTestDatabase } from './database-utils';
test.beforeEach(async () => {
await resetTestDatabase();
await seedTestDatabase();
});
test('Проверка правильности отображения данных', async ({ page }) => {
await page.goto('https://example.com/data');
const result = await page.textContent('.data-list');
expect(result).toBe('Expected Data');
});
Фикстуры — это механизмы, которые обеспечивают подготовку и очистку данных или окружения перед каждым тестом. В Playwright можно использовать фикстуры для управления состоянием тестируемого приложения, загрузки тестовых данных и очистки после выполнения теста.
Использование фикстур помогает изолировать тесты и гарантировать, что каждый тест начинается с одинакового состояния.
Пример использования фикстуры:
import { test, expect } from '@playwright/test';
import { createTestUser, deleteTestUser } from './user-utils';
test.beforeEach(async () => {
const user = await createTestUser();
test.info().testData = user;
});
test.afterEach(async () => {
await deleteTestUser(test.info().testData.id);
});
test('Тест с фикстурой', async ({ page }) => {
const user = test.info().testData;
await page.goto(`/profile/${user.id}`);
const profileName = await page.textContent('.username');
expect(profileName).toBe(user.username);
});
Модульные тесты фокусируются на проверке отдельных компонентов, что также способствует изоляции от данных. В таких тестах можно подменять только необходимые компоненты, а все остальное — оставлять без изменений. Это минимизирует зависимость теста от внешних данных и позволяет гарантировать корректность работы каждой единицы приложения.
Пример модульного теста в Playwright:
import { test, expect } from '@playwright/test';
import { mockApiService } from './mock-api';
test('Модульный тест с подменой API', async ({ page }) => {
mockApiService({ response: { data: 'Test Data' } });
await page.goto('/home');
const result = await page.textContent('.api-result');
expect(result).toBe('Test Data');
});
Тесты, зависимые от времени или состояния внешних сервисов, требуют дополнительного внимания для обеспечения их независимости. В таких случаях полезно использовать подходы, которые позволяют «замораживать» время или фиксировать состояние внешних систем.
mockdate), чтобы
гарантировать предсказуемость выполнения тестов.Пример заморозки времени:
import { test, expect } from '@playwright/test';
import mockdate from 'mockdate';
test('Тест с замороженным временем', async ({ page }) => {
mockdate.set('2023-01-01T00:00:00Z');
await page.goto('/time');
const currentTime = await page.textContent('.current-time');
expect(currentTime).toBe('2023-01-01T00:00:00Z');
});
В идеале, тесты не должны обращаться к реальным внешним сервисам. Вместо этого можно использовать интерцепторы для управления сетевыми запросами, мокировать ответы от внешних сервисов или использовать имитации сервисов. Это позволяет избежать зависимости тестов от внешних ресурсов, которые могут быть недоступны, медленными или изменяться.
Пример с мокированием внешнего сервиса:
import { test, expect } from '@playwright/test';
test('Мокирование ответа от внешнего сервиса', async ({ page }) => {
await page.route('https://api.example.com/items', (route) => {
route.fulfill({
status: 200,
body: JSON.stringify([{ id: 1, name: 'Test Item' }])
});
});
await page.goto('/items');
const itemName = await page.textContent('.item-name');
expect(itemName).toBe('Test Item');
});
Независимость тестов от данных является неотъемлемой частью качественного тестирования с Playwright. Использование моков, фикстур, тестовых баз данных и других методов позволяет изолировать тесты от внешних факторов, таких как данные, состояние системы и время. Это способствует более стабильному и предсказуемому выполнению тестов, улучшая их надежность и снижая вероятность ошибок.