Регресійне тестування — це процес повторної перевірки застосунку після внесення змін для виявлення дефектів у раніше працюючому функціоналі. Кожна зміна коду — новий функціонал, виправлення багу або рефакторинг — може ненавмисно зламати існуючі можливості застосунку. Регресійні тести автоматизують перевірку того, що стара функціональність залишилася працездатною. Згідно з дослідженням IBM, 2023, регресійне тестування охоплює від 30 до 70% усіх виконуваних тестів у комерційних продуктових командах, що підкреслює його роль як основного бар'єра проти виробничих інцидентів.
Головне
Регресійне тестування — це вид тестування, спрямований на підтвердження того, що зміни в коді не порушили існуючу функціональність. Термін «регресія» означає повернення до гіршого стану — коли функція, що працювала в попередній версії, перестає працювати в новій. Регресійні тести виконуються багаторазово на кожному циклі розробки, що відрізняє їх від тестів нової функціональності, які пишуться одноразово.
Необхідність регресійного тестування випливає з ефекту каскадних змін: виправлення багу в одному модулі може вирішити проблему, але зламати суміжну функціональність, яка від нього залежала. Наприклад, зміна SQL-запиту в репозиторії користувачів може прискорити авторизацію, але зламати експорт даних, який використовував цей самий запит. Регресійний тест на експорт даних виявить це порушення до релізу.
Згідно зі звітом CISQ 2023, вартість виправлення регресійного дефекту, виявленого в продакшені, в 15 разів вища, ніж на етапі автоматизованого регресійного прогону. Компанії, що інвестують в автоматизоване регресійне тестування, скорочують частку регресійних дефектів у релізах з 25% до 5% протягом року після впровадження, за даними Capgemini World Quality Report.
Існує кілька підходів до регресійного тестування, які різняться за обсягом і критеріями відбору тестів. Вибір підходу залежить від розміру проєкту, частоти змін і доступного часу в CI-пайплайні. Нижче наведено основні види регресійного тестування з їхніми характеристиками.
Повний регресійний прогін виконує всі автоматизовані тести проєкту без винятку. Цей підхід дає максимальну впевненість, але потребує значних обчислювальних ресурсів і часу. Повний прогін виконується перед великими релізами — раз на 2–4 тижні. Для застосунку з 5000 тестів повний прогін триває від 2 до 6 годин залежно від інфраструктури.
Вибірковий підхід запускає лише тести, пов'язані зі зміненими модулями. Для визначення пов'язаності використовується аналіз залежностей на рівні коду: якщо змінено клас UserRepository, запускаються тести, що залежать від UserRepository прямо або транзитивно. Інструменти Jacoco, Android Test Coverage та Xcode Code Coverage надають карти покриття для точного відбору. Вибірковий прогін виконується на кожен pull request і триває 5–15 хвилин.
Risk-based регресія ранжує тести за критичністю функціональності та ймовірністю поломки. Критичні функції — оплата, авторизація, синхронізація — тестуються при кожній зміні коду. Допоміжні функції — екран «Про застосунок», анімації — тестуються лише перед релізом. Ранжування переглядається раз на квартал на основі даних про виробничі інциденти.
Часто поняття регресійного тестування та ретесту плутають, хоча це різні процеси. Ретест — це повторний запуск конкретного тесту, який раніше впав, після виправлення дефекту. Мета ретесту — переконатися, що виправлення працює: баг більше не відтворюється. Ретест виконується одноразово, одразу після фіксу та підтвердження фіксу розробником.
Регресійне тестування — це запуск тестів на існуючу функціональність, яка НЕ змінювалася. Мета — переконатися, що виправлення одного дефекту не створило новий дефект в іншому місці. Регресійні тести запускаються багаторазово при кожному циклі розробки, незалежно від того, які конкретні баги фіксилися. Головна відмінність: ретест перевіряє сам фікс, регресія перевіряє наслідки фіксу.
У CI/CD пайплайні обидва процеси виконуються послідовно. Після мержу pull request запускається ретест конкретного багу, а потім повний або вибірковий регресійний прогін. За даними SmartBear (2022), розділення цих процесів скорочує час діагностики невдалих CI-прогонів на 30%, оскільки команда одразу бачить, яка частина дефектів пов'язана з регресією, а яка — з непрацюючими фіксами.
Автоматизація регресійного тестування — критичний фактор успіху для сучасних мобільних проєктів. Ручне регресійне тестування не масштабується: при наборі з 200 тестів на один прогін потрібно 2–3 робочих дні QA-інженера, що робить неможливими щоденні прогони. Автоматизовані регресійні тести виконуються за 10–60 хвилин без участі людини, що дозволяє запускати їх при кожному коміті або pull request.
Для підтримання регресійного набору в актуальному стані використовується тестова аналітика: інструменти на кшталт Allure, ReportPortal та Xray відстежують відсотки проходження, тривалість та стабільність кожного тесту. Тести, стабільність яких падає нижче 90% (часто ламаються через зміни в вимогах), маркуються як legacy та призначаються на перегляд власнику.
Розглянемо налаштування автоматизованого регресійного тесту на Android з використанням бібліотеки JUnit 5 та Espresso. Приклад демонструє вибіркову регресію — тест перевіряє, що після рефакторингу репозиторію користувачів не зламався екран профілю. Для iOS використовується XCTest з аналогічною логікою — повторюваний тест на ключовий сценарій.
Тест використовує MockWebServer для емуляції сервера та перевіряє повний шлях: завантаження даних про користувача, відображення на екрані профілю та обробка помилки при недоступному сервері. Такі тести включаються в регресійний набір та виконуються при кожній зміні в module-profile.
@RunWith(AndroidJUnit4::class)
class ProfileRegressionTest {
@get:Rule
val composeRule = createComposeRule()
@Test
fun profileScreen_rendersCorrectly() {
val user = User(id = 1, name = "Alice", email = "alice@test.com")
composeRule.setContent {
ProfileScreen(user)
}
composeRule.onNodeWithText("Alice").assertIsDisplayed()
composeRule.onNodeWithText("alice@test.com").assertIsDisplayed()
}
@Test
fun profileScreen_handlesNetworkError() {
setNetworkError()
composeRule.onNodeWithText("Помилка завантаження").assertIsDisplayed()
}
}
Для iOS регресійний тест використовує XCTestExpectation для асинхронної перевірки оновлення UI після отримання даних від API. Тест емулює мережеву відповідь і перевіряє, що UI-елементи оновилися коректно.
class ProfileRegressionTests: XCTestCase {
func testProfileScreen_rendersCorrectly() {
let viewModel = ProfileViewModel(userId: 1)
let view = ProfileView(viewModel: viewModel)
viewModel.loadProfile()
let expectation = expectation(description: "profile loaded")
viewModel.onProfileLoaded = {
XCTAssertEqual(viewModel.userName, "Alice")
XCTAssertEqual(viewModel.userEmail, "alice@test.com")
expectation.fulfill()
}
waitForExpectations(timeout: 3.0)
}
}
Побудова ефективного регресійного набору — ітеративний процес, заснований на даних про дефекти та зміни коду. Первинна стратегія — включити в регресійний набір всі існуючі тести та запускати повний прогін перед кожним релізом. У міру зростання тестової бази (понад 2000 тестів) повний прогін стає надто довгим, і потрібен вибірковий підхід.
Друга фаза — впровадження інструментів аналізу залежностей: Jacoco для Android, Xcode Test Plan для iOS. Ці інструменти будують карту «тест — клас — метод» та дозволяють визначити, які тести зачеплено конкретною зміною. Вибірковий прогін на основі аналізу покриття скорочує час виконання на 60–80% при збереженні 95% ефективності виявлення регресій, за даними Spotify Engineering (2022).
Третя фаза — постійний моніторинг та оптимізація. Тести, які не падали 6 місяців, переміщуються в низькопріоритетний набір. Тести, що падають частіше 1 разу на місяць, — кандидати на перегляд: або вони ловлять реальні проблеми (потребують фіксу), або надто крихкі (потребують стабілізації). Щоквартальна ревізія регресійного набору — стандартна практика для підтримання його ефективності та швидкості виконання.
Часті запитання
Вибірковий регресійний прогін — на кожен pull request. Повний регресійний прогін — перед кожним релізом та щотижня (nightly build). Ключове правило: чим частіше запуск, тим швидше виявляються регресії та тим нижча вартість їх виправлення. Для критичних проєктів можлива full-регресія при кожному мержі.
Всі модульні тести (базовий регрес), інтеграційні тести на ключові компоненти та UI-тести на критичні користувацькі сценарії. Не включайте тести на експериментальний функціонал, тести з flakiness вище 10% та тести, що потребують ручного оточення.
Видаляйте тести на віддалений функціонал, оновлюйте тести при зміні вимог, раз на квартал проводьте аудит набору. CI-аналітика — Allure, ReportPortal — допомагає виявити тести, що втратили актуальність: якщо тест 3 місяці не змінювався і не падав, він кандидат на видалення з щоденного прогону.
Використовуйте паралельний запуск тестів на кількох пристроях, впровадьте вибіркову регресію на основі аналізу покриття зміненого коду, вимкніть візуальні снипшоти для нерелевантних екранів. Цільовий час вибіркового прогону — 5–10 хвилин, повного — не більше 2 годин.
Ні, регресійне тестування включає також ручні перевірки: дослідницьке тестування після релізу, UX-регресію та перевірку accessibility після зміни інтерфейсу. Автоматизація покриває 70–80% регресійних перевірок; решта 20–30% — ручні, що фокусуються на сценаріях, які неможливо або надто дорого автоматизувати.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також