Как бороться с flaky тестами и уменьшить их количество
Что проверяют
Есть ли у вас система, а не набор заплаток: как вы находите нестабильные тесты, что делаете с ними сегодня и как убираете причину. Следом часто спрашивают, как вы относитесь к автоматическим перезапускам.
Как отвечать
Начните с причин:
- ожидания:
sleepна фиксированное время или проверка до того, как элемент готов. Лечится ожиданием условия:WebDriverWaitв Selenium, автоожидание локаторов иexpect(locator).toBeVisible()в Playwright; - общие данные и порядок: тесты делят одного пользователя или запись и при параллельном запуске мешают друг другу. Каждому тесту свои данные, созданные через API, а не через интерфейс;
- окружение: нестабильный стенд, сторонние сервисы, лимиты. Внешние зависимости заменяют заглушками (WireMock,
page.routeв Playwright), базу поднимают через Testcontainers; - время и случайность: часовые пояса, граница суток, анимации, случайные данные без фиксированного seed.
Дальше процесс. Нестабильность измеряют: отчёт с историей запусков, например Allure, показывает тесты, которые меняют статус без изменений кода. Такой тест уходит в карантин: отдельная метка, прогон без блокировки пайплайна, задача с владельцем и сроком. Причину разбирают по трассам, видео и логам, в Playwright для этого есть trace viewer.
Перезапуски допустимы как временная мера и с учётом: retries в конфиге Playwright, плагин pytest-rerunfailures, rerunFailingTestsCount в Maven Surefire. Тест, прошедший со второй попытки, должен попадать в отчёт как нестабильный, а не как зелёный.
Приведите свой пример: сколько было нестабильных, какую причину нашли, во что обошлось исправление.
Где спотыкаются
Включают ретраи на всё и считают задачу решённой. Иногда нестабильность это настоящая гонка в продукте, и перезапуск прячет баг, который потом всплывёт у пользователей.
Чинят через sleep(5000). Тест становится медленнее и всё равно падает на медленном стенде.
Отключают тест без задачи и срока. Через полгода в карантине лежит заметная часть регресса, и покрытие молча исчезает.