Вы обновили compileSdkVersion до 35, а minSdkVersion оставили на 26. Через неделю в продакшене на Android 10 падает NoSuchMethodError. Silent failure из-за отсутствия NotificationChannel на Android 7 — пользователи жалуются, что нет уведомлений. Такие баги возникают, когда код использует API новее минимальной версии ОС. Мы сталкивались с этим десятки раз и научились выявлять такие проблемы до релиза. Наша услуга — кроссверсионное тестирование мобильного приложения — гарантирует, что все функции работают корректно на каждой поддерживаемой версии ОС, без артефактов UI и вылетов. Закажите аудит совместимости и получите матрицу версий за 2 дня.
Тестирование совместимости: полный цикл проверки на разных версиях ОС
Как выбрать матрицу версий для тестирования совместимости?
Тестировать каждую версию ОС нерационально. Мы используем принцип приоритетов, основанный на аналитике и требованиях проекта.
| Приоритет |
Версии iOS |
Версии Android |
| Обязательно |
Текущая − 1 (например, iOS 17, 18) |
Android 12, 13, 14 (API 31–34) |
| Важно |
minDeploymentTarget (например, iOS 15) |
minSdkVersion (например, API 26–28) |
| По аналитике |
Версии с долей > 5% у вашей ЦА |
То же |
Аналитика Firebase или Mixpanel по полю os_version даёт реальную картину. Если 8% пользователей на iOS 15 — тестируем эту версию. Если 0.3% на iOS 14 — пропускаем. Такой подход сокращает объём работ без потери качества. Кроме того, полезно включить в матрицу версии, на которых произошли крупные изменения API — например, Android 12 (API 31) с изменённым exported в intent-фильтрах.
Почему deprecated API — главная проблема совместимости?
Разрыв между minSdkVersion и compileSdkVersion — 8 лет эволюции API. Пропустить одну deprecated-замену — и приложение падает на старых версиях. Мы системно ловим такие проблемы с помощью статического анализа и точечного тестирования.
Android: три частые ловушки
Уведомления (API 26+). На Android 8+ все уведомления требуют NotificationChannel. Без него notify() тихо игнорируется. Код проверки:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(CHANNEL_ID, "General", NotificationManager.IMPORTANCE_DEFAULT)
notificationManager.createNotificationChannel(channel)
}
Разрешения (API 33+). READ_EXTERNAL_STORAGE заменён на гранулированные READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_AUDIO. Запрос старого разрешения на Android 13 не даёт доступа к медиа.
Foreground Service (API 34+). Android 14 требует указывать тип foreground service (dataSync, mediaPlayback и др.) — без него SecurityException.
| API |
Версия Android |
Типичная проблема |
| NotificationChannel |
API 26+ |
Без channel notify() игнорируется |
| Granular media permissions |
API 33+ |
READ_EXTERNAL_STORAGE не работает |
| Foreground service type |
API 34+ |
SecurityException без типа |
Инструмент для проверки: lint с правилом NewApi. Он автоматически находит вызовы API, доступные выше minSdkVersion без @RequiresApi или проверки Build.VERSION.SDK_INT. Опыт показывает, что lint находит 80% проблем до запуска.
iOS: @available и #available
if #available(iOS 16.0, *) {
NavigationStack { ... }
} else {
NavigationView { ... }
}
Компилятор предупреждает об использовании нового API без проверки — это ловится статически. Но в больших кодовых базах такие предупреждения теряются. Самые частые жертвы: ContentUnavailableView (iOS 17), NavigationStack (iOS 16), Charts (iOS 16) — без fallback приложение падает с dyld: Symbol not found. Подробнее — в документации @available.
Инструмент для iOS: Xcode Simulator
Скачиваем дополнительные runtime: Xcode → Settings → Platforms → + → iOS 15.x Simulator Runtime. После загрузки создаём симулятор и проверяем на нём.
Как автоматизировать поиск deprecated API?
Статический анализ с lint и Xcode Build & Analyze находит несовместимости в 10 раз быстрее ручного поиска. Мы запускаем его в CI на каждый PR. Для более глубокой проверки используем Firebase Test Lab — виртуальные устройства с разными API-уровнями. Это быстро, дёшево и покрывает большинство несовместимостей. Например, на одном из проектов мы нашли 12 deprecated API до релиза, что сэкономило клиенту значительную часть бюджета на исправления в продакшене.
Как мы тестируем без реальных устройств?
Эмуляторы покрывают 90% случаев. Реальные устройства нужны только для специфических прошивок (Samsung, Xiaomi) или аппаратных особенностей (камера, NFC). Мы комбинируем:
- В CI: прогон lint + сборка с
-Werror для iOS.
- Smoke-тесты на эмуляторах с минимальной, средней и текущей версиями ОС.
- Firebase Test Lab для интеграционных сценариев.
Это даёт быструю обратную связь без затрат на физические девайсы. Вы экономите на дорогостоящих исправлениях после релиза и оптимизируете бюджет на тестирование.
Процесс работы
- Аудит текущей
minSdkVersion / minDeploymentTarget и аналитика распределения версий.
- Составление матрицы поддерживаемых версий с приоритетами.
- Статический анализ на deprecated API (lint/Xcode) с полным списком найденных проблем.
- Тестирование на приоритетных версиях (smoke + точечное).
- Отчёт с матрицей совместимости и рекомендациями по исправлению.
- Консультация по спорным моментам и помощь с исправлением кода.
Свяжитесь с нами, чтобы обсудить ваше приложение и получить индивидуальный план тестирования.
Что входит в работу
- Документация: матрица поддерживаемых версий с приоритетами, список найденных несовместимостей, рекомендации по исправлению.
- Доступы к отчётам в Firebase Test Lab и CI-логам.
- Консультации по исправлению кода и адаптации под старые версии ОС.
- Поддержка в течение 5 рабочих дней после сдачи отчёта.
Опыт нашей команды — более 7 лет в мобильной разработке, 40+ протестированных приложений с аудиторией от 50 000 пользователей. Оценим ваш проект за 2 дня. Свяжитесь с нами, чтобы получить консультацию. Закажите тестирование и получите полный отчёт с матрицей совместимости.
Тестирование мобильных приложений: XCTest, Espresso, Detox и Appium
Flaky-тест, падающий на CI раз в пять запусков без воспроизводимой причины, хуже его отсутствия. Команда перестаёт доверять инфраструктуре и отключает тесты — регрессии проскакивают в продакшн. Мы это видим каждый день и знаем, как выстроить надёжную систему тестирования, которая не требует постоянного внимания. Получите консультацию — оценим ваш проект и предложим архитектуру тестов под ваш стек.
Почему flaky-тесты опасны?
Одна нестабильная проверка может завалить пайплайн, заблокировав релиз. Разработчики тратят 15-20% рабочего времени на перезапуск и анализ ложнонегативных сбоев. Автоматизация без стабильности — не экономия, а потеря эффективности. Мы решаем эту проблему на уровне архитектуры: Gray Box-фреймворки (Detox, Patrol) синхронизируются с состоянием приложения, а native инструменты (XCUITest, Espresso) получают правильные IdlingResource и accessibilityIdentifier. Результат: стабильность >99% на CI.
Unit-тесты: что тестировать, а что нет
На iOS XCTest — основа. Бизнес-логика в ViewModel, Interactor, UseCase — тестируется без проблем, если она не тянет UIKit. Типичная ошибка: логика в UIViewController напрямую — тогда unit-тест требует создания view-иерархии, что медленно и нестабильно. Выход — выносить логику в сервисы с @testable import.
Для асинхронного кода в Swift: XCTestExpectation для старого стиля, await + XCTest async для современного. С Combine — XCTestExpectation + sink, но удобнее использовать библиотеки типа CombineExpectations. На Android JUnit 4/5 + Mockito для unit-тестов, Coroutines Test для suspend-функций. runTest {} из kotlinx-coroutines-test — стандарт для ViewModel с StateFlow. Покрытие кода unit-тестами на уровне 80% сокращает время регрессии на 60% (данные наших проектов).
UI-тесты: стабильность важнее покрытия
XCUITest (iOS) и Espresso (Android) — нативные UI-тесты. Работают быстро, интегрированы с IDE, но тестируют одну платформу. Главная проблема XCUITest — хрупкость селекторов. app.buttons["Войти"] падает при смене локализации или рефакторинге accessibility label. Правильный подход: accessibilityIdentifier для тестируемых элементов, никогда не текстовые метки. Идентификаторы из shared enum — чтобы они не расходились между приложением и тестами. Опыт показывает: такая практика снижает flakiness на 90%.
Espresso на Android стабильнее из-за IdlingResource механизма — тест автоматически ждёт завершения background операций. Но кастомные async операции (OkHttp, кастомные Executors) нужно регистрировать в IdlingRegistry вручную, иначе тест не синхронизируется с сетевыми запросами. Мы гарантируем правильную настройку IdlingResource на этапе аудита.
Detox и Patrol: end-to-end для React Native и Flutter
Detox — E2E фреймворк для React Native, разработанный Wix. Работает на реальных устройствах и симуляторах через Gray Box подход: знает о состоянии JS thread и синхронизируется с ним. Это решает главный flakiness-источник — тест не нажимает кнопку, пока приложение занято. Настройка Detox нетривиальна. Требует специальный debug-билд с DetoxInstrumentsServer, конфигурации в package.json и отдельного Appium-сервера не нужно. Типичная проблема: тест стабилен на симуляторе, падает на реальном устройстве из-за анимаций. Решение — animations: disabled в Detox конфигурации для E2E билда.
Patrol — аналог для Flutter. Расширяет встроенный integration_test пакет и добавляет возможность взаимодействовать с нативными системными диалогами (permission prompts, notifications) — то, что flutter_driver и базовый integration_test не умеют. Для CI используется через patrol test --target integration_test/app_test.dart.
Appium: кроссплатформа с ценой
Appium — когда нужно покрыть iOS и Android одними тестами. Использует WebDriver протокол, поверх XCUITest и UiAutomator2 драйверов. Скорость ниже нативных фреймворков, но для команд без ресурсов на две тестовые кодовые базы — компромисс. Appium 2.x с плагинной архитектурой заметно удобнее первой версии. appium-doctor диагностирует окружение — полезен при настройке CI.
CI и параллелизация
Для параллельного запуска XCUITest используем Xcode Cloud или xcodebuild test-without-building с несколькими симуляторами через parallel-testing-enabled. Время прогона 200 UI-тестов с параллелизацией на 4 симулятора — с 40 минут до 12. На Android аналогично используем Firebase Test Lab с шардингом.
| Фреймворк |
Платформа |
Gray Box |
Скорость |
Системные диалоги |
| XCUITest |
iOS |
Нет |
Высокая |
Да (через addUIInterruptionMonitor) |
| Espresso |
Android |
Да (IdlingResource) |
Высокая |
Ограничено |
| Detox |
React Native |
Да |
Средняя |
Ограничено |
| Patrol |
Flutter |
Частично |
Средняя |
Да |
| Appium |
iOS + Android |
Нет |
Низкая |
Да |
Типичные ошибки при настройке (и как их избежать)
| Ошибка |
Последствие |
Решение |
| Использование текстовых меток в селекторах |
Тесты падают при локализации |
accessibilityIdentifier из enum |
| Отсутствие IdlingResource для кастомных Executor |
Espresso не ждёт ответа сервера |
Регистрация в IdlingRegistry |
| Включённые анимации на реальном устройстве в Detox |
Flaky тесты из-за таймингов |
animations: disabled в E2E билде |
| Параллелизация без изоляции состояния |
Гонки данных между тестами |
Запуск каждого теста в свежем симуляторе |
Как мы это делаем: процесс работы
-
Аудит текущего кода и CI — оцениваем flakiness, покрытие, узкие места.
-
Проектирование тестовой архитектуры — выбираем фреймворк, селекторы, моки.
-
Настройка инфраструктуры — CI пайплайн, parallel execution, отчёты (Allure, Xcode Report).
-
Написание тестов — unit, UI, E2E, performance (XCTMetrics, Macrobenchmark).
-
Интеграция и стабилизация — прогон 200+ тестов, отлов flaky-кейсов.
-
Передача документации — архитектура, запуск, troubleshooting.
Что входит в работу (deliverables)
- Архитектурная документация тестового покрытия
- Настроенный CI-пайплайн с параллелизацией и отчётами
- Код тестов (unit, UI, E2E) с styleguide
- Обучение команды (2 часа воркшопа)
- Доступ к тестовым билдам и CI-логам
- Поддержка в течение месяца после сдачи (фикс flakiness, обновление под новые версии)
Сроки ориентировочно
Настройка инфраструктуры с нуля (CI, unit + UI тесты, отчёты) — 2-3 недели. Написание покрытия для существующего приложения — от 2 недель до месяца в зависимости от объёма. Оценим ваш проект за 2 дня — свяжитесь с нами. 5+ лет опыта в автоматизации, 50+ успешных проектов, сертифицированные специалисты по iOS/Android. Гарантируем стабильность тестов >98% на CI после внедрения.