Документация есть, тесты написаны, проверки закончили, даже QA не выгоревший. И всё равно за день до выкладки что-то ломается. Мы собрали истории — из больших и не очень команд — о том, как баги всплывают в последний момент и что с этим делать, если вы не Google, а просто хотите выкатиться без боли.
Почему баги вообще попадают в релиз
Считается, что в больших технологических компаниях ошибки в релизах — редкость. Код проходит несколько уровней проверки: автотесты, ручное тестирование, выкладка на часть пользователей с мониторингом. Всё это это снижает шанс, что баг доживёт до продакшена.
В стартапах ценится скорость. Чем быстрее релиз, тем быстрее проверка гипотезы. Если что-то сломается — починим. Если повезёт — пронесёт. Баги здесь — не ЧП, а часть процесса. Особенно это заметно в мобильной разработке. На вебе можно быстро откатить версию, но в App Store и Google Play фикс пройдёт модерацию не сразу. Бывает, что баг уже у пользователей, а обновление всё ещё на проверке.

Марина Матюшина
QA-тимлид, эксперт Нетологии по ручному тестированию
В условиях жёстких релизных сроков чаще всего на тестирование остаётся всего 1–2 дня. Был случай, когда в релиз новой фичи попал критический баг — он вызывал крэш приложения в старом функционале. Хотфикс подготовили оперативно, но на модерацию App Store ушло четыре дня. Пользователи массово обращались в поддержку, и мы с командой изрядно понервничали.
Но даже в крупных компаниях с сильными командами и процессами появляются ошибки — и часто из-за самого масштаба: количества компонентов, версий, фич, людей. Да и релиз в корпорациях не всегда можно отложить, чтобы исправить ошибку. Для бизнеса выпуск в конкретную дату может быть критичен. А ещё от своевременного выпуска фичи зависят маркетинговые задачи. Разберём причины багов.
Нереалистичная тестовая среда
В зрелых нагруженных продуктах тестовая и боевая среда — это два разных мира. На продакшене работают живые пользователи, система испытывает постоянную нагрузку, обрабатывает миллионы сущностей. Но писать и тестировать код в таких условиях неудобно: прод-среда тяжёлая и медленная. Поэтому почти везде используются синтетические или частично замоканные данные: фикстуры, сокращённые дампы, генерация «похожих» наборов. Такая среда — стерильна в сравнении с продом. Даже если всё покрыто автотестами, в реальности поведение может отличаться — просто потому, что данные и нагрузка другие.

Евгений Корытов
Техлидер в Яндексе, преподаватель Нетологии по направлениям: QA, SQL, PHP, JS
В небольших проектах, где мало данных, иногда удаётся копировать продакшен целиком: разработчик и тестировщик в итоге видят систему так же, как пользователь, и воспроизводимость поведения достигается почти идеально. Но в крупных продуктах это невозможно. Для локальной разработки будет слишком большой объём данных и высокая нагрузка. К тому же реальные данные часто нельзя использовать из-за политики безопасности.
Поэтому разработчики берут урезанные или синтетические данные — это быстро, безопасно, но не как в реальности. Часто это приводит к ложноположительным результатам тестов, а в итоге — к багам после релиза, которых не было видно на тестовом стенде.


Марина Матюшина
QA-тимлид, эксперт Нетологии по ручному тестированию
Когда мы тестировали в приложении игровую механику с мок-анимацией, всё работало без проблем. Но перед релизом дизайнеры отдали финальные анимации, и с ними приложение начало падать через пару минут после запуска. Оказалось, новая анимация вызывала утечку памяти на устройстве и оно просто не справлялось. Хорошо, что мы успели протестировать именно финальный вариант, иначе баг бы ушёл в прод.
С тех пор решили: даже тестовые данные должны быть по сложности максимально приближены к реальности. Так получится снизить риск багов перед релизом.
Ошибки в планировании
Команда получает задачу «сделать фичу до пятницы», но разработка затягивается, и на тестирование остаётся день или несколько часов. Тестировщик может предупредить, что времени не хватает, но внутри команды уже действует установка «надо выкатиться». QA начинает проверку в пятницу вечером, тратит личное время, но в итоге может не успеть всё тщательно проверить. Это не вина разработчиков — просто сроки определили, не учитывая контекста проекта.
Нехватка ресурсов
Во многих командах на весь проект может быть один тестировщик. Даже если автоматизировали регрессионное тестирование, может не хватить рук на его поддержку. Например, внедрили новую функциональность, но автоматизация покрывает только стабильную часть продукта. Проверять приходится вручную. В таких условиях внимание быстро рассеивается: баги не замечаются, приоритеты путаются. Тестировщик может выбрать неправильную стратегию тестирования.

Марина Матюшина
QA-тимлид, эксперт Нетологии по ручному тестированию
Я много раз обжигалась на том, что недооценивала влияние новой фичи на старый функционал. Всё протестировано, отлажено — кажется, можно выкатывать. А на финальном smoke-прогоне вдруг ломается базовый сценарий, который вообще не трогали. Менеджмент уже готов к релизу, а ты откладываешь запуск из-за бага, который всплыл в самый последний момент.
Когда подключаются слишком поздно — и тестировщики, и продакты
Позднее подключение любого участника проекта — это почти всегда путь к повторным циклам проверки, багам на ровном месте и откатам перед релизом. Когда тестировщик подключается на груминге и слышит, чего хочет продакт, он сразу видит проблемы. А если узнаёт о фиче уже на этапе сборки, то проверяет вслепую: нет ни контекста, ни понимания, что действительно важно. Макет в Figma не расскажет, как должна вести себя система в редких кейсах. Похожая ситуация бывает и с продактами, если они подключаются уже на финальной сборке.

Марина Матюшина
QA-тимлид, эксперт Нетологии по ручному тестированию
Оунером фичи был новый продакт, который раньше работал в big tech, где продуктовое ревью проводили уже после разработки и тестирования. Мы сосредоточились на функциональности, всё отладили. На финальной сборке выяснилось, что для продакта были важны детали, которые мы, тестировщики, считали мелочами: интервалы и шрифты. Пришлось вносить правки в последний момент. После этого договорились: дизайн-ревью проводим на первых стабильных сборках, чтобы такое не всплывало впритык к релизу.
Недоговорённости и расхождения в ожиданиях
Многие баги появляются не из-за кода или тестов, а потому, что каждый понял по-своему и не уточнил. Фичу обсудили, макеты показали — все кивают. А потом выясняется, что продакт имел в виду что-то своё, дизайнер упустил важную деталь в макете, и разработчик понял задачу неправильно. Бывает и так, что не разделяют этапы: ждут, что к дате будет готов не только код, но и тестирование, хотя никто этого явно не проговорил. Такие недопонимания случаются даже в сильных командах, если всё строится на предположениях, а не на уточнениях.
Дорогая комбинаторика
Современные продукты — чаще не монолит, а набор микросервисов. Даже при двух сервисах (фронтенд + бэкенд) формируется минимум 3–4 окружения:
продакшен-версия — стабильная, обкатанная;
релиз-кандидат — сборка, которая готовится к выкладке;
разработческие ветки — часто нестабильные и активно меняющиеся;
общее тестовое окружение, куда сливаются фичи со всей команды.
Чем больше сервисов интегрируют друг с другом, тем сложнее комбинаторика. А для многих компаний проверить все возможные сочетания — слишком дорого, долго и сложно. На практике это означает:
что фронтенд может быть протестирован с нестабильным бэкендом;
бэкенд может быть протестирован с нестабильным фронтом;
продакшен может получить новую версию одного компонента, несовместимую со старой версией другого.
Из-за этого возникают дефекты, которых не было видно ни на стенде, ни в автотестах:
компонент ожидает одни поля, а получает другие;
ломается обратная совместимость;
пользователи видят ошибки, которых не существует в тестовой сборке.


Евгений Корытов
Техлидер в Яндексе, преподаватель Нетологии по направлениям: QA, SQL, PHP, JS
Ситуацию с дорогой комбинаторикой осложняет несовпадение жизненных циклов разных компонентов продукта. Чтобы оптимизировать процессы и расходы, компании или команды часто используют один общий тестинг или стейджинг. В нём есть набор тестовых данных, версий бэкенд- и фронтенд-сервисов, файлов конфигураций. Но фронтенд и бэкенд почти всегда выкатываются независимо. Даже если запуск формально идёт одновременно, между компонентами неизбежен лаг: на проде они живут не в том состоянии, в котором тестировались.
В итоге команда тестирует сборную солянку, а релизится каждый компонент по-своему. Это особенно критично для мобильных приложений: из-за долгой модерации в сторах одна часть системы может обновиться, а другая — ещё нет. Так появляется несовместимость, которую никто не заложил в тест-план.
Сборные релизы: десятки фич в одном котле
В больших продуктах релизы чаще всего не выкатываются по одной фиче: это технически сложно, дорого, да и пользователи обычно не готовы к частым обновлениям. Вместо непрерывной доставки команды собирают релиз-кандидатов: в одной сборке сливаются десятки изменений от разных разработчиков. Так проще координировать выкладки и экономить ресурсы. Обратная сторона медали: в прод уходит не просто одна фича, а целый набор потенциальных конфликтов.

В изоляции каждая фича может быть проверена и выглядеть стабильной. Но в реальности всё иначе. Пока одни дорабатывают баги, другие продолжают выкатывать новые правки. QA проверяет не финальную версию релиза, а нечто промежуточное. Часто найденные баги устраняются на лету — и в процессе чинят одно, а ломают другое.
Такая структура релизов приводит к порочному циклу:
Собирается релиз-кандидат.
QA находит баг.
Разработчики правят и случайно затрагивают соседние фичи.
Формируется новый релиз-кандидат, уже с другими конфликтами.
Чем дольше длится цикл, тем сильнее он расходится с реальностью. Уже протестированная фича начинает вести себя иначе просто потому, что контекст поменялся.

Любовь Маясова
QA-лид в Райффайзен Банке
У нас была фича с жёстким сроком. Всех торопили, разработчиков собирали из разных команд — лишь бы успеть. Начинаю тестировать и понимаю: задача не автономная, она зависит от интеграции с другим сервисом. Выяснила, что команда этого сервиса интеграцию с нашим не учла. Пока собирали встречи, обсуждали и дорабатывали, прошло больше месяца. Планировали выкатить в конце сентября, а по факту сделали это в ноябре.
Проблемы с фича-флагами и рефакторингом
Фича-флаги — распространённый способ выкатывать фичи безопасно. Код уходит в прод, но скрыт от пользователей. Этот же механизм используют для A/B-тестов или запуска экспериментальных функций.
Когда таких флагов десятки и сотни, продукт превращается в конструктор со множеством скрытых модулей. Тестирование чаще всего проходит с выключенными флагами — а значит, не проверяет, как фичи работают в реальности. Включение происходит позже, вручную или по расписанию. И именно в этот момент начинаются проблемы. Новая фича может конфликтовать с уже включёнными. А поскольку релиз давно прошёл, никто не связывает баг с недавними флагами. Начинается расследование, метание по логам и поиск виноватого.

Марина Матюшина
QA-тимлид, эксперт Нетологии по ручному тестированию
Мы несколько раз перерабатывали онбординг. В итоге накопилось пять его разных версий в коде. Чтобы удалять неуспешные варианты, надо было рефакторить и перепроверять всё, что связано с регистрацией. Времени на это не было, поэтому код не трогали. А потом включили новую фичу, и она внезапно поломала старый блок, к которому никто не прикасался. Всё потому, что в нём была зависимость, про которую уже забыли.
Хотфиксы и «давай быстренько поправим»
Хотфиксы почти всегда возникают из-за длинного релизного цикла: фича попала в сборку не сразу, а значит, ждать следующего релиза придётся неделями, а то и месяцами. Если это не мобильное приложение и не прошивка для устройства, а обычный веб, разработчика могут попросить внести срочную правку. Это ускорение почти всегда идёт в обход стандартного пайплайна: без регресса, а сразу на прод.
Хотфиксы выглядят некритичными, особенно если фича небольшая, изменение точечное, а дедлайн — вчера. Но в реальности это риск: даже опытный разработчик не всегда может предусмотреть все последствия в связанном или устаревшем коде. Проблема не в квалификации разработчика, а в условиях: ночной деплой, отсутствие тестов, спешка, давящие сроки. И чем больше спешки — тем выше шанс, что хотфикс приведёт к более критичному багу.

Евгений Корытов
Техлидер в Яндексе, преподаватель Нетологии по направлениям: QA, SQL, PHP, JS
Да, такое может произойти с любым. Например, был случай: я добавил правку в самый последний момент, не проверил даже локально — всё казалось очевидным. Выкатить хотфикс надо было срочно, чтобы не блокировать важную работу смежной команды, поэтому сделал это ночью. Картинки исчезли у миллионов пользователей. Хорошо, что всё было под фича-флагом — выключил и лёг спать, а утром исправил.
Просто все устали
Иногда проблема не в системе, а в команде, которая вымоталась.

Марина Матюшина
QA-тимлид, эксперт Нетологии по ручному тестированию
Незадолго до релиза мы в команде решили упростить себе жизнь. Разработчик вручную прописал в сборке ссылку на dev-среду, чтобы каждый раз не вводить данные вручную. Dev-окружение почти ничем не отличалось от продакшена, поэтому перед релизом никто не заметил подмены. Ни проверку конфигурации, ни мониторинг трафика (который бы сразу выявил проблему) не сделали: упустили это из-за усталости и цейтнота. Пользователи массово получили нерабочее приложение.
Парадоксально, но ошибка казалась настолько очевидной, что её даже не рассматривали как возможную. Ситуацию спасли бэкенд-разработчики. Они использовали подход blue-green deployment: быстро переключили пользователей с обновлённой версии приложения на стабильную. Затем выкатили хотфикс в стор.
Что помогает: 10 способов от smoke-тестов до чек-листов для разработки
Ошибки будут. Вопрос в том, насколько команда готова к ним. Хорошая подготовка не гарантирует отсутствия багов, но точно снижает риск того, что они обойдутся дорого.
1. Smoke-тесты по зонам риска
Новый функционал может работать идеально, но при этом незаметно сломать что-то старое: авторизацию, оплату, регистрацию. Поэтому перед релизом важно проходить сквозные сценарии, которые отражают реальный путь пользователя. Даже если автоматизация работает, она не всегда покрывает всё в продукте. Smoke-тест — это ручная или полуавтоматическая проверка ключевых зон, без которой легко пропустить фатальный баг.

Марина Матюшина
QA-тимлид, эксперт Нетологии по ручному тестированию
Я не раз попадала в ситуацию, когда фича — отличная, а старый сценарий не работает. Просто фокусировалась на новом. Теперь у меня всегда есть список критичных сценариев.
2. Shift-left-подход
Shift-left-тестирование — это подход, при котором тестировщик подключается до разработки. В продуктовых командах это критично: документация есть не всегда или она неполная, и единственное, на что можно опереться — это макеты и обсуждения.
Если QA подключается ещё на груминге, он слышит, как продакт формулирует задачу, какие сценарии для него важны. Разработчики в этот момент делят фичу на задачи, а тестировщик уже понимает, где могут быть риски, что продумано, а что нет. Это особенно важно, если дело касается мобильных приложений, где часто забывают об обработке ошибок, плохом интернете, нестандартном вводе.

Любовь Маясова
QA-лид в Райффайзен Банке
Я приходила на презентации макетов и почти всегда задавала кучу вопросов. А что будет, если пользователь нажмёт сюда? А если отключится сеть? Как выглядит ошибка? И дизайнеры потом меняли макет. Не потому, что плохо сделали, — просто для тестировщика такие нюансы очевиднее.
Подключение тестировщика на ранних этапах помогает сразу заложить нужные сценарии и сверить ожидания продакта, дизайнера, разработчика и тестировщика. И чем раньше QA попадает в обсуждение — тем меньше багов потом.
3. Прозрачная приоритизация
Для одного важнее сломанный экран в старом разделе, для другого — неправильный отступ на баннере. Именно поэтому команда должна заранее договориться, как она определяет приоритеты: что считать блокером, а что можно править после релиза.

Марина Матюшина
QA-тимлид, эксперт Нетологии по ручному тестированию
У нас была новая фича, и казалось, что главное — чтобы всё работало. Но для продакта не менее важной была аналитика по этой фиче. Мы недосмотрели: в событиях не все параметры отправлялись корректно. А их там немало: в одном ивенте 5–10 штук — часть дефолтная, часть изменяемая. Всё это нужно проверять. В итоге у продактов рушились A/B-тесты из-за искажённых метрик и они не могли понять, насколько фича эффективна.
4. Больше автоматизации
Если баг всплыл на финишной прямой, команда делает root cause analysis и добавляет сценарий в автотесты, чтобы проблема не повторилась.
Сам запуск тестов тоже можно автоматизировать, чтобы не зависеть от внимания и свободного времени QA, но ловить критичные баги до ручного тестирования.

Любовь Маясова
QA-лид в Райффайзен Банке
Как только собирается релизный пакет, у нас сразу летят базовые проверки. Это снимает риски до того, как QA даже откроет сборку.
5. Debug-инструменты и ускорители тестирования
Разработчики могут сильно облегчить тестирование, если заранее встроят:
debug-меню с возможностью пропустить этапы — например, авторизацию или прохождение сценария до конца;
кнопки, эмулирующие нужные состояния: ошибку сети, крэш, покупку;
упрощённые режимы теста, которые не искажают поведение, но экономят время.

Марина Матюшина
QA-тимлид, эксперт Нетологии по ручному тестированию
У нас в приложении были тренировки по иностранному языку. Чтобы проверить финальную анимацию, мне нужно было пройти каждую тренировку вручную. Разработчики сделали режим с автопрохождением и сэкономили мне время.
6. Канареечный деплой и аналитика
Чтобы понять, как новая фича поведёт себя «вживую», нужен доступ к боевому окружению, но без риска обрушить продакшен. Здесь помогает канареечный деплой.
Суть простая: новую версию выкатывают не сразу на весь трафик, а на 1–5% пользователей. Это может быть конкретная география, сегмент или A/B-группа. Главное — выкладка идёт малыми порциями. Дальше команда смотрит на метрики, алерты, логи, поведение пользователей. Если всё спокойно — выкладывают дальше. Если что-то пошло не так — откатывают.

Евгений Корытов
Техлидер в Яндексе, преподаватель Нетологии по направлениям: QA, SQL, PHP, JS
Это очень хорошая практика: она показывает, как всё работает на боевых данных и под настоящей нагрузкой. Так команда вероятнее успеет откатиться до того, как всё у всех сломается. Однако нужно иметь полноценные дашборды, графики, мониторинги, систему алертов, чтобы вовремя увидеть проблему. Кроме того, важно помнить, что такой подход — не замена тестированию.
Чтобы равномерно покрыть функциональность тестами, у QA должен быть доступ к аналитике: какие устройства самые популярные, где чаще всего случаются сбои. Статистика помогает понять, какие конфигурации самые популярные, — и именно на них нужно фокусироваться при тестировании.

Марина Матюшина
QA-тимлид, эксперт Нетологии по ручному тестированию
Был случай, когда приложение отлично работало на флагманских смартфонах — именно на них мы и тестировали. А потом, уже после релиза, начали приходить жалобы: на планшетах оно падало сразу при запуске. Эмуляторы проблему не показывали, а сами планшеты в тест-план не попали. С тех пор мы регулярно смотрим аналитику установок и крэш-репорты. Для QA это самый надёжный источник правды о том, как ведёт себя продукт у реальных пользователей.
7. Юнит-тесты, или предварительная проверка разработчиков
Хорошая практика: разработчик, перед тем как отдать сборку, сам проходит базовый сценарий и проверяет, работает ли хотя бы критичный функционал.

Марина Матюшина
QA-тимлид, эксперт Нетологии по ручному тестированию
Если я открываю сборку, а она просто не запускается — это минус полдня. Лучше, если разработчик сам убедится, что хотя бы основное не ломается. Некоторые команды даже составляют небольшой чек-лист для разработчика — неформальный список того, что нужно пройти перед передачей в тест.

Любовь Маясова
QA-лид в Райффайзен Банке
Когда мы писали стратегию тестирования, я предложила покрывать базовые вещи юнит-тестами — и на фронте, и на бэке. Бэкенд это спокойно принял: ребята и раньше так работали. А вот фронтенд сперва сопротивлялся: мол, у нас же есть UI-тесты, зачем ещё что-то? Пришлось объяснить, что UI-тесты нестабильные и тяжело поддерживаются. В итоге договорились: хотя бы основные компоненты и отрисовку страниц покрываем юнитами.
8. Blame-free-культура
Если после каждого релиза начинается поиск виноватых — команда замолкает. Люди боятся поднимать проблемы, не хотят признаваться в ошибках и работают в страхе. Это мешает общению и влияет на качество продукта.

Марина Матюшина
QA-тимлид, эксперт Нетологии по ручному тестированию
Если на ретро спросили: «Почему вы не нашли баг раньше?», — в следующий раз человек просто скроет проблему, чтобы его не осудили. Намного полезнее спрашивать: «Окей, баг есть — что сделаем, чтобы такого больше не было?». Когда команда ищет не виноватых, а решение, люди перестают бояться говорить о проблемах. Именно это помогает избежать серьёзных багов в будущем и сделать разработку и тестирование надёжнее.
9. День на дополнительную проверку
Перед релизом команде нужен хотя бы один рабочий день в запас, чтобы не экономить время в ущерб качеству.

Любовь Маясова
QA-лид в Райффайзен Банке
Мы поспешили: знали, что в одном браузере фича не работает, но решили, что процент пользователей маленький. Оказалось — 10% наших клиентов. Выкатились, получили жалобы и всё равно потратили время на правку — только уже в цейтноте.
10. План отката
Перед релизом важно заранее продумать, что делать, если фича сломает прод. Для веба — это откат версии или быстрый хотфикс. Для мобильных приложений — фича-флаг, который позволяет мгновенно выключить новую функциональность, не дожидаясь апдейта в сторе. Фича-флаги — это страховка, но ими нужно пользоваться ответственно: включать, отключать и удалять по плану. Если их копить, продукт превращается в зоопарк скрытых состояний и в какой-то момент включение старого флага приводит к багу, который вообще никто не ждал.

Евгений Корытов
Техлидер в Яндексе, преподаватель Нетологии по направлениям: QA, SQL, PHP, JS
На каждый релиз должен быть не только план выкатки, но и план отката — с доступами, инструкциями и пониманием, что делать, если что-то пойдёт не так. А если в проекте используются фича-флаги, важно вести логи: кто, когда и что включал или отключал. Иначе дежурный просто не поймёт, почему что-то сломалось: релиза же не было, а поведение системы поменялось.
Резюмируем
Почти всегда баги — это результат:
разных версий систем, плохо синхронизированных между собой;
отсутствия реалистичной среды;
давления дедлайнов;
нерегламентированных хотфиксов;
неуправляемого роста фича-флагов;
банальной человеческой усталости.
Контроль качества начинается не на этапе QA, а с момента, когда планируют фичу. Если команда готова обсуждать риски заранее, строить инфраструктуру под стабильную доставку и не боится сказать: «Мы не успеваем — давайте позже», — то багов будет меньше. Они всё равно будут — но хотя бы не критичные и не в пятницу вечером.

Прикоснуться к магии тестирования можно, начав с бесплатных занятий. А научиться релизить проекты без багов и выкатываться без боли позволит полноценное обучение профессии «Инженер по тестированию». Это курс с программой трудоустройства и возможностью выбрать траекторию обучения: manual, junior или middle, — а также язык программирования: Python или Java.
Специально для хабровчан действует скидочный промокод CODEHABR10.