Флаки-тесты: перестаньте нажимать «перезапустить»
У каждой команды, у которой больше пары сотен UI-тестов, рано или поздно появляется кнопка «перезапустить упавшие». Сначала её жмут изредка, потом — на каждом прогоне, а через полгода никто уже не помнит, какой тест падал по делу. Ретрай лечит симптом: прогон зеленеет, а доверие к набору медленно уходит в ноль.
Что на самом деле стоит за флаки
По опыту, причины почти всегда укладываются в четыре группы:
- Ожидания. Тест кликает раньше, чем элемент стал интерактивным. Фиксированные
sleepтолько сдвигают проблему на медленные устройства. - Общее состояние. Тесты делят аккаунт, корзину или кэш и мешают друг другу при параллельном запуске.
- Внешние зависимости. Стенд, сторонний API, push-сервис — всё, что вы не контролируете.
- Порядок. Тест проходит только после другого теста, который случайно готовит ему данные.
Как разбирать
Первое — карантин, а не удаление. Нестабильный тест уходит в отдельный прогон, чтобы не блокировать релиз, но продолжает собирать статистику. Второе — прогнать его 50 раз подряд изолированно и 50 раз в составе набора. Если изолированно он стабилен, ищите общее состояние или порядок; если падает и там — смотрите на ожидания и зависимости.
Хорошее правило: у каждого теста в карантине есть владелец и срок. Тест, который месяц живёт в карантине без владельца, честнее удалить.
Что помогает системно
Явные ожидания состояния вместо таймаутов, отдельные тестовые данные на каждый поток, моки для всего, что не является предметом проверки, и метрика «процент перезапусков» на дашборде команды. Последняя особенно отрезвляет: когда цифра видна всем, кнопку «перезапустить» начинают нажимать заметно реже.