Большинство команд запускают весь Playwright-сьют после каждого деплоя и называют это регрессионным тестированием. Когда что-то ломается в продакшне в 23:00, 45-минутный сьют бесполезен: нужны 10 тестов подтверждающих что логин работает, API отвечает и основное действие пользователя выполняется. Статья разбирает разницу в назначении между smoke и регрессионным тестированием, как тегировать и структурировать оба вида в одном Playwright-сьюте, и когда запускать каждый.
Smoke-тестирование
Smoke-тест отвечает на один вопрос: система фундаментально работает?
Название пришло из тестирования железа: включи устройство, смотри не задымится ли. Прошёл эту проверку: стоит идти дальше. Нет: глубокое тестирование бессмысленно.
В программном обеспечении smoke-тест: небольшое быстрое подмножество тестов которое верифицирует что самые критичные пути работают. Обычно 10–20 тестов, выполняемых менее чем за 5 минут.
Что покрывают smoke-тесты
- Приложение запускается и загружается
- Аутентификация работает
- Самое критичное действие пользователя выполняется (размещение заказа, отправка формы, платёж)
- Основные API-эндпоинты отвечают
Что smoke-тесты не покрывают
- Edge case
- Состояния ошибок
- Второстепенные фичи
- Производительность под нагрузкой
Когда запускать smoke-тесты
- После каждого деплоя (даже в продакшн)
- После изменений инфраструктуры (перезапуски серверов, изменения конфигурации)
- Как первый шаг в CI, до запуска полного сьюта
- Когда нужна быстрая санитарная проверка перед демо
Пример smoke-теста в Playwright
// smoke.spec.ts
import { test, expect } from '@playwright/test';
test.describe('@smoke', () => {
test('app loads', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveTitle(/MyApp/);
await expect(page.getByRole('navigation')).toBeVisible();
});
test('login works', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill(process.env.TEST_USER_EMAIL!);
await page.getByLabel('Password').fill(process.env.TEST_USER_PASSWORD!);
await page.getByRole('button', { name: 'Log in' }).click();
await expect(page).toHaveURL('/dashboard');
});
test('core API is responding', async ({ request }) => {
const response = await request.get('/api/health');
expect(response.status()).toBe(200);
const body = await response.json();
expect(body.status).toBe('ok');
});
test('order placement works end to end', async ({ page }) => {
// сокращённый критический путь
await page.goto('/products');
await page.getByRole('link', { name: 'Laptop Pro' }).click();
await page.getByRole('button', { name: 'Add to cart' }).click();
await page.goto('/checkout');
// ... минимальные шаги чекаута
await expect(page.getByText('Order confirmed')).toBeVisible();
});
});Запустить только smoke-тесты:
npx playwright test --grep @smokeРегрессионное тестирование
Регрессионный тест-сьют верифицирует что существующая функциональность продолжает работать после изменения. Вопрос не "работает ли система вообще", а "сломали ли мы что-то что работало раньше".
Регрессионные тесты шире и медленнее smoke-тестов. Полный регрессионный сьют может покрывать сотни сценариев и выполняться 20–60 минут.
Что покрывают регрессионные тесты
- Все фичи включая второстепенные сценарии и edge case
- Обработку ошибок
- Граничные условия
- Кросс-браузерное поведение
- Точки интеграции между сервисами
Когда запускать регрессионные тесты
- Перед каждым релизом
- После значимых изменений кода (новые фичи, рефакторинг)
- На основной ветке после мержа PR
- Ночью для больших сьютов
Виды регрессионного тестирования
Полная регрессия: каждый тест в сьюте. Запускается перед крупными релизами. Частичная/целевая регрессия: тесты в областях связанных с недавними изменениями. Запускается чаще. Требует знания какие тесты покрывают какие фичи. Автоматизированная регрессия: твой Playwright-сьют. Запускается в CI. Основная часть регрессионного покрытия. Ручная исследовательская регрессия: QA-инженер исследует области наиболее вероятно затронутые изменением. Ловит то что пропускают автотесты.Ключевые различия
| | Smoke-тестирование | Регрессионное тестирование |
|---|---|---|
| Цель | Система жива? | Мы что-то сломали? |
| Охват | Только критические пути | Все фичи |
| Скорость | Быстро (2–5 мин) | Медленно (20–60+ мин) |
| Частота | Каждый деплой | Перед релизами, после изменений |
| Количество тестов | 10–30 | Сотни–тысячи |
| При сбое | Откат или стоп | Исправить до релиза |
Правильное разделение сьюта
Большинство команд запускают весь сьют как регрессию и не имеют выделенного smoke-слоя. Это создаёт проблему: когда деплоишь в продакшн и что-то не так, быстро верифицировать критические пути не получится, потому что 45-минутный полный регрессионный сьют: не тот инструмент.
Лучшая структура:
@smoke (запускать на каждый деплой, максимум 5 мин)
├── Приложение загружается
├── Аутентификация работает
├── Основная фича выполняется
@regression (запускать перед релизом, 30-60 мин)
├── @smoke тесты (включены)
├── Все остальные тесты фич
├── Edge case
└── Кросс-браузерные тестыТегируй самые критичные тесты @smoke. Запускай их после каждого деплоя. Запускай полный сьют перед каждым релизом.
Что не является регрессионным тестированием
Юнит-тесты: верифицируют изолированные функции. Это не регрессионные тесты в QA-смысле, это тесты разработчиков. Нагрузочные тесты: измеряют скорость и ёмкость, а не функциональную корректность. Smoke-тестирование: как описано выше, другой охват и назначение. Исследовательское тестирование: нескриптованное обнаружение новых багов, не верификация существующего поведения.Путаница возникает из-за перегруженности слова "регрессия": в обиходном использовании любой автоматизированный тест запускающийся после изменения называют регрессионным. В формальном использовании регрессионное тестирование конкретно означает верификацию что ранее работавшая функциональность продолжает работать.
Оба варианта нормальны на практике. Важно понимать что именно верифицируешь и зачем.
→ See also: Пирамида тестирования: объяснение для QA-инженеров | Запуск тестов Playwright из CLI: флаги, фильтры и отладка | Параллельное выполнение в Playwright: workers, шарды и шардирование для ускорения