Когда автоматизировать, а когда нет: пирамида тестирования простыми словами
Зачем это знать?
Представьте, что вы открыли небольшую пекарню. Каждое утро нужно проверять десятки позиций: свежесть хлеба, температуру духовок, правильность ценников, работу кассы. Всё это можно делать вручную — но с ростом ассортимента вы начнёте тратить на проверки больше времени, чем на саму выпечку.
В разработке программного обеспечения (то есть приложений и сайтов) ровно та же проблема. Чем больше проект, тем больше вещей нужно проверять после каждого изменения. Рано или поздно встаёт вопрос: что автоматизировать, а что проверять руками?
Ответить на этот вопрос помогает инструмент под названием пирамида тестирования. Это не математическая формула и не сложная схема — это простая визуальная идея, которая объясняет, каких тестов должно быть много, каких мало, и почему. Разобравшись в ней, вы будете принимать грамотные решения даже без опыта в программировании.
Теория
Шаг 1. Что такое тест и зачем он нужен?
Прежде чем говорить о пирамиде, освежим базовые понятия.
Программное обеспечение (ПО) — это любая программа или приложение: мобильное приложение банка, сайт интернет-магазина, игра на телефоне.
Тест — это проверка. Вы задаёте вопрос «работает ли это?» и смотрите на ответ. Например: «Если я нажму кнопку "Войти" с правильным паролем, откроется ли личный кабинет?»
Баг (bug) — это ошибка в программе. Буквально — «жучок». Когда что-то работает не так, как задумано, говорят: «Нашли баг».
Ручное тестирование — это когда человек сам кликает по приложению и проверяет, всё ли работает.
Автоматизированное тестирование — это когда проверку делает программа-робот вместо человека. Вы один раз «объясняете» роботу, что проверять, и он делает это снова и снова без устали.
Шаг 2. Почему нельзя просто автоматизировать всё подряд?
Казалось бы: давайте напишем роботов для каждой проверки и забудем о ручном тестировании. Но у автоматизации есть цена:
| Что нужно учесть | Объяснение |
|---|---|
| Время на создание | Написать автоматизированный тест дольше, чем проверить вручную один раз |
| Поддержка | Когда приложение меняется, тесты нужно обновлять — иначе они будут «ломаться» |
| Стоимость | Автоматизация требует специалистов и инфраструктуры |
| Некоторые проверки плохо автоматизируются | Например, «красиво ли выглядит кнопка?» — субъективный вопрос, который сложно объяснить роботу |
Вывод: автоматизировать всё — не значит автоматизировать умно. Нужна стратегия.
Шаг 3. Знакомьтесь: пирамида тестирования
Концепцию пирамиды тестирования предложил Майк Кон (Mike Cohn) — специалист по разработке программного обеспечения — в начале 2000-х годов. С тех пор она стала стандартом в профессии.
Пирамида выглядит вот так:
/\
/ \
/ UI \ <- мало тестов, дорогие, медленные
/------\
/ API \ <- средне тестов, быстрее и дешевле
/----------\
/ Unit \ <- много тестов, быстрые и дёшевые
/______________\
Три уровня пирамиды — это три вида тестов. Давайте разберём каждый.
Шаг 4. Нижний уровень — Unit-тесты (модульные тесты)
Unit — по-английски «единица», «единичный элемент».
Unit-тест проверяет самую маленькую, изолированную часть программы — одну функцию или один модуль — в отрыве от всего остального.
Аналогия: Вы тестируете отдельный болт на заводе. Не всю машину, не двигатель — просто один болт: правильного ли он размера, нет ли трещин.
Пример из жизни программы:
Допустим, в приложении есть функция, которая считает итоговую сумму заказа с учётом скидки. Unit-тест проверит именно эту функцию: «если скидка 10% от 1000 рублей, результат должен быть 900 рублей».
# Это простой пример Unit-теста на языке Python.
# Пока не нужно понимать синтаксис — просто посмотрите на логику.
def применить_скидку(сумма, процент_скидки):
"""Функция вычисляет итоговую сумму с учётом скидки."""
return сумма - (сумма * процент_скидки / 100)
# Тест: проверяем, что функция работает правильно
def test_скидка_10_процентов():
результат = применить_скидку(1000, 10)
assert результат == 900, f"Ожидали 900, но получили {результат}"
# Тест: проверяем нулевую скидку
def test_нулевая_скидка():
результат = применить_скидку(500, 0)
assert результат == 500
Ключевое слово assert означает «утверждаю, что это правда». Если утверждение окажется ложным, тест провалится и сообщит об ошибке.
Характеристики Unit-тестов:
- ✅ Очень быстрые — выполняются за доли секунды
- ✅ Дешёвые в написании и поддержке
- ✅ Точно указывают, где именно сломалось
- ❌ Не проверяют, как части работают вместе
- 📊 Должны составлять большинство тестов в проекте (около 70%)
Шаг 5. Средний уровень — Integration-тесты (интеграционные тесты)
Integration — «интеграция», «объединение».
Интеграционный тест проверяет, как несколько частей программы работают вместе. Это уже не один болт, а пара шестерёнок — крутятся ли они слаженно?
Аналогия: Вы уже проверили каждую деталь автомобиля по отдельности. Теперь вы проверяете, работает ли двигатель вместе с коробкой передач.
Часто на этом уровне говорят об API-тестах. API (Application Programming Interface — «интерфейс прикладного программирования») — это способ, которым разные части программы или разные программы «разговаривают» между собой. Представьте официанта в ресторане: вы (клиент) говорите официанту (API) свой заказ, он передаёт его на кухню (сервер) и приносит вам результат.
Пример: Пользователь нажимает «Оформить заказ». Система должна:
- Сохранить заказ в базу данных
- Отправить письмо пользователю
- Уменьшить остаток товара на складе
Интеграционный тест проверит, что все три шага происходят корректно и «общаются» друг с другом правильно.
Характеристики интеграционных тестов:
- ✅ Проверяют реальное взаимодействие компонентов
- ✅ Выявляют проблемы на стыках между модулями
- ⚡ Медленнее Unit-тестов, но быстрее UI-тестов
- 💰 Дороже в написании, чем Unit-тесты
- 📊 Должны составлять около 20% тестов в проекте
Шаг 6. Верхний уровень — UI-тесты (End-to-End тесты)
UI расшифровывается как User Interface — «пользовательский интерфейс», то есть то, что видит и с чем взаимодействует пользователь: кнопки, поля ввода, экраны.
End-to-End (E2E) означает «от начала до конца». Такой тест проходит весь путь пользователя целиком — как будто реальный человек сидит за компьютером и работает с приложением.
Аналогия: Вы собрали весь автомобиль и теперь выезжаете на тест-драйв по реальной дороге. Это самая реалистичная проверка, но и самая долгая.
Пример: Тест сценария «Покупка товара в интернет-магазине»:
- Открыть сайт
- Найти товар через поиск
- Добавить в корзину
- Перейти к оформлению
- Ввести адрес доставки
- Нажать «Оплатить»
- Убедиться, что появилась страница «Заказ оформлен»
Инструменты вроде Selenium или Playwright позволяют записать такой сценарий и запускать его автоматически — робот будет «кликать» по сайту вместо человека.
Характеристики UI/E2E-тестов:
- ✅ Максимально реалистичны — проверяют систему глазами пользователя
- ✅ Выявляют сквозные проблемы, незаметные на нижних уровнях
- ❌ Очень медленные — один тест может занять несколько минут
- ❌ Дорогие в создании и поддержке
- ❌ Хрупкие: стоит немного изменить дизайн кнопки — тест «сломается»
- 📊 Должны составлять около 10% тестов в проекте
Шаг 7. Антипаттерны: мороженое и кекс
Пирамида — это идеал. На практике команды иногда делают всё наоборот, и тогда говорят об антипаттернах (то есть «неправильных образцах»).
🍦 Антипаттерн «Перевёрнутая пирамида» (мороженое)
/______________\
/ UI/E2E \ <- очень много медленных UI-тестов
/------------------\
/ API \ <- немного
/----------------------\
Unit <- почти нет
Команда написала много UI-тестов и мало Unit-тестов. Результат: тесты запускаются часами, часто «падают» по случайным причинам (например, из-за задержки сети), и разработчики перестают им доверять.
🧁 Антипаттерн «Кекс»
Тесты есть на всех уровнях примерно поровну. Казалось бы, неплохо — но это означает, что Unit-тестов недостаточно, а значит, мелкие ошибки обнаруживаются только на дорогих верхних уровнях.
Почему это важно для новичка? Когда вас попросят написать тест, подумайте: на каком уровне пирамиды он будет? Можно ли проверить эту же вещь дешевле — на уровень ниже?
Шаг 8. Когда автоматизировать, а когда — нет?
Вот практическое правило в виде таблицы:
| Ситуация | Автоматизировать? | Почему |
|---|---|---|
| Проверка одна и та же, повторяется при каждом обновлении | ✅ Да | Экономия времени на дистанции |
| Проверка делается один раз для разового релиза | ❌ Нет | Затраты на автоматизацию не окупятся |
| Логика сложная, много вариантов входных данных | ✅ Да | Робот не устаёт и не ошибается |
| Проверка «красиво ли выглядит?» | ❌ Нет | Субъективная оценка требует человека |
| Регрессионное тестирование (проверка, что старое не сломалось) | ✅ Да | Классический кандидат для автоматизации |
| Исследовательское тестирование (поиск неожиданных проблем) | ❌ Нет | Нужно человеческое любопытство и интуиция |
| Нагрузочное тестирование (тысячи пользователей одновременно) | ✅ Да | Невозможно воспроизвести вручную |
Золотое правило: Автоматизируйте то, что стабильно, повторяемо и хорошо определено. Оставляйте человеку то, что требует суждения, творчества и эмпатии.
Шаг 9. Пирамида в реальной жизни — пример целиком
Представим простое приложение: калькулятор чаевых в ресторане. Пользователь вводит сумму счёта и выбирает процент чаевых, приложение показывает итог.
Что тестировать на каждом уровне:
Unit-тесты (много, быстрые):
- Функция расчёта:
10% от 500 = 50✓ - Функция расчёта:
0% от любой суммы = 0✓ - Что происходит, если ввести отрицательную сумму? ✓
- Что происходит, если поле пустое? ✓
Интеграционные тесты (средне):
- Данные из полей ввода корректно передаются в функцию расчёта
- Результат расчёта корректно передаётся на экран для отображения
UI/E2E-тесты (мало, медленные):
- Пользователь открывает приложение → вводит 1000 → выбирает 15% → видит на экране «150 рублей» ✓
Заметьте: основную логику мы проверили дёшево на уровне Unit. UI-тест только убеждается, что весь поток работает — он не проверяет все возможные числа.
Практика
Выполните следующие задания. Они не требуют написания кода — только вдумчивого анализа.
Задание 1. Классифицируй тест
Прочитайте описание каждого теста и определите, к какому уровню пирамиды он относится: Unit, Интеграционный или UI/E2E.
- Тест проверяет, что функция
конвертировать_валюту(100, "USD", "RUB")возвращает число больше нуля. - Тест открывает браузер, переходит на сайт банка, авторизуется, переводит 500 рублей другому пользователю и проверяет, что баланс уменьшился.
- Тест проверяет, что при сохранении нового пользователя в базу данных ему автоматически отправляется приветственное письмо.
- Тест проверяет, что функция
разбить_на_слова("привет мир")возвращает список["привет", "мир"].
Подсказка: Спросите себя — тест проверяет одну маленькую функцию? Это Unit. Несколько частей вместе? Интеграционный. Весь путь пользователя через интерфейс? UI/E2E.
Задание 2. Автоматизировать или нет?
Для каждой ситуации решите: стоит ли её автоматизировать? Объясните своё решение в 1–2 предложениях.
- После каждого обновления приложения нужно убедиться, что форма входа работает — вводишь логин и пароль, попадаешь в аккаунт.
- Дизайнер просит проверить, «достаточно ли приятно смотрится новый шрифт на главной странице».
- Раз в год нужно проверить, работает ли функция экспорта отчёта в PDF.
- Каждую ночь нужно прогонять 500 тест-кейсов для проверки, что вчерашние изменения кода ничего не сломали.
Задание 3. Нарисуй пирамиду для своего проекта
Возьмите любое знакомое вам приложение (мессенджер, приложение доставки еды, онлайн-банк). Придумайте:
- 3 примера Unit-тестов (что можно проверить на уровне отдельных функций)
- 2 примера интеграционных тестов (что можно проверить на стыке двух частей)
- 1 пример UI/E2E-теста (полный сценарий глазами пользователя)
Запишите свои примеры в текстовый файл или тетрадь. Пример оформления:
Приложение: Яндекс.Еда
Unit-тесты:
- Проверка, что функция расчёта времени доставки возвращает корректное число минут
- ...
Интеграционные тесты:
- Проверка, что выбранные блюда корректно добавляются в корзину и обновляют итоговую сумму
- ...
UI/E2E-тест:
- Пользователь открывает приложение → выбирает ресторан → добавляет пиццу → оформляет заказ → видит подтверждение
Задание 4. Найди антипаттерн
Команда разработала приложение и написала тесты в таком соотношении:
- Unit-тестов: 5 штук
- Интеграционных тестов: 10 штук
- UI/E2E-тестов: 85 штук
Ответьте на вопросы:
- Это пирамида или антипаттерн? Если антипаттерн — какой именно?
- Какие проблемы может испытывать эта команда при запуске тестов?
- Как бы вы перераспределили тесты, если бы всего их было 100?
Итоги урока
- Пирамида тестирования — это визуальная стратегия, которая помогает решить, каких тестов писать много, а каких мало.
- Три уровня пирамиды: Unit (низ) → Integration (середина) → UI/E2E (верх).
- Unit-тесты — самые дешёвые и быстрые, проверяют одну изолированную функцию. Их должно быть большинство (~70%).
- Интеграционные тесты проверяют взаимодействие нескольких частей системы. Средний слой (~20%).
- UI/E2E-тесты проверяют полный пользовательский сценарий. Их должно быть мало (~10%), потому что они медленные и дорогие.
- Автоматизируйте то, что повторяется, стабильно и хорошо определено.
- Оставляйте человеку субъективные, творческие и исследовательские проверки.
- Антипаттерны (перевёрнутая пирамида, кекс) — признак того, что стратегия тестирования требует пересмотра.
- Ключевой вопрос перед любым тестом: «Можно ли проверить это же — но дешевле, на уровень ниже в пирамиде?»