AI-система Self-Healing Tests: автоматическое исправление сломанных тестов
Тесты ломаются по трём причинам: изменился UI (локатор не находит элемент), изменилось API (ответ пришёл с другой структурой), изменилась бизнес-логика (условие теста устарело). В большинстве проектов команда тратит 20–40% времени на поддержку тестовой базы — не на написание новых тестов, а именно на исправление упавших. Self-Healing Tests — это слой ML, который детектирует причину падения и автоматически применяет фикс без участия человека.
Архитектура self-healing слоя
Система работает в два режима: проактивный (превентивное обновление локаторов при деплое новой версии фронтенда) и реактивный (исправление после падения в CI/CD).
Ядро системы — три модуля:
-
Failure Classifier — NLP-модель (дообученный DistilBERT), которая классифицирует тип падения по stack trace и сообщению об ошибке:
ElementNotFound,AssertionError,TimeoutError,NetworkError -
Selector Healer — для
ElementNotFoundприменяет стратегию поиска альтернативного локатора через DOM-анализ; обучен на парах (старый локатор → новый локатор) из истории коммитов -
Assertion Fixer — для
AssertionErrorсравнивает фактическое и ожидаемое значение, определяет паттерн изменения (числовой drift, изменение формата строки, структурное изменение JSON) и предлагает обновлённый assert
class SelfHealingRunner:
def __init__(self, model_path: str):
self.classifier = FailureClassifier.load(model_path)
self.healer = SelectorHealer()
self.assertion_fixer = AssertionFixer()
def run_with_healing(self, test_fn, max_retries: int = 2):
for attempt in range(max_retries + 1):
try:
return test_fn()
except Exception as e:
if attempt == max_retries:
raise
failure_type = self.classifier.predict(str(e))
if failure_type == "ElementNotFound":
self.healer.apply_fix(e)
elif failure_type == "AssertionError":
self.assertion_fixer.suggest(e)
Selector Healing: детали реализации
Для Selenium/Playwright тестов основной источник нестабильности — хрупкие CSS-селекторы вида #app > div:nth-child(3) > button. После изменения вёрстки такой локатор перестаёт работать.
Алгоритм восстановления:
- Парсим DOM текущей страницы в момент падения
- Извлекаем признаки потерянного элемента из исходного кода теста: тип тега, text content, aria-label, соседние элементы
- Строим эмбеддинг элемента (признаки → вектор через обученный энкодер)
- Ищем ближайший элемент в текущем DOM по cosine similarity
- Генерируем новый локатор: предпочтение
data-testid, затем aria-label, затем XPath с text()
Точность восстановления на тестовом датасете (5000 пар сломанный/исправленный локатор): 87% корректных фиксов.
Интеграция с CI/CD
# .github/workflows/tests.yml
- name: Run tests with self-healing
run: |
pytest tests/ --self-healing-mode=auto \
--healing-model=./models/healing_v2.pkl \
--max-healing-retries=2 \
--healing-report=artifacts/healing_report.json
После каждого healing-события система создаёт Pull Request с предложенным фиксом — инженер делает code review, а не отлаживает тест с нуля. За первые 3 месяца эксплуатации в проектах с 500+ e2e тестами auto-healing закрывает 60–70% падений без участия QA.
Поддерживаемые фреймворки и технологии
| Фреймворк | Тип тестов | Статус поддержки |
|---|---|---|
| Playwright | E2E, компонентные | Полная |
| Selenium WebDriver | E2E | Полная |
| Cypress | E2E | Частичная (через proxy) |
| pytest | API, unit | Только Assertion Fixing |
| JUnit/TestNG | Unit, integration | Только Assertion Fixing |
Этапы внедрения
Аудит тестовой базы: анализ частоты падений по типам, выявление наиболее нестабильных тестов. Сбор датасета из истории CI — пары (упавший тест, коммит-исправление). Обучение Failure Classifier и Selector Healer на конкретном проекте. Интеграция в CI/CD pipeline с режимом report-only на первые 2 недели. Переключение в режим auto-fix с порогом confidence > 0.85.
| Объём тестовой базы | Срок внедрения |
|---|---|
| До 200 тестов | 2–3 недели |
| 200–1000 тестов | 3–5 недель |
| Более 1000 тестов | 5–8 недель |







