Тестировщик замечает проявление проблемы: сообщение об ошибке, неверное число, пропавшую кнопку. Но то, что видно на экране, — почти никогда не сам дефект, а лишь его симптом. Между «что я вижу» и «что на самом деле сломано» лежит цепочка причин, и чем ниже по ней вы спуститесь, тем полезнее будет ваш баг-репорт — и тем быстрее дефект починят. Систематический спуск по этой цепочке называют анализом первопричин (root cause analysis).
Спуск по цепочке: каждый ответ на «почему?» — не догадка, а проверенная гипотеза. По верхней строке чинить нечего, чинится только нижняя — поэтому репорт про неё и ценен.
Симптом → причины → первопричина
Худший случай — проблема вообще не замечена. Чуть лучше — репорт описывает только внешнее проявление («иногда не открывается отчёт»). Приемлемо — описаны причины, лежащие на поверхности. Идеал — добраться до двух нижних уровней цепочки:
- Первопричина — конкретный изъян, порождающий всё дерево следствий.
- Условия, способствовавшие её появлению — почему изъян вообще возник (это уже чаще вопрос к процессу, чем к коду).
Вся идея укладывается в три вопроса: что произошло, почему это произошло и как снизить вероятность повторения. Устранение первопричины ценнее заплатки на симптом: ненайденная первопричина продолжит порождать новые дефекты — в других местах и в других формах.
Пример: спуск по цепочке
Живой пример из практики. Консольная утилита обрабатывает каталоги; команда с абсолютным путём /var/www возвращает ошибку «SOURCE_DIR name [var/www] is not a valid directory» — хотя каталог существует и доступен.
- Проявление. В сообщении об ошибке имя каталога отличается от заданного: пропал начальный
/. Несколько контрольных запусков подтверждают: начальный слеш исчезает во всех параметрах. - Причина N. Проверяем относительные пути — работают. Проверяем под Windows — работает. Значит, дело в обработке введённых имён. Гипотеза: обрезаются начальные и конечные слеши.
- Причина N-1. Запуск с путями вида
\\\\c:\\\\подтверждает: приложение убирает все слеши в начале и конце имени, в любом количестве. - Первопричина. Гипотеза: где-то в коде есть первичный фильтр путей, и он работает неверно. Заглянув в код разбора параметров (или попросив разработчика), находим метод, который «канонизирует» имя и срезает краевые разделители. Для Linux это фатально: любой абсолютный путь начинается со слеша.
Теперь сравните два репорта. «Приложение не обнаруживает доступные каталоги» — описание симптома: некорректное по сути, и всё исследование ложится на программиста. «Удаление краевых / и \ из параметров запуска ломает абсолютные пути в Linux» — описание первопричины: разработчику осталось исправить конкретный метод.
Алгоритм поиска
Универсальная последовательность:
- Определить проявление проблемы. Что именно происходит и почему это плохо?
- Собрать информацию. Происходит ли то же самое в других ситуациях? Всегда ли одинаково? От чего зависит появление и исчезновение проблемы? Это тот же приём, что и варьирование условий при исследовательском тестировании.
- Выдвинуть гипотезу о причине. Что может её вызывать? Какие действия или условия приводят к проявлению?
- Проверить гипотезу дополнительными экспериментами. Не подтвердилась — выдвинуть другую.
- Убедиться, что найдена первопричина, а не очередное звено цепи. Если звено промежуточное — повторить алгоритм уже для него. Если первопричина — сформулировать, что и где чинить.
Заглядывать в код необязательно (хотя полезно, если умеете читать его): часто достаточно грамотных экспериментов снаружи плюс вопроса разработчику «где в коде это может обрабатываться?».
Пять почему и рыбья кость
Спуск по цепочке легко превращается в импровизацию: на третьем шаге теряется нить, на первом правдоподобном ответе рука уже тянется заводить репорт. Чтобы этого не случалось, пользуются двумя техниками с общепринятыми именами — их упоминают в разборах инцидентов, и понимать, о чём речь, стоит.
Пять почему — это тот самый вопрос «а почему происходит это?», заданный подряд, пока ответы не упрутся в изъян, который можно починить. Отчёт не открывается → запрос отваливается по таймауту → выборка идёт без индекса → индекс не создался при обновлении базы → обновление не проверяли на копии боевых данных. Пять — не норма, а напоминание не остановиться на первом ответе: цепочка кончается там, где следующий «почему» уже не про продукт, а про то, как команда работает.
Диаграмма Исикавы, она же «рыбья кость», нужна, когда причина не одна и гипотезы расходятся веером. Вдоль горизонтальной оси пишут проявление («оплата не проходит у части покупателей»), а от неё наклонными косточками отводят группы причин: данные, окружение, настройки, код, внешний сервис, действия человека. В каждую группу выписывают гипотезы и потом проверяют их по алгоритму выше. Ценность в том, что пустая косточка видна сразу — это область, куда никто ещё не заглядывал.
Где это применяется
Каждый «плавающий» баг — это непройденный до конца анализ первопричины: воспроизводимость «иногда» означает ровно то, что закономерность не найдена. Каждый возвращённый с «не воспроизводится» репорт — чаще всего описание симптома вместо причины. И наоборот: тестировщик, который приносит не «что-то сломалось», а «ломается вот здесь, вот почему и вот при каких условиях», экономит команде часы и быстро зарабатывает репутацию сильного специалиста. Сам алгоритм — определить, собрать, предположить, проверить — универсален: он же работает при отладке, в инцидентах на проде и далеко за пределами ИТ.
Где спотыкаются чаще всего:
- Заводят репорт по первому проявлению, не сделав ни одной дополнительной проверки. Пять минут экспериментов часто превращают «иногда не работает» в чёткую закономерность.
- Останавливаются на первой причине и принимают её за первопричину. Спросите себя: «а почему происходит это?» — пока вопрос имеет ответ, вы ещё не на дне цепочки.
- Подгоняют факты под гипотезу. Гипотеза, которую вы не пытались опровергнуть, — не проверенная гипотеза. Ищите эксперимент, который может её сломать.
Коротко
- Видно на экране симптом, а не дефект: чем ниже по цепочке причин вы спустились, тем полезнее репорт и тем быстрее починка.
- Алгоритм один: определить проявление, собрать данные (где ещё воспроизводится, всегда ли одинаково, от чего зависит), выдвинуть гипотезу, проверить её, убедиться, что это дно, а не очередное звено.
- Гипотезу проверяют попыткой её сломать: та, которую не пытались опровергнуть, ещё не проверена.
- Пять почему — напоминание не останавливаться на первом ответе; цепочка кончается там, где следующий «почему» уже не про продукт, а про то, как работает команда.
- Диаграмма Исикавы раскладывает гипотезы по группам — данные, окружение, настройки, код, внешний сервис, действия человека; пустая косточка показывает область, куда никто не смотрел.
- «Иногда не работает» и возврат «не воспроизводится» почти всегда означают недоведённый анализ, а не плавающий баг.
Что почитать дальше
- Качество баг-репорта — как оформить найденное, чтобы дефект взяли в работу с первого раза.
- Что такое баг — цепочка «ошибка человека → дефект → сбой» и вес находки.
- Исследовательское тестирование — варьирование условий, из которого рождаются гипотезы о причине.
- Жизненный цикл бага и трекеры (Jira) — куда уходит репорт и почему возвращается со статусом «не воспроизводится».