Что такое E2E и пирамида тестов

Разбираемся, что значит «протестировать приложение целиком» и почему таких тестов должно быть мало.

End-to-end (E2E) тест — это автоматический сценарий, который проверяет работу приложения от начала до конца через пользовательский интерфейс, как если бы за компьютером сидел живой человек.

Что значит «end-to-end»

Представьте интернет-магазин. Пользователь открывает сайт, ищет товар, кладёт его в корзину, вводит адрес и оплачивает. В этом сценарии участвуют десятки частей системы: фронтенд на JavaScript, бэкенд-API, база данных, платёжный шлюз. E2E-тест проходит весь этот путь целиком — отсюда название «от конца до конца».

Ключевая идея: E2E-тест ничего не знает о внутреннем устройстве кода. Он взаимодействует с приложением только так, как это делает реальный пользователь — кликает по кнопкам, заполняет поля, читает текст на экране. Если сценарий проходит, значит, все части системы корректно работают вместе. Unit-тест может убедиться, что функция calculateTotal() правильно складывает цены, но он не заметит, что кнопка «Оплатить» не появляется из-за ошибки в вёрстке. E2E-тест поймает именно такую проблему — он видит кнопку (или её отсутствие) глазами пользователя.

Как выглядит E2E-тест

Типичный сценарий состоит из действий (открыть страницу, кликнуть, ввести текст) и проверок (убедиться, что на экране появился нужный результат). Вот как это выглядит на Playwright — пока просто прочитайте, синтаксис разберём дальше в курсе.

import { test, expect } from '@playwright/test';

test('пользователь может войти', async ({ page }) => {
  await page.goto('https://example.com/login');
  await page.getByLabel('Email').fill('[email protected]');
  await page.getByLabel('Пароль').fill('secret123');
  await page.getByRole('button', { name: 'Войти' }).click();

  // проверка: после входа видно приветствие
  await expect(page.getByText('Добро пожаловать')).toBeVisible();
});

Этот код буквально описывает то, что делает человек: перешёл на страницу входа, заполнил email и пароль, нажал кнопку и убедился, что вошёл. Если на любом шаге что-то сломается, тест упадёт и сообщит об этом.

Пирамида тестов

Пирамида тестов — модель, которая советует держать много быстрых unit-тестов в основании и мало медленных E2E-тестов на вершине.

Когда команда впервые видит силу E2E («они же проверяют всё по-настоящему!»), возникает соблазн покрыть ими каждую мелочь. Это ловушка: E2E медленные и хрупкие, и сотни таких тестов превращают прогон в многочасовое мучение, которое к тому же постоянно «моргает» ложными падениями. Пирамида подсказывает, как распределить усилия.

         /\
        /  \      E2E          ← мало (секунды, хрупкие)
       /----\
      /      \    Интеграционные ← средне
     /--------\
    /          \  Unit          ← много (миллисекунды, надёжные)
   /____________\

Unit (основание). Самые быстрые и многочисленные, проверяют отдельные функции. Интеграционные (середина). Проверяют связку модулей — например, что API-обработчик правильно сохраняет данные в базу. E2E (вершина). Запускают браузер, ходят по сети, зависят от множества факторов — их держат мало.

Почему «мало, но важно»

E2E-тестов мало не потому, что они плохие, а потому что они дорогие в сопровождении. Зато каждый покрывает огромную площадь: один тест на оформление заказа косвенно проверяет десятки функций, API-эндпоинтов и компонентов разом. Это даёт уверенность, которую не дают unit-тесты по отдельности.

СвойствоUnitE2E
Количествомного (сотни)мало (десятки)
Скоростьмиллисекундысекунды
Стабильностьвысокаяниже (бывают флаки)
Площадь покрытияузкаяширокая

Антипаттерн: «мороженое»

Если перевернуть пирамиду — много E2E и мало unit — получается «рожок мороженого». Такой набор тестов прогоняется медленно, постоянно падает по случайным причинам и подрывает доверие команды. Признак беды: разработчики начинают перезапускать упавшие тесты «на всякий случай», не разбираясь в причине. Помните: E2E — это дополнение к нижним уровням пирамиды, а не замена им.

Итог

  • E2E-тест проверяет приложение целиком через интерфейс, как реальный пользователь, и ничего не знает о внутреннем коде.
  • В отличие от unit-тестов, E2E ловит проблемы интеграции и UI, но работает медленнее.
  • Пирамида тестов: много unit снизу, мало E2E сверху — зато каждый E2E покрывает широкую площадь.
  • Перевёрнутая пирамида («мороженое») — антипаттерн: медленно и нестабильно.
Проверьте себя
1. Что в первую очередь проверяет end-to-end тест?
AКорректность одной отдельной функции в изоляции
BРаботу всего приложения через интерфейс, как у реального пользователя
CСкорость выполнения SQL-запросов к базе данных
DСоответствие кода стилю и форматированию
2. Почему в пирамиде тестов E2E-тестов должно быть мало?
AОни бесполезны и проверяют слишком мало
BОни медленные, хрупкие и дорогие в сопровождении
CИх нельзя писать на JavaScript
DОни не находят настоящих ошибок
3. Как называют антипаттерн с большим числом E2E и малым числом unit-тестов?
AПеревёрнутая пирамида («рожок мороженого»)
BДвойная воронка
CТестовый куб
DПесочные часы
4. Какой сценарий — хороший кандидат на E2E-тест?
AПроверка, что функция сложения возвращает правильную сумму
BОформление заказа: от выбора товара до оплаты
CФорматирование чисел в строку
DСортировка массива из десяти элементов
Поддержать проект