Обновить

FlakyDetector 2.0: Как я превратил сырое исследование в продакшен-инструмент с AST, ML и красивым дашбордом…

Уровень сложностиПростой
Время на прочтение4 мин
Охват и читатели10K
Всего голосов 3: ↑0 и ↓3-3
Комментарии3

Комментарии 3

Интересный подход, особенно комбинация AST + ML. Вопрос: как инструмент обрабатывает случаи, когда flakiness не в самом коде теста, а в shared state между тестами?

У меня был кейс: fixture создавала слот с фиксированными timestamp'ами. Код теста абсолютно чистый, никаких антипаттернов. Но если предыдущий тест не успел удалить свой слот - новый fixture падал с SLOT_OVERLAP. В изоляции тест всегда зелёный, в CI при определённом порядке падал.

37 признаков из AST это не обнаружат - там нет ничего подозрительного. Планируете добавлять анализ взаимодействий между тестами?

Привет! Ого, вот это кейс — прямо хрестоматийный пример той самой «дьявольской» сложности, с которой мы все сталкиваемся.

Во-первых, огромное спасибо за этот пример — в нём вскрывается настоящее ахиллесово пятно многих статических анализаторов.

Почему мой AST-анализ бессилен в твоём случае

Модель выдаст уверенные 99% с пометкой Чисто, потому что формально код безупречен нет sleep, нет мутаций глобальных переменных, нет сетевых вызовов. Пока не встанет в очередь за другим тестом. Исследования это подтверждают: около 59% нестабильных тестов в Python появляются именно из-за такого порядка выполнения.

Но вот что важно: сама по себе ошибка возникает не в коде, а в данных, которые создаёт фикстура а это уже территория динамического анализа, который требует выполнения, а не просто чтения кода.

· Динамический анализ через логи (как в FlakyXbert). Он сравнивает состояния в момент падения и прохода и может сказать: В момент прогона в слоте было занято, сейчас нет. · Анализ зависимостей данных (как в Peeler). Ищет цепочки: тест А что-то изменил → тест Б это прочитал. · Детерминированные стратегии выполнения. Простой, но мощный метод — инструменты вроде JS-TOD для JS специально прогоняют тесты в случайном порядке (10, 20, 50 раз). Если хоть раз упадёт — значит, есть скрытая связка.

Как это повлияет на мои планы по FlakyDetector

Я сейчас очень плотно изучаю два направления:

· Анализ связок тестов. Хочется не просто сказать У вас проблема в порядке тестов, а указать пальцем: Тест B падает, потому что тест A не почистил за собой конкретный слот. · LLM-классификация из коробки. Современные модели показывают очень достойные результаты в предсказании нестабильности по одному лишь коду, не требуя ручного выделения 37 признаков.

Поскольку я ещё только пилю следующий релиз, вот тебе мои «костыли»:

· pytest-randomly или pytest-xdist --random-order — прогони свои тесты в разнобой, и он тебе со 100% вероятностью упадёт. · Идеальным решением для твоей боли будет transactional fixture. Суть проста: тест запускается → фикстура создаёт слот → тест завершается → фикстура гарантированно всё откатывает. В этом случае все следы пребывания теста в БО уничтожаются, и соседям нечем пачкаться.

А твой кейс по ссылкам на ptvsd, mergify и замоканный datetime я с удовольствием изучу — как раз для полировки следующей версии.

Ещё раз спасибо за такой развёрнутый фидбек! Если будут ещё идеи или примеры — подкидывай. Пиши в комментариях, интересно обсудить.

Привет! Именно так и вышло в итоге - transactional fixture. В Playwright это function-scoped fixture: создаёт данные для конкретного теста, убивает их в teardown. Если предыдущий тест по какой-то причине не дочистил, то следующий всё равно начинает с чистого листа.

Интересный момент: решение оказалось архитектурным, не тестовым. Код самого теста не трогали, а только перевели fixture из shared scope в function scope. После этого SLOT_OVERLAP исчез полностью.

И вот здесь как раз проявляется "flakiness as a signal": тест падал не потому, что был плохо написан, а потому что подсвечивал реальный дефект в дизайне окружения. Если просто пометить его flaky и заглушить, то теряется единственный индикатор проблемы.

Про анализ зависимостей между тестами - очень жду. Особенно если инструмент сможет отвечать не только "есть order dependency", а конкретно: "тест B падает, потому что тест A не очистил состояние X". Рандомный порядок выполнения хорошо вскрывает связки, но почти не помогает локализовать источник загрязнения.

Кстати, твой пример с AST vs shared state отлично показывает границу между "code smell detection" и настоящим behavioural analysis. Это уже ближе к tracing/runtime observability, чем к классическому статическому анализу.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации