Ми стикалися з проєктами, де повний тестовий прогін займав 40–90 хвилин. Один із клієнтів — продуктова команда з 25 розробників — робила понад 100 комітів на день. Кожен коміт блокувався на годину, поки CI прогоняв 1200 тестів. Розробники йшли пити каву, а потім перемикалися на інші завдання. Тести запускали дедалі рідше, баги спливали в проді. Запускати всі тести на кожен коміт — дорого й повільно. Test Impact Analysis (TIA) — метод вибору мінімального набору тестів за змінами в коді. AI-підхід розширює класичний TIA за рахунок історичного аналізу: які тести історично знаходили баги в цих компонентах. Наш досвід показує, що такий підхід скорочує час CI у 3–5 разів без втрати якості.
Як AI-пріоритизація скорочує час CI?
Класичний TIA працює через code coverage mapping: запускає всі тести з інструментацією, записує який тест покриває який файл, при наступній зміні вибирає лише тести, що покривають змінені файли. Точний, але вимагає повного coverage-прогону як baseline.
AI-підхід додає історичний сигнал:
- Тести, які історично падали при змінах у даному компоненті.
- Тести з високою семантичною близькістю до зміненого коду (через code embeddings).
- Тести, що покривають функції, які використовують змінені API.
class AITestSelector: def __init__(self, coverage_db, history_db, code_encoder): self.coverage_db = coverage_db # test → file coverage map self.history_db = history_db # history of test failures by change self.encoder = code_encoder # CodeBERT/UniXcoder embeddings def select_tests(self, changed_files: list[str], changed_diffs: list[str]) -> list[str]: # Coverage-based candidates coverage_tests = self.coverage_db.get_tests_for_files(changed_files) # History-based candidates history_tests = self.history_db.get_historically_related(changed_files) # Semantic similarity candidates diff_embedding = self.encoder.encode(changed_diffs) semantic_tests = self.find_semantic_matches(diff_embedding) # Merge and rank by failure probability all_candidates = coverage_tests | history_tests | semantic_tests return self.rank_by_failure_probability(all_candidates, changed_files) Чому класичний TIA недостатній?
Він не враховує, що тест може покривати файл, але не перевіряти критичну логіку. Наприклад, зміна в utils.py може зачепити всі модулі, але coverage покаже лише тести, що безпосередньо тестують utils. AI-підхід через ембеддинги знаходить тести, логічно пов'язані зі змінами. Крім того, класичний TIA не ранжує тести за ймовірністю падіння — ми запускаємо їх у порядку спадання ризику, щоб fast feedback приходив швидше.
Як ранжувати тести за ймовірністю падіння?
Після формування набору кандидатів застосовуємо ранжувальну модель LightGBM, навчену на історії CI. Ознаки для ранжування:
- Час останнього падіння тесту при зміні даного компонента.
- Cosine similarity між diff-ембеддингом та ембеддингом тесту.
- Глибина покриття: тест покриває змінений рядок безпосередньо або через 2–3 виклики.
- Ознака «критичний тест»: тест пов'язаний з платіжним функціоналом, автентифікацією тощо.
- Історичний flakiness score тесту.
Тести ранжуються за спаданням failure_probability, CI запускає їх у такому порядку — fast feedback приходить швидше, оскільки тести з високим ризиком стартують першими.
Адаптивний вибір стратегії
Система автоматично перемикається між режимами залежно від контексту змін:
| Тип зміни | Стратегія |
|---|---|
| Правка одного файлу у відомому компоненті | TIA-відбір, ~10–30% тестів |
| Зміна shared utility / common lib | Розширений відбір, ~50–70% тестів |
| Зміна конфігурації / env variables | Повний прогін |
| Зміна у 10+ файлах (великий рефакторинг) | Повний прогін |
| Коміт у гілку main/master | Повний прогін |
Кейс із практики
Один із проєктів (1200 тестів, середній час прогону 55 хвилин) відчував постійні затримки в CI при кількості комітів понад 100 на день. Після впровадження TIA AI середній час CI для feature-комітів скоротився до 12 хвилин — це ~78% прискорення. Відсоток запущених тестів на коміт склав 22% у середньому, при цьому за півроку не було зафіксовано жодної пропущеної регресії. Ключовим фактором стало налаштування історичного аналізу: модель навчилася на 10 000+ попередніх прогонах і навчилася відрізняти зміни, що зачіпають критичну функціональність. Отримайте консультацію інженера — ми проаналізуємо ваш проєкт і спрогнозуємо прискорення CI.
Кроки впровадження AI-пріоритизації
- Інструментування збирача coverage — налаштування pytest-cov, JaCoCo або аналогів.
- Збір історичних даних CI — вивантаження пайплайнів, результатів прогонів, змін.
- Навчання ранжувальної моделі (LightGBM) на вашому проєкті.
- Інтеграція в пайплайн — GitHub Actions, GitLab CI, Jenkins, Buildkite.
- Налаштування дашборду метрик — середній час CI, відсоток запущених тестів, кількість пропущених регресій.
- Документація та передача — супровід протягом місяця після впровадження.
Що входить у роботу
При впровадженні ми надаємо:
- Інструментування збирача coverage (pytest-cov, JaCoCo, etc.) та налаштування baseline.
- Збір історичних даних CI (пайплайни, результати прогонів, зміни).
- Навчання ранжувальної моделі (LightGBM) на вашому проєкті.
- Інтеграцію в пайплайн (GitHub Actions, GitLab CI, Jenkins, Buildkite).
- Дашборд метрик: середній час CI, відсоток запущених тестів, кількість пропущених регресій.
- Документацію з налаштування та супроводу.
Інтеграція
Підтримка GitHub Actions, GitLab CI, Jenkins, Buildkite. Плагіни для pytest, JUnit, Go test, Jest. Зберігання coverage map та історичних даних у PostgreSQL або ClickHouse.
| Тип проєкту | Термін впровадження |
|---|---|
| Одна мова, один CI | 2–3 тижні |
| Кілька мов / мікросервіси | 4–6 тижнів |
| Ентерпрайз (10+ команд) | 6–10 тижнів |
Замовте впровадження AI-пріоритизації тестів — наші інженери оцінять ваш проєкт і запропонують рішення під ключ з гарантією результату.







