Баг ушёл в прод: как QA пройти постмортем и не стать виноватым
Четверг, вечер. В чате поддержки растёт тред: у части пользователей не проходит оплата. Через десять минут кто-то из менеджеров пишет в общий канал: «А QA это вообще тестировал?» И вот он, момент, ради которого написана эта статья. Тестировщика в эту секунду тянет в одну из двух сторон: начать доказывать, что тестировал, или молча решить, что да, виноват, надо было лучше. Оба пути ведут не туда. Первый портит отношения с командой и ничего не меняет в процессе. Второй портит тебя и тоже ничего не меняет в процессе.
Есть третий путь, и у него есть название: blameless postmortem, разбор без поиска виноватых. Ниже о том, почему он работает, как в нём участвовать со стороны QA, и что делать, если в твоей компании разбор пока выглядит как трибунал.
Почему «кто виноват» — неправильный вопрос
Начнём с неудобной мысли: баг в проде — это почти никогда не провал одного человека. Чтобы дефект дошёл до пользователя, он должен был пройти сквозь требования, код, code review, автотесты, ручное тестирование, staging, релизный процесс и мониторинг. Каждый слой мог его поймать, ни один не поймал. Это модель «швейцарского сыра» Джеймса Ризона: инцидент случается, когда дырки в нескольких слоях защиты выстраиваются в одну линию. Ричард Кук в классическом эссе How Complex Systems Fail формулирует ещё жёстче: у катастрофы в сложной системе не бывает единственной первопричины, её требуется несколько отказов одновременно, и поиск «корня» — это скорее социальная потребность, чем техническая правда.
QA в этой цепочке — один слой. Важный, но один. Когда команда назначает виноватым тестировщика, она получает быстрое эмоциональное облегчение и ноль информации о том, почему остальные семь слоёв тоже пропустили.
Второй аргумент ещё практичнее. Google в главе про культуру постмортемов из SRE-книги объясняет, зачем им blameless: если за ошибку наказывают, люди перестают о них рассказывать. Инженер, который знает, что за честный рассказ «я нажал не ту кнопку» получит выговор, в следующий раз промолчит, и команда потеряет единственный источник данных о том, как на самом деле работает система. Джон Оллспо, который ввёл blameless-постмортемы в Etsy, называет это прямо: культура обвинения даёт компании меньше информации при большем количестве инцидентов.
Для QA это означает простую вещь: твоя задача на разборе не защититься и не покаяться. Твоя задача — принести максимум фактов о том, как дефект прошёл через тестирование, потому что без этих фактов процесс не починить.
Первые часы: что делать, пока ещё горит
Постмортем будет потом. Пока инцидент идёт, у тестировщика есть работа, и она полезнее любых объяснений в чате.
- Не оправдываться в общем канале. Реплика «я это проверял, у меня работало» в момент, когда у пользователей не проходит оплата, звучит как отказ от ответственности, даже если это чистая правда. Всё, что ты хочешь сказать про покрытие, скажи позже и с фактами.
- Локализовать. Самая ценная роль QA в инциденте — быстро сузить проблему: воспроизводится ли, на каких платформах, версиях, странах, у каких сегментов пользователей. «Падает только на Android 14 при оплате через Google Pay, iOS в порядке» — это сокращает поиск разработчикам на час.
- Оценить масштаб и найти обходной путь. Сколько пользователей затронуто, есть ли workaround для поддержки, нужно ли откатывать или можно жить до hotfix. Это то, о чём менеджер спросит первым.
- Проверить hotfix как следует. Под давлением «выкатывай быстрее» именно здесь рождается второй инцидент. Смок по затронутому сценарию плюс соседние сценарии, которые трогает фикс. Если времени на регресс нет, зафиксируй письменно, что именно не проверено.
- Собрать факты для будущего разбора, пока они свежие. Когда влит код, какой был тест-план, что из него прогонялось, на каком окружении, какие данные использовались, что было в требованиях. Через неделю половина этого забудется, а память у всех участников удобно исказится в свою пользу.
Отдельно про фразу вместо «я тестировал». Когда тебя всё-таки спрашивают в моменте, работает формула из трёх частей: что покрывалось, чего не было, почему. «Оплата проверялась на iOS и на Android 13 с тестовой картой. Google Pay на Android 14 не проверялся: в тест-плане его не было, тестовых устройств с 14 в команде нет». Это не оправдание и не признание, это данные. С ними можно работать, а с эмоцией нельзя.
Как устроен blameless-постмортем
Формат разбора у разных компаний немного отличается, но скелет один. Хорошие открытые шаблоны есть у Atlassian и у PagerDuty, а самый глубокий современный гайд — Howie от команды Jeli. Основные блоки:
- Impact. Что сломалось, для кого, на сколько времени, в деньгах или пользователях. Без этого не понять, стоит ли разбор вообще двух часов десяти человек.
- Timeline. Хронология по фактам с таймстампами: когда влито, когда задеплоено, когда первый сигнал, когда обнаружили, когда починили. Только события, без интерпретаций.
- Contributing factors. Не «root cause» в единственном числе, а список факторов, каждый из которых внёс вклад. Здесь живёт вся честность разбора.
- Что сработало. Что помогло обнаружить и починить быстро. Это не для утешения, а чтобы не сломать случайно то, что работает.
- Action items. Конкретные изменения с владельцем и сроком. О них отдельный раздел ниже.
Правил у формата два, и оба важнее шаблона.
Первое: запрет на контрфактуалы. Фразы «надо было», «если бы QA прогнал регресс», «должен был заметить» описывают воображаемый мир, а не тот, в котором случился инцидент. Они не объясняют, почему разумный человек в тот момент с той информацией сделал то, что сделал. Это и есть hindsight bias: после того как исход известен, он кажется очевидным заранее. На разборе полезнее спрашивать «что ты видел в тот момент и почему это выглядело нормально».
Второе: осторожно с «пятью почему». Метод популярен, но в сложных системах он почти всегда упирается в человека: «почему баг в проде? потому что не проверили; почему не проверили? потому что тестировщик не подумал». Оллспо в The Infinite Hows предлагает вместо линейного «почему» спрашивать «как»: как система была устроена так, что это стало возможным? «Как» даёт ветвящуюся картину и уводит от поиска крайнего.
Что говорить QA на разборе
У тестировщика на постмортеме есть уникальная позиция: он единственный, кто знает, как выглядел дефект с точки зрения проверки. Эти знания надо принести в виде фактов, и почти каждый факт превращается в системный фактор.
- Сценария не было в требованиях. Тогда фактор не «QA не додумался», а «требования не описывают крайние случаи оплаты, и нет этапа, где их уточняют». Action item про процесс требований, не про внимательность.
- Не было окружения или данных. Нет устройства с Android 14, нет тестового аккаунта с реальной картой, нет прод-подобной конфигурации. Фактор про инфраструктуру тестирования.
- Регресс урезали по срокам. Кто-то решил выкатить без полного прогона. Это решение, у него есть автор и причина, и оно должно быть в timeline как факт, а не как обвинение. Если QA предупреждал письменно, это тоже факт.
- Тест был, но не сработал. Автотест был flaky и его отключили, или он проверял мок вместо реальной интеграции. Фактор про качество тестов.
- Staging отличался от прода. Другой платёжный провайдер, другой фича-флаг, другие данные. Фактор про паритет окружений.
- Мониторинг не поймал. Проблему заметили пользователи, а не алерт. Фактор про наблюдаемость, и он вообще не про QA.
Заметь: в каждом пункте фактор сформулирован так, что его можно починить изменением системы. «Тестировщик будет внимательнее» починить нельзя, это не система, это надежда.
Action items, которые что-то меняют
Половина постмортемов заканчивается пунктами вида «быть аккуратнее», «улучшить коммуникацию», «добавить в чек-лист». Через месяц о них никто не помнит. Хороший action item проходит три проверки: он конкретный, у него есть один владелец, и можно объективно сказать, сделан он или нет.
Плохие и хорошие пары для нашего примера с оплатой:
- «Тщательнее тестировать платежи» против «автотест на оплату через Google Pay в CI, владелец Х, до конца спринта».
- «Не забывать про новые версии Android» против «в Definition of Done для мобильных фич — прогон на последних двух мажорных версиях, закупить устройство с Android 14».
- «Внимательнее относиться к регрессу» против «релиз без полного регресса требует явного решения лида с записью в релизном тикете».
- «Быстрее реагировать» против «алерт на падение конверсии оплаты ниже порога, дежурный получает пуш».
- «Лучше писать требования» против «в шаблоне фичи обязательный раздел про платформенные ограничения и негативные сценарии».
Обрати внимание, что из пяти хороших пунктов про тестирование только два. Остальные про мониторинг, релизный процесс и требования. Так и должно быть: если после разбора все action items на QA, это верный признак, что искали виноватого, а не причины.
Если у вас всё-таки ищут виноватого
Не во всех компаниях есть SRE-книга на полке. Иногда разбор действительно выглядит как «кто пропустил». Что можно сделать, не меняя работу:
- Написать постмортем первым. Кто пишет документ, тот задаёт рамку. Если ты приходишь на встречу с готовым timeline по фактам и списком факторов, обсуждение идёт по твоей структуре, а не по «ну и кто у нас тестировал».
- Предложить формат. Принести шаблон Atlassian или PagerDuty и сказать: «давайте попробуем разобрать по этой схеме». Мало кто откажется от чужого проверенного процесса, особенно если он экономит время.
- Переводить обвинения в факты вслух. «Ты должен был это поймать» превращается в «давай зафиксируем: сценарий Google Pay на Android 14 не был в тест-плане. Почему его там не было?» Спокойно, без защиты. Один-два таких перевода меняют тон встречи.
- Хранить письменные следы. Тест-план, список того, что не проверено, предупреждения о рисках перед релизом. Не для того чтобы потом тыкать, а чтобы разбор шёл по документам, а не по памяти.
- Эскалировать через лида. Если культура обвинения системная, это разговор для 1-1, и его лучше вести в формате «проблема, варианты, что прошу». Как готовить такие разговоры, мы разбирали в статье про 1-1 для QA.
И честный пункт напоследок: если после нескольких попыток любой инцидент по-прежнему заканчивается поиском крайнего, а крайним раз за разом оказывается QA, это информация о компании, а не о тебе. Она тоже пригодится, в том числе при выборе следующего места.
Как не съесть себя
Про команду поговорили, теперь про тебя. Пропущенный баг больно бьёт по самооценке именно тестировщика, потому что находить баги — буквально твоя работа. Несколько опор.
Эдсгер Дейкстра ещё в 1970-м сформулировал: тестирование может показать наличие ошибок, но никогда не может доказать их отсутствие. Это не оправдание, это математика. Ни один тест-план не покрывает бесконечное пространство состояний. Вопрос никогда не в том, пропустишь ли ты баг, а в том, какие баги ты выбираешь ловить в первую очередь и как система страхует остальное.
Отдели два вопроса, которые мозг склеивает в один. «Что я мог сделать иначе» — рабочий вопрос, на него отвечают фактами, и ответ идёт в action items. «Я плохой тестировщик» — не вопрос, а вывод, и он делается по одному инциденту, что статистически бессмысленно. Первым вопросом заниматься полезно, вторым нет.
Практика, которая помогает лично: вести свой лог пропущенных багов. Дата, что за баг, почему прошёл, что бы поймало. Через полгода в этом логе видны паттерны: например, ты систематически недооцениваешь платформенные различия или доверяешь staging. Паттерн — это то, что реально можно исправить. Один инцидент — это шум.
И последнее. Если после инцидента тебя не отпускает неделями, ты боишься ставить sign-off и каждый релиз ждёшь удара, это уже не про один баг. Об этом мы подробно писали в разборе про выгорание в QA, и там же о том, что просить у тимлида.
Чек-лист QA на постмортеме
- Во время инцидента: локализовать, оценить масштаб, найти workaround, проверить hotfix. Не оправдываться в общем канале.
- Зафиксировать факты по горячим следам: что покрывалось, что нет, на каком окружении, с какими данными, что было в требованиях.
- На вопрос «тестировали?» отвечать формулой: что проверялось, что не проверялось, почему.
- Прийти на разбор с готовым timeline по фактам, без интерпретаций.
- Каждый факт со стороны тестирования сформулировать как системный фактор, который можно изменить.
- Ловить контрфактуалы («надо было») и переводить их в «что было видно в тот момент».
- Следить, чтобы action items были конкретными, с владельцем и сроком.
- Если все action items достались QA, сказать об этом вслух: значит, разобрали не всё.
- Не подписываться на «быть внимательнее». Это не действие.
- Записать инцидент в личный лог и через полгода посмотреть на паттерны, а не на отдельный случай.
Баг в проде — это не экзамен, который тестировщик провалил. Это самый дорогой и самый честный тест вашего процесса, и его результаты уже оплачены пользователями. Единственный способ не заплатить за них дважды — разобрать без поиска виноватых и починить систему, а не человека.