Що таке нестабільний тест
Нестабільний тест - це тест, який іноді проходить, а іноді падає без очевидної зміни в коді.
Зазвичай причина лежить не в одному місці, а на межі кількох речей:
- час виконання або гонка між подіями;
- спільний стан між тестами;
- випадкові дані або seed;
- залежність від мережі, часу, локалі чи файлової системи;
- занадто крихка перевірка, яка дивиться не туди.
Якщо тест падає завжди, це вже не нестабільний тест, а звичайний баг. Якщо падає лише інколи, думайте як про діагностику, а не про косметичне виправлення.
Одна маленька сцена
Тест “створити замовлення” падає вночі на CI. Після повторного запуску він зелений. Команда хоче просто додати автоматичний повтор і піти далі. Але в логах видно, що інколи відповідь приходить на 400 мс пізніше, ніж очікує перевірка.
Це вже підказка: не поспішайте міняти сам тест. Спочатку з’ясуйте, чи проблема в часі виконання, стані, чи випадкових даних.
Як мислити: коротке дерево рішень
Коли тест “зелений після повторного запуску”, поставте собі три питання.
- Чи змінюється результат, якщо запускати той самий тест багато разів?
- Чи ламається він тільки в CI, але не на локальній машині?
- Чи є у падінні натяк на час, порядок, паралельність або випадковість?
Ознаки, які часто ведуть до причини:
| Симптом | Що перевірити | Ймовірна причина |
|---|---|---|
| Падає лише іноді | Запуск у циклі, повторний запуск, seed | нестабільна поведінка, час виконання, випадковість |
| Падає тільки в CI | Версія раннера, таймзона, паралельність | відмінність середовища |
| Залежить від порядку тестів | Спільний стан, очищення даних | витік спільного стану |
| Падає на очікуванні або таймауті | Очікування події, debounce, асинхронний UI | час виконання або гонка |
| Ламається на випадкових даних | seed, генератор, фабрики | випадковість |
Найменший надійний сценарій відтворення
Мета не в тому, щоб “повторити весь пайплайн”. Мета в тому, щоб звести проблему до мінімального набору умов.
Чекліст:
- зафіксуйте назву тесту, гілку, коміт і середовище;
- запустіть лише цей тест 20-50 разів;
- вимкніть паралельність, якщо підозрюєте спільний стан;
- зафіксуйте seed для випадкових даних;
- збережіть повний лог, а не тільки останній рядок;
- порівняйте локальний запуск і CI-запуск;
- перевірте, чи є повторний запуск, який маскує симптом, а не лікує причину.
Коли це не нестабільний тест
Іноді тест здається нестабільним тільки тому, що він ховає справжню помилку.
Це не нестабільний тест, якщо:
- він падає стабільно на тому самому кроці;
- на повторному запуску нічого не змінюється;
- лог чітко вказує на одну й ту саму причину;
- фікс у тесті лише маскує зламану бізнес-логіку.
У такому випадку проблема не в нестабільності. Проблема в тому, що тест уже підсвітив справжній дефект.
Коротко
Нестабільний тест - це не “дрібний збій”. Це сигнал, що ваша система має приховану залежність від часу, стану або випадковості.
Правильний порядок дій такий: зібрати симптоми, звузити причину, зробити мінімальний сценарій відтворення, і тільки тоді міняти тест або код.
Короткий чеклист
- Зберіть повний лог першого падіння і повторного запуску.
- Перевірте, чи змінюється результат у циклі запусків.
- Вимкніть паралельність, якщо підозрюєте спільний стан.
- Зафіксуйте seed і порівняйте CI з локальним запуском.
- Не плутайте повторний запуск з лікуванням причини.
Діагностувати нестабільний CI-тест
Ти допомагаєш розібрати нестабільний тест у CI. Ось контекст: [фреймворк], [назва тесту], [що саме падає], [повний лог], [чи проходить повторний запуск], [чи є паралельність], [чи використовуються випадкові дані], [seed], [timeout], [відмінності між локальною та CI-версією]. Зроби три речі: 1. Назви 3 найімовірніші причини у порядку ймовірності. 2. Скажи, які 3 додаткові дані треба зібрати першими. 3. Запропонуй найменший надійний сценарій відтворення без зайвих змін у коді.