Amiga
Оглавление курса · урок 10 из 13

Модуль 3 · Баги и регресс · урок 10 из 13

Нестабильные тесты: поиск причин

Нестабильный (flaky) тест хуже, чем отсутствие теста: он учит команду игнорировать красный CI. Агент может как помочь, так и навредить. Помогает — тем, что неутомимо гоняет тест в цикле и сравнивает прогоны. Вредит — тем, что «чинит» флак паузой на три секунды, и проблема уходит из отчёта, но не из продукта.

У OpenAI нет официального руководства по нестабильным тестам, поэтому всё ниже — методика курса, собранная из практики работы с Playwright и агентами.

Шаг 1. Подтвердить, что тест нестабилен

Прежде чем искать причину, убедитесь, что она есть. Один красный прогон в CI — ещё не флак: возможно, тест честно ловит баг, который проявляется не всегда.

bash
# один тест, двадцать раз подряд, в один поток, без ретраев
npx playwright test tests/e2e/feedback-form.spec.ts -g "принимает телефон" \
  --repeat-each=20 --workers=1 --retries=0

# то же самое параллельно — проявляет конфликты данных и ресурсов
npx playwright test tests/e2e/feedback-form.spec.ts -g "принимает телефон" \
  --repeat-each=20 --workers=4 --retries=0

Сравнение двух прогонов — уже диагностика. Падает только параллельно — ищите общие данные или общий ресурс. Падает и в один поток — скорее гонка внутри страницы или зависимость от окружения. Не падает локально, но падает в CI — разница окружений: скорость машины, размер окна, сеть, версия браузера.

Это отличная работа для агента: попросите его прогнать оба варианта и свести результаты в таблицу — сколько падений, на каком шаге, с какой ошибкой.

Шаг 2. Категории причин

Дайте агенту список категорий, чтобы он проверял гипотезы системно, а не перебирал правки наугад:

Категория Типичный признак
Гонка с интерфейсом Клик до того, как обработчик навешен; проверка до завершения запроса
Общие данные Падает только параллельно; два теста правят одну запись
Зависимость от порядка Падает при запуске одного файла, проходит в полном наборе (или наоборот)
Окружение Падает только в CI; медленный стенд, другой размер окна, нет шрифтов
Сторонние скрипты Баннер куки, виджет чата или счётчик аналитики перекрывает элемент
Анимации и переходы Элемент найден, но ещё движется; клик мимо
Время и даты Падает около полуночи, в конце месяца, в другом часовом поясе
Случайность Тест или приложение используют случайные значения без фиксации

Шаг 3. Гипотеза → эксперимент → вывод

Главное, что вы требуете от агента, — не правка, а эксперимент, который подтверждает или опровергает гипотезу.

text
Тест "принимает телефон" в tests/e2e/feedback-form.spec.ts нестабилен:
результаты прогонов ниже. Не меняй тест и код продукта, пока не найдёшь
причину.
1. Выдвини до трёх гипотез по категориям из AGENTS.md.
2. Для каждой предложи эксперимент, который её проверит (другой набор
   воркеров, замедление сети, другой размер окна, трейс на каждом
   прогоне), выполни его и запиши результат.
3. Только для подтверждённой гипотезы предложи исправление и объясни,
   почему оно устраняет причину, а не симптом.
Запрещено как исправление: waitForTimeout, увеличение timeout и retries,
force: true, удаление шагов или утверждений.

Трейсы помогают сравнить удачный и неудачный прогоны. Включите их на каждый прогон флагом --trace on, затем попросите агента найти первое расхождение между ними: какой запрос не успел завершиться, какой элемент появился позже.

Чинить тест или продукт

Флак не всегда вина теста. Двойной клик по «Отправить», который иногда создаёт две заявки, — баг продукта, который тест честно нашёл. Поэтому правило в AGENTS.md сформулируйте так: агент по умолчанию исправляет тест, но если причина в продукте, он останавливается и описывает баг, а не обходит его в тесте.

markdown · AGENTS.md
### Нестабильные тесты

- Сначала подтвердить нестабильность прогоном с --repeat-each, потом искать причину.
- Исправлять тест, а не код продукта. Если причина в продукте — остановиться и описать баг.
- Запрещённые исправления: waitForTimeout, рост timeout/retries, force: true,
  удаление утверждений.
- Не удалось найти причину за отведённое время — карантин с задачей в трекере.

Карантин вместо удаления

Если причину быстро найти не удалось, тест не удаляют и не отключают молча. Его помечают тегом и исключают из блокирующего прогона, а в трекере заводят задачу.

typescript · tests/e2e/feedback-form.spec.ts
test('принимает телефон вместо email', { tag: '@quarantine' }, async ({ page }) => {
  // KAITEN-XXXX: нестабилен при параллельном запуске, причина не найдена
  // ...
});

Блокирующий прогон в CI запускается с --grep-invert @quarantine, а отдельная неблокирующая задача гоняет карантин и собирает статистику. Карантин — временная мера: попросите агента раз в неделю выдавать список тестов на карантине с датой постановки.

Для сравнения: в статье OpenAI о harness engineering команда при очень высокой пропускной способности агентов чаще перезапускала флаки, чем позволяла им блокировать работу. Авторы сами оговариваются, что в среде с низкой пропускной способностью такой подход был бы безответственным (Harness engineering). Для агентства с регресс-набором на каждый MR разумнее карантин с задачей.

Упакуйте процедуру в навык

Шаги этого урока повторяются для каждого флака — хороший кандидат в навык .agents/skills/triage-flaky/SKILL.md: подтверждение циклом, категории, эксперименты, запреты, формат отчёта. Тогда вся команда разбирает флаки одинаково, а вызов сводится к $triage-flaky и имени теста.

Попробуйте сами

10–15 мин на рабочем месте
  1. Выберите тест, который хоть раз падал в CI без явной причины, и прогоните его с --repeat-each=20 в один и в четыре потока.
  2. Дайте агенту промпт «гипотеза → эксперимент → вывод» и посмотрите, сколько гипотез он проверил до первой правки.
  3. Добавьте в AGENTS.md раздел о нестабильных тестах и тег @quarantine в конфигурацию CI.

Коротко

  • У OpenAI нет официальной практики по флакам — это методика курса.
  • Сначала подтвердите нестабильность циклом прогонов в один и несколько потоков.
  • Категории причин делают поиск системным: гонки, данные, порядок, окружение, сторонние скрипты, время.
  • От агента требуйте эксперимент на каждую гипотезу; паузы и ретраи как исправление запрещены.
  • Не нашли причину — карантин с тегом и задачей, а не удаление.
Отметка хранится только в вашем браузере
Хотите связаться с владельцем
компании напрямую?
Дмитрий Тарасов
Дмитрий Тарасов
СЕО

НАПИСАТЬ

Написать в MAX