AI-система анализа результатов тестирования и классификации ошибок
Когда в CI падает 80 тестов, инженер открывает логи и начинает вручную определять: это один баг или восемь разных? Один сетевой таймаут, который каскадом повалил все зависимые тесты, выглядит как 40 независимых падений. AI-система анализа тестов решает эту задачу: кластеризует падения по первопричине, приоритизирует по критичности и направляет уведомление нужному владельцу, а не всей команде.
Архитектура системы
Пайплайн обработки результатов состоит из четырёх этапов: парсинг → классификация → кластеризация → роутинг.
Парсинг — поддержка JUnit XML, Allure, pytest JSON, Cypress Mochawesome. Нормализация в единую схему: {test_id, status, duration, error_message, stack_trace, timestamp}.
Классификация — мультилейбл классификатор на базе fine-tuned CodeBERT, обученный на размеченных stack trace'ах. Выходные классы:
INFRASTRUCTURE - таймауты, connection refused, OOM
REGRESSION - тест работал, сломался после коммита
FLAKY - нестабильный (проходит с retry)
TEST_BUG - ошибка в самом тесте, не в коде
NEW_BUG - реальный дефект в продукте
ENVIRONMENT - проблема с тестовым окружением
Кластеризация — эмбеддинги stack trace через CodeBERT → HDBSCAN кластеризация. Тесты из одного кластера с высокой вероятностью имеют одну первопричину.
from sentence_transformers import SentenceTransformer
import hdbscan
class ErrorClusterer:
def __init__(self):
self.encoder = SentenceTransformer('microsoft/codebert-base')
self.clusterer = hdbscan.HDBSCAN(
min_cluster_size=3,
metric='cosine',
cluster_selection_method='eom'
)
def cluster_failures(self, failures: list[dict]) -> list[int]:
texts = [f['error_message'] + '\n' + f['stack_trace'][:500]
for f in failures]
embeddings = self.encoder.encode(texts, batch_size=32)
return self.clusterer.fit_predict(embeddings)
Определение flaky тестов
Flaky тесты — отдельная категория. Система анализирует историю 30 последних запусков каждого теста и вычисляет flakiness score:
flakiness_score = std(pass_rate_per_day) * frequency_of_status_changes
Тест с flakiness_score > 0.3 маркируется как flaky и автоматически помещается в карантин — он продолжает запускаться для сбора статистики, но не блокирует CI.
Роутинг уведомлений
Система определяет владельца упавшего теста через git blame на файл теста и на файлы из stack trace. Уведомление идёт не всей команде, а:
- REGRESSION/NEW_BUG → автор последнего коммита в затронутых файлах + тимлид
- FLAKY → владелец теста по git blame
- INFRASTRUCTURE → DevOps-канал
- TEST_BUG → QA, ответственный за данный тест-файл
Метрики качества классификации
Обучение проводится на размеченном датасете из истории проекта. Типичные метрики после 2–3 недель накопления данных:
| Класс | Precision | Recall |
|---|---|---|
| INFRASTRUCTURE | 0.94 | 0.91 |
| REGRESSION | 0.88 | 0.85 |
| FLAKY | 0.91 | 0.87 |
| NEW_BUG | 0.83 | 0.79 |
| ENVIRONMENT | 0.89 | 0.86 |
Интеграция и дашборд
Система предоставляет REST API для получения отчётов и webhook для Slack/Teams. Дашборд показывает тренды по типам ошибок, топ нестабильных тестов, среднее время до обнаружения первопричины.
| Размер тестовой базы | Срок внедрения |
|---|---|
| До 500 тестов | 2–3 недели |
| 500–2000 тестов | 3–5 недель |
| Более 2000 тестов | 5–7 недель |







