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

Почему здоровый проект держит много дешёвых тестов внизу и мало дорогих наверху.

Пирамида тестирования — модель, по которой тестов нижнего уровня (быстрых модульных) должно быть много, среднего (интеграционных) — меньше, а верхнего (медленных end-to-end) — совсем немного.

Три яруса

Снизу вверх тесты становятся реалистичнее, но медленнее, дороже и хрупче. Поэтому их количество должно убывать.

ЯрусЧто проверяетСкоростьСколько
Unit (модульные)Отдельную функцию/класс в изоляцииМиллисекундыМного (основа)
Integration (интеграционные)Связку модулей: код + БД, два сервисаДоли секундыСредне
E2E (сквозные)Систему целиком, как пользовательСекунды–минутыМало (только ключевое)

Почему именно такое соотношение

  • Скорость. Тысячи unit-тестов проходят за пару секунд; столько же e2e заняли бы часы. Быстрый прогон — это частая обратная связь.
  • Локализация. Упавший unit-тест точно указывает на сломанную функцию. Упавший e2e лишь говорит «где-то в цепочке поломка» — ищи долго.
  • Стабильность. E2E хрупки: сеть, тайминги, верстка. Много e2e = много «флакающих» тестов, которым перестают верить.

Антипаттерны формы

Если нарушить пропорции, получаются известные антипаттерны: «мороженое наоборот» (ice-cream cone) — мало unit и куча медленных ручных/e2e сверху; «песочные часы» — много unit и e2e, но провал в середине. Здоровая форма — именно широкое основание из unit-тестов.

Считаем здоровую пропорцию

tests = {"unit": 700, "integration": 200, "e2e": 50}
total = sum(tests.values())

for level, count in tests.items():
    share = count / total * 100
    print(f"{level:12} {count:4}  ({share:.0f}%)")

# «Тест» формы: unit-тестов должно быть больше всего, e2e — меньше всего
assert tests["unit"] > tests["integration"] > tests["e2e"]
print("Форма пирамиды соблюдена")

Вывод:

unit          700  (74%)
integration   200  (21%)
e2e            50  (5%)
Форма пирамиды соблюдена

Итог

  • Много быстрых unit-тестов внизу, меньше интеграционных, совсем мало e2e.
  • Причины — скорость, точная локализация ошибки и стабильность.
  • Перевёрнутая пирамида («рожок мороженого») — типичный антипаттерн.
Проверьте себя
1. Каких тестов в здоровой пирамиде должно быть больше всего?
AEnd-to-end (сквозных)
BМодульных (unit)
CРучных
DНагрузочных
2. Почему e2e-тестов держат мало?
AОни слишком простые
BОни медленные, хрупкие и плохо локализуют поломку
CОни не находят багов
DИх нельзя автоматизировать
3. Что такое антипаттерн «рожок мороженого»?
AМного unit-тестов и мало e2e
BМало unit-тестов и много медленных e2e/ручных сверху
CПолное отсутствие интеграционных тестов
DТесты без assert
Поддержать проект