Як розібрати тест, який падає не завжди

testingcidebuggingai

Як діагностувати нестабільний тест у CI: час виконання, спільний стан, випадковість, повторні запуски, логи й мінімальний сценарій відтворення

Що таке нестабільний тест

Нестабільний тест - це тест, який іноді проходить, а іноді падає без очевидної зміни в коді.

Зазвичай причина лежить не в одному місці, а на межі кількох речей:

  • час виконання або гонка між подіями;
  • спільний стан між тестами;
  • випадкові дані або seed;
  • залежність від мережі, часу, локалі чи файлової системи;
  • занадто крихка перевірка, яка дивиться не туди.

Якщо тест падає завжди, це вже не нестабільний тест, а звичайний баг. Якщо падає лише інколи, думайте як про діагностику, а не про косметичне виправлення.

Одна маленька сцена

Тест “створити замовлення” падає вночі на CI. Після повторного запуску він зелений. Команда хоче просто додати автоматичний повтор і піти далі. Але в логах видно, що інколи відповідь приходить на 400 мс пізніше, ніж очікує перевірка.

Це вже підказка: не поспішайте міняти сам тест. Спочатку з’ясуйте, чи проблема в часі виконання, стані, чи випадкових даних.

Як мислити: коротке дерево рішень

Коли тест “зелений після повторного запуску”, поставте собі три питання.

  1. Чи змінюється результат, якщо запускати той самий тест багато разів?
  2. Чи ламається він тільки в CI, але не на локальній машині?
  3. Чи є у падінні натяк на час, порядок, паралельність або випадковість?

Ознаки, які часто ведуть до причини:

СимптомЩо перевіритиЙмовірна причина
Падає лише інодіЗапуск у циклі, повторний запуск, seedнестабільна поведінка, час виконання, випадковість
Падає тільки в CIВерсія раннера, таймзона, паралельністьвідмінність середовища
Залежить від порядку тестівСпільний стан, очищення данихвитік спільного стану
Падає на очікуванні або таймаутіОчікування події, debounce, асинхронний UIчас виконання або гонка
Ламається на випадкових данихseed, генератор, фабрикивипадковість

Найменший надійний сценарій відтворення

Мета не в тому, щоб “повторити весь пайплайн”. Мета в тому, щоб звести проблему до мінімального набору умов.

Чекліст:

  • зафіксуйте назву тесту, гілку, коміт і середовище;
  • запустіть лише цей тест 20-50 разів;
  • вимкніть паралельність, якщо підозрюєте спільний стан;
  • зафіксуйте seed для випадкових даних;
  • збережіть повний лог, а не тільки останній рядок;
  • порівняйте локальний запуск і CI-запуск;
  • перевірте, чи є повторний запуск, який маскує симптом, а не лікує причину.

Коли це не нестабільний тест

Іноді тест здається нестабільним тільки тому, що він ховає справжню помилку.

Це не нестабільний тест, якщо:

  • він падає стабільно на тому самому кроці;
  • на повторному запуску нічого не змінюється;
  • лог чітко вказує на одну й ту саму причину;
  • фікс у тесті лише маскує зламану бізнес-логіку.

У такому випадку проблема не в нестабільності. Проблема в тому, що тест уже підсвітив справжній дефект.

Коротко

Нестабільний тест - це не “дрібний збій”. Це сигнал, що ваша система має приховану залежність від часу, стану або випадковості.

Правильний порядок дій такий: зібрати симптоми, звузити причину, зробити мінімальний сценарій відтворення, і тільки тоді міняти тест або код.

Короткий чеклист

  • Зберіть повний лог першого падіння і повторного запуску.
  • Перевірте, чи змінюється результат у циклі запусків.
  • Вимкніть паралельність, якщо підозрюєте спільний стан.
  • Зафіксуйте seed і порівняйте CI з локальним запуском.
  • Не плутайте повторний запуск з лікуванням причини.

Діагностувати нестабільний CI-тест

Ти допомагаєш розібрати нестабільний тест у CI. Ось контекст: [фреймворк], [назва тесту], [що саме падає], [повний лог], [чи проходить повторний запуск], [чи є паралельність], [чи використовуються випадкові дані], [seed], [timeout], [відмінності між локальною та CI-версією]. Зроби три речі: 1. Назви 3 найімовірніші причини у порядку ймовірності. 2. Скажи, які 3 додаткові дані треба зібрати першими. 3. Запропонуй найменший надійний сценарій відтворення без зайвих змін у коді.