
Суть
Принцип Тетриса — это написание тестов как можно ниже в «Пирамиде тестирования». То есть, отдавайте предпочтение юнит-тестам, где это возможно, и используйте UI-тесты по минимуму, потому что низкоуровневые тесты быстрее, дешевле и их легче поддерживать.
У меня накопился некий «писательский долг» — идеи, которыми я делился на конференциях, митапах и в разговорах, но так и не записал. Одна из них — то, что я называю Принципом Тетриса. Идея проста и понятна, но несёт в себе удивительно сильные смыслы.
Это простая, но мощная концепция, которая напрямую связана с одной из самых фундаментальных моделей тестирования по Agile: «Пирамидой тестирования». Также, насколько мне известно, это единственный термин, который я когда-либо придумал, и который кто-то процитировал. И не просто кто-то: блестящая Элизабет Хендриксон подхватила его и поделилась с другими.
После более чем десяти лет практического применения и объяснения командам я, наконец, оформляю свои мысли в письменном виде. ✍️
Чтобы было понятно, это (Принцип Тетриса) — не революционная новая концепция. Это скорее удачная и легко запоминающаяся метафора, которая помогает командам применять принципы тестирования, заложенные в «Пирамиде».
Первые Agile Testing Days
Всё началось в 2010 году, когда я посетил самую первую конференцию Agile Testing Days в Берлине, Германия. Там, погруженный в сообщество тестировщиков и agile-практиков, я был особенно вдохновлен новаторской книгой Лизы Криспин и Джанет Грегори Agile Testing. Их идеи глубоко повлияли на моё мышление о качестве и автоматизации, и я начал размышлять о том, как превратить эти инсайты в нечто практическое в собственных проектах.
Мой доклад, How to Brew a Tasty Agile Test Strategy («Как заварить вкусную стратегию agile-тестирования»), был посвящён различным техникам, включая раздел о применении Пирамиды тестирования для создания надежной и эффективной стратегии. Он содержал слайд, где я рассказывал о Принципе Тетриса как о руководстве к тому, как использовать «Пирамиду тестирования». Но давайте сначала объясним подробнее саму концепцию.
Что такое «Пирамида тестирования»?
«Пирамида тестирования» — это фундаментальная модель в agile и тестировании ПО. Она показывает, как автоматизированные тесты должны быть распределены по уровням системы:
- Юнит-уровень (формирует основание пирамиды)
- Сервисный уровень (средний слой)
- UI или сквозной уровень (наверху)
Эту концепцию популяризировал Майк Кон, известный деятель в agile-сообществе и автор книг Succeeding with Agile (2009) и Agile Estimating and Planning. Он представил эту концепцию в 2009 году, чтобы показать, как автоматизированные тесты должны быть расположены слоями. Его оригинальную статью в блоге можно найти здесь: The Forgotten Layer of the Test Automation Pyramid.
Мартин Фаулер предлагает краткое и широко цитируемое объяснение этой концепции в своей статье: The Test Pyramid. Его объяснение подкрепляет идею, что юнит-тесты обычно быстрые 🐇, в то время как UI и сквозные тесты, как правило, намного медленнее 🐢 — как в исполнении, так и в получении обратной связи.
Помимо того, что пирамида предлагает концепцию для категоризации автоматизированных тестов по слоям, она также даёт указание по их распределению:
Пирамида подчеркивает, что необходимо иметь большое количество низкоуровневых юнит-тестов и меньше высокоуровневых UI-тестов, чтобы обеспечить быструю обратную связь, удобство поддержки и надёжность.
Антипаттерн «Пирамиды»: Рожок мороженого

К сожалению, часто бывает много тестов на уровне интеграции с UI, что соответствует вершине пирамиды, и мало юнит-тестов, что соответствует ее основанию. В результате получается форма, похожая на рожок мороженого: много мороженого сверху, а внизу — вафельная трубочка.
Это обычно приводит к:
- Хрупким тестам
- Поздней обратной связи — и я уверен, что уважаемый читатель знает 50 причин, почему ранняя обратная связь важна (кстати, этот термин тоже придумал Майкл Кон. )
«Пирамида тестирования» — Насколько велика ваша SUT?
Ещё один ключевой момент при рассмотрении уровней тестирования — это размер Системы под Тестированием (SUT).
- Юнит-тест может проверять один метод или класс — по минимуму и быстро.
- Тест на сервисном уровне обычно требует работающей базы данных или HTTP-интерфейса.
- Тест на UI-уровне часто требует полностью интегрированной системы: с UI, бэкендом и базой данных.
По мере продвижения вверх по пирамиде — SUT-система становится больше, медленнее инициализируется и нестабильна. Вот почему Принцип Тетриса призывает вас реализовывать любой тест на самом низком уровне, где SUT еще невелика и контролируется.
Что такое Принцип Тетриса

Как в старой игре «Тетрис», вам нужно приземлить каждый блок как можно ниже, и та же логика применима к автоматизированному тестированию:
Для каждого аспекта, который вы хотите протестировать, реализуйте тест на самом низком уровне из доступных, в соответствии с правилом Пирамиды.
Если поведение можно протестировать как юнит-тест — делайте так. Если нет, возможно, подойдёт интеграционный тест на сервисном уровне. Не переходите сразу к UI-тестам, если это возможно.
Принцип Тетриса — это метафора, это стратегия надежной автоматизации. Вот плюсы:
1. Скорость 🚀
Низкоуровневые тесты — особенно юнит-тесты — выполняются быстро. Вы получаете обратную связь в течение миллисекунд или секунд. Для разработчика это означает мгновенную обратную связь сразу после любого изменения кода, без ожидания сборок и развертываний.
Сравните это с обычным рабочим процессом PR-merge-test: вы отправляете код, ждете ревью, мержите pull-запрос, запускаете развёртывание — и наконец ⏳ тесты прошли.
Эта задержка нарушает рабочий процесс и затрудняет раннее выявление проблем. Быстрая обратная связь необходима для хороших Developer Experience (DX).
2. Стоимость 💰
Юнит-тесты дешевле писать, их легче запускать локально и проще отлаживать. Они снижают зависимость от сложных окружений, включая расходы на хостинг тестовых окружений.
В итоге, Принцип Тетриса способствует снижению затрат — на инфраструктуру и разработчиков.
3. Четкость 🔍
Применение этого принципа снижает сложность: упавший юнит-тест прямо указывает на проблему. С UI-тестами часто непонятно, где проблема.
Значит ли это, что UI-тесты не нужны?
Точно нет! В «Тетрисе» вы стараетесь не приземлять блоки в верхней части экрана, а в тестировании нам нужно буквально несколько UI-тестов, особенно для проверки того, как компоненты работают в интеграции.
Эти высокоуровневые тесты могут находить проблемы, которые не были видны на низких уровнях, например неправильно настроенные зависимости, поломанные пользовательские потоки и плохие связи между сервисами. Но используйте UI-тесты экономно, сосредоточьтесь на ключевых пользовательских путях и полагайтесь на юнит-тесты для основной части тестового покрытия.
Применение Принципа
Логика валидации? Тестируйте ее на юнит-уровне, а не через UI.
Например, если система включает логику валидации, которая проверяет форматы ввода и обязательные поля, переместите эту логику в отдельную функцию JavaScript или объект домена. Затем вы можете написать быстрые изолированные юнит-тесты для проверки этой логики — без необходимости в UI-тестах.
Запросы к базе данных? С помощью интеграционных тестов, ориентированных на ваш репозиторий или слой доступа к данным.
Бизнес-правила? С помощью тестов на сервисном уровне или уровне домена, прежде чем рассматривать автоматизацию UI.
Опишите ключевую бизнес-логику — например пути пользовательских подтверждений, условия ценообразования, или разрешения на доступ — в виде кода в вашем доменном слое. Тестируйте эту логику напрямую, используя простые юнит- и сервисные тесты.
Я люблю Behavior-Driven Development (BDD) — и в большинстве случаев применяю его на юнит-уровне.
Это позволяет мне писать выразительные бизнес-ориентированные сценарии, сохраняя тесты быстрыми и сфокусированными. Вам не нужен полностековый UI или сложная инфраструктура, чтобы извлечь выгоду из BDD-стиля.
Тема BDD на юнит-уровне заслуживает подробного рассмотрения — возможно, в будущей статье.
Пример: Автомобильная навигационная система
Представьте, что вы в команде, которая разрабатывает информационно-развлекательную навигационную систему для автомобиля.
Будете ли вы запускать все свои тесты в полной системе, подключенной к реальному автомобилю, сидя в ней на водительском сиденье?
Конечно, нет. Большинство тестов — таких как валидация алгоритмов маршрутизации, рендеринг экрана или воспроизведение медиа — можно запустить на тестовом стенде или даже как юнит-тесты в изолированных компонентах.
Только несколько самых важных, критически важных тестов — например, проверка интеграции с рулевым колесом или прием GPS-сигнала — должны быть запущены в автомобиле.
То же самое с ПО: тестируйте низко и изолированно, насколько это возможно, и тестируйте всю систему только тогда, когда это абсолютно необходимо.
Влияние на архитектуру ПО
Принцип Тетриса не просто влияет на то, как я пишу тесты — он также формирует то, как я проектирую системы.
Вот пример:
Предположим, у нас есть основная бизнес-логика, инкапсулированная в сервисе. Вместо тестирования UserRegistrationService, который обращается к базе данных, извлеките логику валидации в функцию validateUserData(userData), которая возвращает результаты валидации. Тестируйте эту функцию напрямую, используя мок-данные в качестве входных.
Если мы следуем Принципу Тетриса, мы понимаем: всякий тест должен работать ниже. Поэтому вместо тестирования всего потока с подключением базы данных, я слегка пере-проектирую систему:
- Извлекаю основную логику в функцию
- Внедряю зависимости по данным (например заранее созданные доменные объекты)
- Пишу юнит-тест — база данных не нужна здесь
Этот подход в архитектуре незаметен, но силён. Он уменьшает связанность, улучшает тестируемость и упрощает архитектуру.
Я использую Принцип
Даже спустя десять лет, Принцип Тетриса остается краеугольным камнем моего подхода к автоматизации. Я ссылаюсь на него, когда обучаю команды, анализирую тестовые стратегии и проектирую CI-пайплайны, и считаю его одним из моих личных пяти принципов Agile-тестирования:

Принцип помогает:
- Улучшить скорость обратной связи
- Поощрять простую слоистую архитектуру
- Снизить стоимость, сложность и нестабильность тестов