Короткий ответ
Нужно сначала воспроизвести нестабильность (прогнать тест многократно, в т.ч. в изоляции и в случайном порядке с остальными), а затем искать источник недетерминизма: общее состояние между тестами, зависимость от реального времени/сети, гонки в асинхронном или многопоточном коде, неявный порядок выполнения.
Как это работает подробнее
Flaky-тест обычно связан со скрытой зависимостью от внешнего или разделяемого состояния: случайных данных без фиксированного seed, реального времени, порядка выполнения тестов (если один тест оставляет данные для следующего), таймаутов в CI с ограниченными ресурсами, гонок между потоками или корутинами, которые не всегда успевают пересечься по времени.
Пример кода
testing_example_312.txt
# Диагностика шаг за шагом:
pytest tests/test_orders.py::test_flaky_case --count=50 # pytest-repeat: воспроизвести
pytest -p randomly --randomly-seed=12345 # проверить зависимость от порядка
pytest tests/test_orders.py -k test_flaky_case -vv --tb=long # подробный вывод при паденииЧто использовать на практике
- Практика. Полезные инструменты диагностики: запуск теста в цикле (pytest --count=50 с pytest-repeat), запуск тестов в случайном порядке (pytest-randomly) для выявления скрытых зависимостей по порядку, логирование состояния перед падением. Временная карантинная маркировка (@pytest.mark.flaky или skip с тикетом) допустима, но не должна становиться постоянным решением.
Подводные камни
- Риск. Просто перезапускать упавший тест до зелёного результата в CI без расследования причины — это маскирует реальную проблему, которая может быть и в production-коде (например, настоящая гонка данных). Списывать нестабильность на «медленный CI» без проверки гипотезы через воспроизведение локально.