Left Shift Testing: как выстроить процесс, чтобы тесты реально помогали
В статье разбираем современный подход к автоматизации тестирования — от требований до продакшена. Как писать автотесты ещё до выката фичи, запускать их в изоляции, работать в одной ветке с разработчиком и ловить баги раньше, чем они попадут на стенд. Реальные практики, понятные схемы и причины, почему "автоматизация после релиза" — путь в никуда.
Вступление
В этой статье я хочу поделиться взглядом на то, каким может быть оптимальный процесс автоматизации тестирования. Мы разберём, зачем он нужен, почему именно такой подход может считаться эффективным, а также какие плюсы и минусы он несёт. Важной частью статьи станет анализ рисков, к которым может привести нарушение или игнорирование этих процессов. Кроме того, мы ответим на частый вопрос: когда и какие тесты стоит запускать на CI/CD, чтобы это было максимально эффективно и стабильно.
Сразу хочу подчеркнуть: в этой статье мы будем говорить исключительно о концепции процесса, а не о технической реализации. Здесь не будет примеров кода, конфигураций CI/CD, или привязки к конкретным инструментам и фреймворкам. Цель статьи — описать качественную архитектуру процесса автоматизации, которая может быть адаптирована под любой технологический стек.
Ведь в каждой компании свои инструменты, процессы, команды и особенности CI/CD. Универсального "рецепта" не существует — но существует направление движения и принципы, к которым стоит стремиться. Если же вас интересуют технические детали, реализация автотестов или настройка пайплайнов, рекомендую ознакомиться с другими моими статьями:
Также важно отметить, что описанный здесь процесс — это обобщённая концепция. В зависимости от специфики проекта, команды или компании он может меняться. Это не жёсткий шаблон, а скорее ориентир, позволяющий построить стабильную, понятную и эффективную систему автоматизации. Подходите к нему критически и адаптируйте под свои условия — но старайтесь двигаться в этом направлении.
0. Требования
Всё начинается с появления требований — будь то новая функциональность или доработка существующей. На этом этапе ещё нет ни кода, ни тестов — только описание того, что должно быть реализовано. Сейчас мы не будем углубляться в детали того, откуда берутся требования, кто их пишет (аналитики, продакт-менеджеры и т.д.) и как они оформляются. Нас интересует роль инженера по автоматизации тестирования в этом процессе.
На этапе работы с требованиями QA Automation Engineer может и должен подключаться так же, как и другие QA-инженеры. Важные активности на этом этапе:
- Участие в ревью требований: проверка на полноту, непротиворечивость, тестируемость;
- Выявление потенциальных рисков или неясностей, требующих уточнений;
- Создание чек-листов или заметок под будущие автотесты;
- Оценка сложности автоматизации с точки зрения архитектуры, стека, времени.
Однако на этом этапе не стоит пытаться писать тесты или проектировать систему полностью — ваша задача пока в том, чтобы подготовиться и внести свой вклад в формирование качественных требований. А также оценить, сколько времени потребуется на написание или корректировку автотестов для данной функциональности.
1. Начало разработки
Следующий этап — начало разработки, когда фича официально переходит в статус "In Progress". С точки зрения тестирования это пока "пустая" стадия — функциональность ещё не реализована, и запускать тесты просто не на что. Но несмотря на это, автоматизатор уже может начать работу.
Вот какие задачи стоит выполнять на этом этапе:
- Создание базовых объектов для UI-тестов: страницы, элементы, локаторы;
- Подготовка шаблонов тестов: "болванки" с заранее прописанными структурами и шагами;
- Разметка тестов: добавление тегов, маркировок, групп (например, @smoke, @regression);
- Инфраструктура для тестов:Фикстуры,Клиенты для API,Доработки общих библиотек,Pydantic-модели (или другие схемы данных),Вспомогательные утилиты;
- Коммуникация с разработчиками: договориться о добавлении data-test-id, ID, уникальных классов и других элементов, необходимых для стабильных автотестов.
Этот этап можно кратко охарактеризовать как подготовку инфраструктуры под автотесты. Даже если сами тесты ещё не пишутся, заранее подготовленная среда позволяет в дальнейшем значительно сократить время на реализацию и избежать накопления технического долга.
Важно понимать: не всегда и не везде это возможно. Где-то фича слишком нестабильна, где-то слишком динамичный процесс, а где-то просто нет смысла заранее тратить время. Однако если это возможно — лучше начать подготовку заранее. Это убережёт от ситуаций, когда в продакшн улетает "огромный" pull request с тестами на 1500 строк, написанными в спешке.
2. Работа в фича-ветке
После завершения реализации задачи разработчиком наступает момент, когда в игру вступает QA Automation Engineer. Идеальный процесс предполагает, что автотесты пишутся прямо в той же фича-ветке, где была реализована новая функциональность. Это ключевой момент в построении качественного и быстрого процесса автоматизации.
Что делает автоматизатор на этом этапе:
- Для UI-тестов:Локально поднимается фронтенд-приложение;Серверная часть мокается (эмуляция API-ответов);Создаются и выполняются автотесты на новую фичу.
- Для API-тестов:Локально поднимается backend-сервис;Все внешние зависимости (БД, Redis, очереди, сторонние сервисы) заменяются моками;Проводится локальное тестирование с использованием реального кода, но без сторонних интеграций.
Сегодня поднятие локального окружения, как правило, не вызывает сложностей, особенно если используется docker и docker-compose. Если у проекта ещё нет удобных скриптов для запуска, можно попросить разработчиков — для них это обычно пара часов работы. В качестве моков можно использовать как кастомные решения, так и готовые инструменты вроде WireMock, MockServer, Hoverfly и других.
Цель этого этапа — провести максимально полноценное локальное тестирование фичи без необходимости выкладки на dev-окружение.
Локальное тестирование (Left Shift Testing)
Такой подход, когда тестирование выполняется до деплоя, ещё называют Left Shift Testing. Это означает «сдвиг тестирования влево» — к более ранним этапам разработки. У него есть множество преимуществ.
Преимущества Left Shift Testing:
- Быстрая коммуникация. Автоматизатор и разработчик работают "в одной связке", буквально в одной ветке. Любые вопросы и баги решаются на месте, без бюрократии и лишнего трекинга задач.
- Мгновенная обратная связь. Нашли баг — тут же сообщили разработчику, он сразу внёс правки. Тестировщик подтянул изменения в локальную ветку и продолжает проверку. Нет ожиданий, нет повторных деплоев.
- Существенная экономия времени. Один деплой на dev-окружение может занимать 20–30 минут. При классическом процессе (баг → возврат → исправление → новый деплой) можно потерять до 4 часов только на ожидание. Здесь же цикл занимает несколько минут.
- Изоляция фич и предсказуемость. Автотесты пишутся и прогоняются до мерджа. Это исключает ситуации, когда одна фича ломает другую. Если что-то пошло не так, мы точно знаем — проблема в текущей ветке.
Подход Left Shift Testing требует определённой зрелости процессов и культуры внутри команды, но он кардинально ускоряет разработку, снижает количество дефектов в продакшене и делает автоматизацию частью разработки, а не "прицепом в конце".
Общая инфраструктура: чемодан автоматизатора
Важный момент! Когда тесты пишутся в разных проектах и запускаются локально, очень часто возникает дублирование кода: вспомогательные функции, фикстуры, утилиты, конфигурации, обёртки над клиентами и многое другое. Особенно эта проблема проявляется в командах, работающих с микросервисной архитектурой, где каждый сервис может иметь свой репозиторий и свою тестовую инфраструктуру.
Чтобы избежать этого, рекомендуется выносить всё общее в отдельные переиспользуемые модули:
- Общие утилиты и вспомогательные функции;
- API/DB-клиенты;
- Pydantic-модели, схемы, enum'ы;
- Фикстуры и плагины для фреймворков (например, pytest);
- Конфигурации и шаблоны запуска;
- Общие тестовые фреймворки и базовые классы;
- Константы: tags, features, suites, epics;
- Шаблоны CI/CD, базовые docker-образы и т.п.
Такие модули можно оформить как:
- Отдельную библиотеку, устанавливаемую через пакетный менеджер (с приватного Nexus, Git или локального артефакт-менеджера);
- Git submodule или monorepo-подпроект, если нужен tight coupling;
- Общий workspace/инфраструктурный репозиторий внутри компании.
Это ваш "чемодан автоматизатора" — вы приходите с ним на новый проект, быстро всё подключаете, и можете сразу писать автотесты без повторной настройки окружения и копипаста кода.
Преимущества подхода:
- Нет дублирования кода между сервисами;
- Все обновления и фиксы делаются в одном месте;
- Упрощается сопровождение, повышается стабильность;
- Быстрый старт нового проекта;
- Унифицированные шаблоны и best practices распространяются на все команды.
Такой подход особенно хорошо работает в крупных компаниях или продуктовых командах с несколькими микросервисами. Он делает процесс автоматизации масштабируемым, гибким и профессиональным.
3. Выгрузка тестов на CI/CD
После того как автотесты написаны и фича протестирована локально, переходим к следующему шагу: выгрузка кода в репозиторий и автоматический запуск тестов в CI/CD.
Что происходит на этом этапе:
- Мы пушим изменения в репозиторий. Как правило, фича и автотесты находятся в одном репозитории, в одной ветке.
- CI/CD запускает пайплайн. Сначала поднимается нужное окружение (приложение, БД, зависимости и т.п.), затем запускаются автотесты.
- Если инфраструктура CI/CD еще не готова — не стесняйтесь попросить помощи у разработчиков. Обычно они легко могут:Добавить шаги запуска сервиса в пайплайн;Настроить запуск тестов в нужной фазе (например, после сборки, но до мерджа в основную ветку).
Такой подход называется изоляционное тестирование (Isolation Testing) — когда тесты запускаются вместе с фичей, в изолированной среде, до попадания кода на общий dev/stage/prod стенд.
Преимущества изоляционного тестирования
Упрощённая коммуникация и быстрая обратная связь:
- Разработчик и тестировщик работают в одной ветке, в одном контексте.
- Никаких "билетов в два конца" между тестировщиком и разработчиком: баги можно чинить и проверять буквально в одном коммите.
- Нет ожидания деплоев: исправили — запустили — проверили. Минуты вместо часов.
Лёгкая локализация проблем:
- Если что-то сломалось — это точно в этой фиче, никаких "соседних" фич в пайплайне нет.
- Исключается ситуация, когда в dev-окружение влетает 10 задач, и вы не понимаете, кто поломал ваши тесты.
Быстрые и стабильные тесты:
- Тесты работают на локальных моках, не зависят от нестабильности внешнего dev/staging-окружения, интеграции с партнерами.
- Тесты становятся атомарными, короткими и предсказуемыми.
- Если тест упал — почти всегда это реальный баг, а не "моргнуло электричество".
Тесты — часть фичи, а не внешняя сущность:
- Тесты живут рядом с кодом, не "в отдельном мире".
- Разработчики начинают вовлекаться: видят тесты, запускают, правят, пишут/помогают писать.
- Выстраивается здоровая инженерная культура, когда тестирование — часть продукта, а не "то, что QA где-то сам делает".
Такой подход значительно ускоряет цикл разработки, снижает количество багов на стенде и повышает качество тестов. Изоляционное тестирование — важный шаг в построении зрелого процесса автоматизации.
4. Деплой на окружение и интеграционное тестирование
Только после успешного локального тестирования и прохождения изоляционных тестов на CI/CD, фича попадает на общее окружение (Dev / Stable / Staging).
Что происходит на этом этапе:
- Фича деплоится на стенд. Обычно это dev или staging окружение — в зависимости от этапа разработки.
- Запускается скоуп стабильных интеграционных тестов. Чаще всего это sanity/smoke-набор: короткие, но показательные тесты, которые проверяют общую "жизнеспособность" системы.
Цель интеграционного тестирования
Важно понимать: цель интеграционных тестов — не протестировать фичу. Эта работа уже сделана ранее — локально, изолированно, в фича-ветке.
Интеграционное тестирование нужно для:
- Проверки, что новая фича не сломала остальную систему;
- Убедиться, что все модули и сервисы взаимодействуют корректно;
- При необходимости — обновить или дописать интеграционные тесты, если система изменилась.
Что делать, если найдены баги?
- Разработчик правит баги в своей фича-ветке.
- Повторяется цикл:Изоляционное тестирование;Интеграционное тестирование;И так до стабильного результата.
Перед продакшен-деплоем
- Собирается новый тег/версия.
- Прогоняется регрессионный скоуп изоляционных тестов — прямо из репозитория сервиса или приложения. Это финальная гарантия того, что текущая версия работает стабильно и предсказуемо.
- Если всё проходит — фича выкатывается в прод.
Такой подход позволяет:
- Минимизировать риски перед выкладкой;
- Быстро ловить критические баги на стейдже, а не в проде;
- Обеспечить баланс между скоростью и стабильностью релизов.
Пример процесса на схемах
На схеме ниже — полный процесс с изоляционными и интеграционными тестами:
На второй схеме — упрощённый процесс, где сразу после деплоя запускаются только интеграционные тесты:
Такой упрощённый вариант можно использовать:
- В начале проекта
- При ограничениях по времени/ресурсам/компетенциям
- Если команда ещё не готова к полноценной изоляционной автоматизации
Какие риски закрываются данным процессом?
Чтобы понять ценность изоляционного подхода, давайте представим обратную ситуацию — когда автоматизация тестирования существует отдельно от разработки. Тесты пишутся не во время реализации фичи, а постфактум, уже после релиза, с ощутимым опозданием.
Что в таком случае происходит?
1. Автоматизация теряет ценность
Если фича уехала с багами, а тесты пишутся позже, то:
- Тесты не ловят баги до релиза;
- Обратная связь поступает слишком поздно;
- Баги могут всплыть уже в проде, и это дорого;
- А должна быть: ранняя диагностика — ранняя реакция.
2. Разрыв между разработкой и тестированием
Когда автоматизатор не участвует в процессе разработки:
- Уходит контекст: нет живого понимания логики, зависимостей, "подводных камней";
- Возникают ошибки в тест-кейсах и сценариях;
- Тесты становятся поверхностными и слабо покрывают критичные пути.
3. Невозможность быстро локализовать баг
Если тесты не запускаются в изоляции:
- Мы не знаем, в какой фиче и в какой ветке произошёл сбой;
- Начинаются долгие выяснения: "А это точно не твой тест?", "А у нас всё работало";
- Возникают "битые" релизы, которые сложно откатить.
4. Отсутствие вовлечённости разработчиков
Без изоляционного подхода:
- Разработчики не видят "красных" тестов в своей ветке;
- Нет вовлечения в поддержку и исправление тестов;
- Нет общей ответственности за качество.
А ведь разработчик — первый человек, кто может быстро починить баг или добавить недостающий идентификатор для UI.
5. Нестабильность окружения убивает надёжность тестов
Когда тесты запускаются только на dev/staging/prod окружениях:
- Они становятся заложниками нестабильной среды (рассинхрон сервисов, очередь не работает, база не поднялась);
- Медленные, тяжеловесные, зависимые от внешних факторов;
- Постоянные флейки → Падает доверие к тестам.
6. Красные тесты → игнор → обесценивание
Когда тесты часто падают:
- Команда начинает игнорировать отчёты ("Они всегда красные");
- Тесты воспринимаются как помеха, а не как инструмент контроля;
- В итоге: вложений много, пользы — минимум.
А что даёт изоляционный процесс?
- Быстрая обратная связь;
- Совместная ответственность;
- Локализация проблем;
- Минимизация багов в проде;
- Повышение доверия к автотестам;
- Культура качества — не на словах, а в процессе.
Реально ли это?
Да, абсолютно реально. И если на первый взгляд процесс кажется сложным или даже невозможным — скорее всего, это говорит не о его нереалистичности, а о нехватке практического опыта в автоматизации тестирования, понимании CI/CD, инфраструктуры или построении зрелых инженерных процессов.
Это не упрёк — это нормальный этап развития. Всё, что описано в статье, не теория: процесс уже успешно работает в десятках команд и проектах, был отточен за год реального боевого использования, и доказал свою надёжность.
Он не родился из воздуха. Он появился как ответ на реальные проблемы и боли. И если хочется внедрить по-настоящему устойчивую практику автотестирования — другого пути просто нет.
Можно идти к этому поэтапно, не обязательно внедрять всё сразу. Главное — не останавливаться на "у нас не получится", а разбираться, пробовать, задавать вопросы и расти как инженер.
Вывод
Современная автоматизация — это не просто "писать тесты", а стать частью процесса разработки. Чем раньше мы встраиваемся в цикл — тем больше пользы приносим.
Изоляционное тестирование — это не про контроль, а про партнёрство:
- Разработчик и тестировщик работают в одной ветке,
- делят ответственность,
- ловят баги ещё до релиза,
- и вместе делают продукт надёжнее.
Это и есть настоящая культура качества. Не отчёты ради галочки. А живая, полезная автоматизация, которая работает на продукт — каждый день.