Flaky-тест — тот, что проходит и падает на одном и том же коде через раз. Он опаснее отсутствующего: команда привыкает перезапускать «красное», и в какой-то момент пропускает настоящую поломку среди ложных. Один флаки-тест подрывает доверие ко всему набору. Поэтому борьба с нестабильностью — не гигиена, а условие, при котором e2e вообще имеет смысл.
Источники и их лечение
Флаки почти всегда сводится к нескольким причинам, и у каждой есть лечение в этом разделе:
- Тайминги — проверка раньше, чем готов интерфейс. Лечится авто-ожиданием: web-first assertions вместо
sleep. Это причина номер один, и она снимается почти полностью. - Гонки — действие и ожидание не синхронизированы (клик и ожидание ответа порознь). Лечится ожиданием условия (
waitForResponseв связке с действием), а не времени. - Общее состояние — тест зависит от данных, оставленных другим, и падает при изменении порядка или параллельном запуске. Лечится изоляцией: каждый тест создаёт и чистит своё.
- Сеть и внешнее — нестабильные сторонние сервисы. Лечится контролем/моком внешних зависимостей.
Большая часть флаки уходит, если эти четыре закрыты дисциплиной, а не костылями.
Retries — снижают шум, не лечат
Playwright умеет повторять упавший тест (retries). Это полезно в CI — отсеять случайный сбой инфраструктуры, — но это обезболивающее, не лечение.
// playwright.config.ts
export default defineConfig({
retries: process.env.CI ? 2 : 0,
});
Опасность retries — спрятать настоящую нестабильность: тест «зелёный со второго раза» выглядит рабочим, а на деле флачит. Поэтому retries сочетают с наблюдением: если тест регулярно проходит только с повтора — это сигнал чинить причину, а не радоваться зелёному.
Детерминизм
Тест должен давать один результат на одном коде. Враги детерминизма — всё «плавающее»: текущее время и даты, случайные данные, зависимость от часового пояса, от порядка элементов. Их фиксируют: подставляют время, генерируют данные с уникальным, но контролируемым ключом, не полагаются на сортировку по умолчанию. Детерминированный тест либо всегда зелёный, либо всегда красный — и тогда красному можно верить.
Карантин, а не игнор
Найденный флаки нельзя просто отключить и забыть — дыра в покрытии останется незамеченной. Его помечают (карантин/отдельная метка), заводят на починку и чинят причину. Молча закомментированный тест — это потерянная проверка, о которой никто не помнит.
Где это в UCP
Борьба с флаки — это про доверие к набору: закрыть источники (тайминги, гонки, состояние, сеть) дисциплиной, использовать retries как индикатор, а не маскировку, держать тесты детерминированными. Доверие к тестам — то же, что доверие к исполняемому стандарту: красное должно означать реальную проблему. Для продукт-инженера, который полагается на e2e как на последний рубеж, флаки недопустимы — иначе рубеж дырявый. Запускается всё это в CI, где стабильность особенно на виду.