Регрессионное тестирование — это процесс повторной проверки приложения после внесения изменений для обнаружения дефектов в ранее работавшем функционале. Каждое изменение кода — новый функционал, исправление бага или рефакторинг — может непреднамеренно сломать существующие возможности приложения. Регрессионные тесты автоматизируют проверку того, что старая функциональность осталась работоспособной. Согласно исследованию 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 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также