> For the complete documentation index, see [llms.txt](https://vladislaveremeev.gitbook.io/qa_bible/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://vladislaveremeev.gitbook.io/qa_bible/avtomatizaciya-testirovaniya/tekhniki-i-patterny/chto-takoe-flaky-tests.md).

# Flaky tests

Flaky-тест — нестабильный, ненадёжный тест, который без изменений в коде то проходит, то падает. Это не просто неудобство: нестабильные тесты подрывают доверие ко всему тестовому суиту и замедляют доставку. Когда команда привыкает перезапускать упавший тест вместо расследования, это сигнал системной проблемы.

## Определение

**Flaky-тест (Flaky Test)** — тест, который при одинаковом состоянии системы и одинаковом коде иногда проходит, иногда падает. Само слово «flaky» (хлопчатый, рассыпающийся) передаёт непредсказуемость результата.

## Причины

### Асинхронность и тайминги

Самая распространённая причина: тест ожидает элемент или результат асинхронной операции с фиксированным `sleep()` вместо умного ожидания готовности. Решение — использовать встроенные механизмы ожидания фреймворка.

### Неправильная инициализация и очистка данных

Тест зависит от состояния, которое оставил предыдущий тест. При параллельном запуске это проявляется особенно часто. Каждый тест должен самостоятельно создавать нужные данные и очищать состояние после себя.

### Неустойчивые локаторы

XPATH-локаторы, зависящие от позиции элемента в DOM, ломаются при изменении разметки. Предпочтительны `data-testid`, `aria-label`, `role`-атрибуты.

### Параллельное выполнение и shared state

Тесты, изменяющие одни и те же данные в БД или одного тестового пользователя, конфликтуют при параллельном запуске.

### Внешние зависимости

Нестабильное сетевое соединение, медленный внешний API, недоступная база данных. Идеальная тестовая среда — «герметичная»: без внешних зависимостей (моки, Testcontainers, WireMock).

### Аппаратные и системные проблемы

Нехватка памяти, медленный диск, неправильно настроенные ресурсы фреймворка.

## Автоматическое ожидание как профилактика

Современные фреймворки устраняют целый класс timing-проблем через умное ожидание:

**Playwright auto-waiting** — перед каждым действием Playwright автоматически проверяет actionability: элемент должен быть visible, enabled, stable (не анимируется), attached to DOM. `sleep()` для ожидания элементов не нужен.

**Cypress retry-ability** — assertion-команды автоматически ретраят до тех пор, пока условие не выполнится или не истечёт timeout. `cy.get('.button').should('be.visible')` не упадёт при анимации появления.

```typescript
// Playwright: не нужен sleep(), фреймворк ждёт сам
await page.click('.submit-btn');  // ждёт пока кнопка станет visible + enabled + stable

// Явное ожидание для нестандартных случаев
await page.waitForResponse(resp => resp.url().includes('/api/data'));
await expect(page.locator('.result')).toBeVisible({ timeout: 10000 });
```

## Диагностика

1. Документировать нестабильный тест: когда падает, как часто, в каком окружении
2. Проверить логи, скриншоты, видео прогона (Playwright автоматически записывает при падении)
3. Запустить тест 10–20 раз изолированно — воспроизвести нестабильность
4. В 90% случаев причина ясна из артефактов прогона

## Управление flaky-тестами в CI

### Паттерн quarantine

Нестабильный тест помечается как карантинный: он продолжает запускаться, но не блокирует пайплайн. Команда получает уведомление и разбирает проблему по расписанию, не в режиме блокировки PR.

### BuildPulse

SaaS-сервис для автоматического отслеживания flaky-тестов. Интегрируется с GitHub Actions/CircleCI/Jenkins через upload junit-xml артефактов. Определяет нестабильные тесты по истории 50+ запусков, автоматически создаёт GitHub Issues.

```yaml
# GitHub Actions: upload результатов в BuildPulse
- name: Upload test results to BuildPulse
  uses: buildpulse/buildpulse-action@main
  if: always()
  with:
    account: ${{ secrets.BUILDPULSE_ACCOUNT_ID }}
    repository: ${{ secrets.BUILDPULSE_REPOSITORY_ID }}
    path: test-results/*.xml
    key: ${{ secrets.BUILDPULSE_ACCESS_KEY_ID }}
    secret: ${{ secrets.BUILDPULSE_SECRET_ACCESS_KEY }}
```

### Currents.dev

Платформа оркестрации для Playwright и Cypress. Dashboard с историей тестов, flakiness score, аналитика по веткам и воркерам. Поддерживает quarantine mode из коробки.

## Статистика

По данным тестировщиков, основные причины нестабильности по «сложности разбора»:

1. Асинхронные операции (async wait)
2. Многопоточность и shared state
3. Неправильный порядок запуска тестов
4. Аппаратные проблемы (сеть, память)

Как говорил вице-президент Unity3D Алан Берд: «Нестабильные тесты хуже, чем вообще без тестов» — они создают ложный сигнал и убивают доверие к автоматизации.

## Источники

* [Нестабильные тесты. Почему они существуют и что с ними делать](https://testengineer.ru/nestabilnye-testy-pochemu-oni-sushchestvuyut-i-chto-s-nimi-delat/)
* [Playwright: Auto-waiting](https://playwright.dev/docs/actionability)
* [BuildPulse — flaky test detection](https://buildpulse.io)
* [Currents.dev — Playwright analytics](https://currents.dev)

### Дополнительные материалы

* [Flaky-тесты: Откуда ноги растут. Опыт Uber](https://habr.com/ru/post/565806/) — кейс масштабной диагностики
* [Blog: Flaky Testing](https://www.developsense.com/blog/2021/02/flaky-testing/) — системный взгляд на проблему
