Тесты часто воспринимают как роскошь: «нет времени, сначала выпустим». На практике их отсутствие означает, что каждую правку приходится проверять руками — и рано или поздно проверять перестают. Дальше сценарий повторяется из проекта в проект: небольшое изменение в расчёте скидки ломает оформление заказа, узнают об этом от клиента, а разбор занимает больше времени, чем заняло бы написание проверки. Разберём, что имеет смысл покрывать тестами в первую очередь, какими бывают уровни проверок и как начать в проекте, где тестов нет вообще.
Почему до тестов обычно не доходят руки
Довод «нет времени» почти всегда означает другое: новая функция видна заказчику, а тесты не видны. Поэтому в оценке работ они уходят под сокращение первыми. Экономия при этом разовая, а расплата регулярная: чем дольше живёт проект, тем больше времени уходит на повторную ручную проверку одного и того же.
Второй частый аргумент — «у нас всё меняется, тесты устареют». Он справедлив для вёрстки на раннем этапе и несправедлив для бизнес-логики. Правила расчёта цены, условия доставки, права доступа и обмен данными с учётной системой живут годами и меняются точечно. Именно они и должны быть закрыты проверками.
Третий — «мы и так тестируем руками». Ручное тестирование нужно и никуда не денется, но оно плохо масштабируется. Повторить перед выпуском десяток сценариев человек готов, восемьдесят — уже нет: часть проверок начинают пропускать, и обычно это те, которые «и так работали».
Что покрывать в первую очередь
Мы отталкиваемся не от структуры кода, а от цены поломки. Если сбой в этом месте приводит к потере денег, к утечке данных или к тихому браку в данных, который вскроется через месяц, — сюда нужен тест. Если поломка заметна сразу и правится за несколько минут, можно обойтись.
| Область | Почему важно | Чем проверяем |
|---|---|---|
| Оформление заказа и оплата | Прямые потери денег при поломке, клиент не сообщит об ошибке — он уйдёт | Сценарный тест полного пути плюс модульные на статусы заказа |
| Расчёты: цены, скидки, налоги, доставка | Ошибка не видна глазом и накапливается в документах | Модульные тесты с набором крайних значений |
| Авторизация и права доступа | Вопрос безопасности: чужие данные не должны открываться по прямой ссылке | Интеграционные тесты на каждую роль |
| Интеграции с внешними системами | Ломаются при обновлениях на чужой стороне, без предупреждения | Тесты на заглушках плюс проверка формата ответа |
| Формы заявок и уведомления | Тихо перестают работать, и это выясняется через недели | Интеграционный тест отправки и записи обращения |
| Импорт и выгрузка данных | Порча каталога или остатков лечится дольше, чем создаётся | Тесты на образцах реальных файлов, включая испорченные |
Уровни проверок и что они ловят
Проверки различаются по объёму того, что они запускают, и по скорости. Смешивать их в одну кучу не стоит: у каждого уровня своя работа.
- Модульные. Проверяют отдельную функцию или класс без базы и сети. Выполняются за миллисекунды, поэтому их может быть много, и запускать их можно на каждое сохранение файла. Хорошо ложатся на расчёты и правила.
- Интеграционные. Проверяют связку модулей, работу с базой, обращение к внешнему сервису через заглушку. Медленнее, но именно они ловят самое частое — несовпадение ожиданий между двумя частями системы.
- Сценарные. Проходят путь пользователя в браузере: открыть каталог, добавить товар, оформить заказ. Самые медленные и самые хрупкие, поэтому их держат немного и только на ключевых сценариях.
Разумное соотношение — много быстрых, немного медленных. Если сценарных тестов становится столько же, сколько модульных, набор начинает выполняться десятки минут, и разработчики перестают запускать его до отправки правки.
Инструменты: чем пишут автотесты
Набор инструментов зависит не от моды, а от того, на чём написан проект и какой уровень проверок вы закрываете. Ниже — то, что реально встречается в работе и не требует отдельной команды на поддержку.
- Действия пользователя в браузере (e2e). Playwright и Cypress — современный выбор: сами ждут появления элементов, пишут видео и трассировку падения. Selenium жив там, где нужен парк старых браузеров или уже есть наработки.
- Проверки логики (unit). PHPUnit и Pest для PHP, PyTest для Python, Jest и Vitest для JavaScript. Это самые дешёвые тесты: выполняются за секунды и запускаются на каждый коммит.
- API и интеграции. Postman с прогоном через Newman, REST Assured, тот же PyTest с запросами. Здесь проверяются коды ответов, схема данных и поведение при ошибке на стороне партнёра.
- Нагрузка. k6 и JMeter — чтобы узнать, на какой посещаемости сайт начинает тормозить, до того как это выяснится в сезон.
- Регресс вёрстки. Скриншотные проверки в Playwright или BackstopJS: ловят съехавшую кнопку и сломанную сетку, которых функциональные тесты не замечают.
Отдельно — где это всё запускается. Сами по себе тесты пользы не приносят: их нужно прогонять автоматически при каждом изменении. Обычно это GitHub Actions, GitLab CI или Jenkins — прогон на пул-реквест, отчёт в интерфейсе, запрет на слияние при падении. Если такой привычки в команде нет, начинать стоит именно с этого, а не с количества тестов.
Выбор в двух словах: нет тестов вообще — берите e2e на 3–5 главных сценариев и любой CI; есть сложные расчёты — начинайте с unit; много внешних обменов — с API. Смешивать всё сразу не нужно, это верный способ забросить затею на второй неделе.
Чего не стоит делать
- Гнаться за стопроцентным покрытием. Цифра покрытия показывает, какие строки выполнялись во время прогона, а не то, что поведение проверено. Сто процентов покрытия достигаются тестами, которые ничего не утверждают.
- Тестировать очевидное: геттеры, присвоение полей, обёртки без логики. Такие тесты дают объём и не ловят ничего.
- Писать сценарные тесты, привязанные к вёрстке. Поиск элемента по цепочке вложенных блоков ломается от любой правки шаблона. Мы привязываемся к отдельным атрибутам, поставленным специально для тестов.
- Оставлять «мигающие» тесты, которые падают через раз из-за таймингов или общего состояния. Один такой тест обесценивает весь набор: команда привыкает перезапускать прогон вместо разбора.
- Ставить тесты в зависимость от конкретных данных на боевом сервере. Набор должен подниматься с нуля на чистой базе, иначе он не воспроизводится.
С чего начать в проекте без тестов
Отдельный проект «внедрим тестирование» обычно не доживает до конца: он не даёт видимого результата и первым отменяется при срочных задачах. Мы идём иначе.
- Первый тест пишем на тот сценарий, который ломался чаще всего. У любого живого проекта есть такое место, и его помнят все.
- Дальше действует правило: каждая исправленная ошибка сопровождается тестом, который её воспроизводит. Сначала тест падает, потом правится код, потом тест проходит.
- Новый код закрываем сразу — это дешевле, чем возвращаться. Старый трогаем только когда его и так приходится менять.
- Перед крупной переработкой узла пишем проверки на текущее поведение. Они и служат страховкой при переписывании.
Через полгода такой практики критичные места оказываются закрыты, хотя отдельного бюджета на тестирование никто не выделял.
Как тесты встраиваются в выпуск
Написанные тесты приносят пользу только если их кто-то запускает. Мы настраиваем автоматический прогон при отправке изменений в репозиторий: быстрый набор проходит на каждую правку, полный — перед выкладкой. Результат виден в запросе на слияние, и правка с падающими тестами не уезжает на боевой сервер.
Отдельно стоит проверка после выкладки: короткий сценарий, который открывает главные страницы, отправляет тестовую заявку и убеждается, что она дошла. Он занимает меньше минуты и снимает самый неприятный класс проблем — когда всё работало на тестовом окружении и не работает на боевом из-за настроек.
Что это даёт бизнесу
Тесты не делают код красивее и не ускоряют разработку саму по себе. Они дают другое: возможность выпускать изменения без страха сломать оплату или расчёты. У этого есть измеримые следствия — меньше срочных ночных правок, меньше простоев в сезон, короче путь от идеи до выпуска, потому что проверка перестаёт быть отдельным событием.
Есть и менее очевидный эффект. Набор тестов описывает, как система должна себя вести, и это описание не устаревает, в отличие от документации. Новый разработчик разбирается в проекте по тестам быстрее, чем по коду, а уход человека из команды перестаёт быть катастрофой.
Если писать тесты некому
Регулярное тестирование требует людей, которые постоянно находятся в проекте: разово настроить набор мало, его надо поддерживать вместе с кодом. Если своей команды нет или она загружена, мы предоставляем выделенную команду разработчиков, которая ведёт проект на длинной дистанции. Расскажите о своей системе — обсудим, что покрывать в первую очередь.
Сколько стоит внедрить автотесты на работающем проекте
Вопрос, который обычно и останавливает: тесты выглядят расходом без видимого результата. Считать их стоит не в часах написания, а в стоимости одного повторного бага на проде — с разбором, срочным исправлением и потерянными за это время заявками.
На практике внедрение раскладывается на три шага, и каждый даёт результат сам по себе. Первый — покрыть тестами денежный путь: корзина, оформление заказа, оплата, отправка формы. Это 20–40 часов на типовом сайте и снимает большую часть критичных поломок. Второй — подключить прогон к выкладке, чтобы тесты запускались сами, а не когда кто-то вспомнил. Третий — дописывать тест на каждый найденный баг, чтобы он не вернулся; отдельного бюджета этот шаг уже не требует.
| Шаг | Что закрывает | Когда окупается |
|---|---|---|
| Тесты на денежный путь | Поломки корзины, оплаты и форм | С первой предотвращённой поломкой оформления заказа |
| Прогон при выкладке | Правки, которые ломают соседний функционал | На втором-третьем релизе |
| Тест на каждый баг | Возврат старых ошибок | Сразу, отдельных затрат нет |
Если писать тесты некому, это типовая задача для выделенной команды разработчиков или разовых работ в рамках технической поддержки сайта — в обоих случаях начинают с денежного пути, а не с полного покрытия.











