Для фичи чекаута нужны три E2E-теста, а не тридцать: один для happy path, один для ошибки платежа, один для товара не в наличии. Остальные edge case дешевле и стабильнее в виде юнит и API-тестов. Статья объясняет три слоя пирамиды, что происходит когда команды переворачивают её в мороженое, и современный вариант (тестовый трофей) который подходит для фронтенд-тяжёлых приложений.
Исходная модель
Майк Кон представил пирамиду тестирования в 2009 году. Исходная версия имела три слоя:
/\
/ \
/ E2E \ <- мало, медленно, дорого
/--------\
/ Integration\ <- умеренно
/--------------\
/ Unit Tests \ <- много, быстро, дёшево
/------------------\Форма имеет значение: много снизу, меньше наверху. Пирамида.
Почему форма важна
Если перевернуть пирамиду: много E2E-тестов, мало юнит-тестов, получаешь:
- Медленный сьют (E2E-тесты работают в 10–60 раз дольше юнит-тестов)
- Флакующие тесты (больше движущихся частей = больше режимов сбоев)
- Плохую отладочную информацию (падение E2E говорит что что-то не так; падение юнит-теста говорит что именно)
- Дорогую поддержку (изменения UI ломают E2E-тесты; API меняются реже)
Классический антипаттерн: мороженое. Крошечный слой юнит-тестов, никакого интеграционного слоя, и масштабный E2E-сьют который работает 45 минут и падает случайно.
Современная интерпретация
Исходная пирамида появилась до микросервисов, serverless и фреймворков вроде Playwright которые делают E2E-тесты значительно надёжнее. Современная версия это признаёт:
/\
/ \
/ E2E \ <- smoke-тесты, критические пути
/--------\
/ API/Svc \ <- интеграция, contract-тесты
/--------------\
/ Component/Unit \ <- бизнес-логика, утилиты
/--------------------\Конкретные пропорции варьируются в зависимости от команды и типа продукта. CRUD-API может иметь очень мало E2E-тестов и большое API-покрытие. React-дашборд со сложным UI может иметь больше компонентных тестов и меньше юнит-тестов.
Принцип остаётся тем же: опирайся на более дешёвые, быстрые и стабильные тесты. Резервируй E2E для сценариев которые можно верифицировать только через полный стек.
Применение пирамиды к Playwright-проекту
Что относится в E2E-тесты
- Критические пользовательские пути (вход → чекаут → подтверждение)
- Кросс-сервисная интеграция (фронтенд + бэкенд + база данных вместе)
- Специфичное для браузера поведение (загрузка файлов, несколько вкладок, OAuth-редирект)
- Smoke-тесты для продакшн-деплоев
Что не относится в E2E-тесты
- Сообщения об ошибках валидации (тестируй в юнит-тестах логики валидации)
- Каждый edge case сложного алгоритма (юнит-тест)
- API-ответы в изоляции (API-тест)
- Все 15 перестановок формы (разбивка на классы, выбери 3–4 представительных случая для E2E)
Конкретный пример
Тестируется фича размещения заказа. Требования:
1. Пользователь добавляет товар в корзину
2. Пользователь переходит к чекауту
3. Пользователь заполняет данные доставки
4. Пользователь оплачивает
5. Показывается подтверждение заказа
6. Пользователю отправляется email
Юнит-тесты покрывают
- Логику расчёта цены (скидки, налог, стоимость доставки)
- Рендеринг шаблона email
- Функцию валидации адреса
- Округление суммы платежа
API/интеграционные тесты покрывают
- POST /orders создаёт запись в базе данных
- POST /orders с невалидным платежом возвращает 422
- Переходы статуса заказа (pending → confirmed → shipped)
- Сервис email вызывается с правильными параметрами
E2E-тесты покрывают
Happy path (один тест): полный заказ от корзины до подтверждения. Ошибка платежа (один тест): карта отклонена, ошибка показана, заказ не создан. Нет в наличии (один тест): товар недоступен, пользователь перенаправлен с сообщением.
Всё. Три E2E-теста для целой фичи чекаута. Юнит и API-тесты покрывают edge case: E2E покрывает флоу которые важнее всего пользователям.
Тестовый трофей (альтернативная модель)
Кент С. Доддс предложил тестовый трофей в 2018 году, который адаптирует пирамиду для JavaScript-фронтендов:
/\
/ \ <- E2E (мало)
/----\
/ Integ \ <- интеграция (большинство)
/----------\
/ Unit \ <- юнит (некоторые)
/--------------\
/ Static \ <- типы, линтинг (всегда)
/------------------\Ключевое отличие: интеграционные тесты наверху середины. Для React/Vue/Next.js-приложений "интеграционные тесты" означает рендеринг компонентов с их реальными зависимостями (реальные API-вызовы к тестовому серверу или версия с моком на уровне сети). Философия React Testing Library: тестируй как пользователи взаимодействуют с компонентом, а не детали реализации.
Обе модели валидны. Пирамида хорошо подходит для бэкенд-систем. Трофей подходит для фронтенд-тяжёлых приложений. Любая из них лучше мороженого.
Правило большого пальца
Когда собираешься писать E2E-тест: спроси себя, что реально верифицирует этот тест, что нельзя было бы верифицировать на более низком уровне?
Если ответ "что фронтенд и бэкенд соединены и данные корректно проходят через весь стек": пиши E2E-тест.
Если ответ "что валидация формы показывает ошибку для пустого поля email": это юнит-тест для функции валидации и компонентный тест для формы. E2E-тест здесь был бы просто шумом.
→ See also: Дымовое тестирование vs регрессионное: в чём разница? | Компонентное тестирование в Playwright: тестирование React/Vue компонентов в изоляции | Практики автоматизации тестирования, которые реально важны