Основы тестирования Android
Открытая экосистема Android создаёт как возможности, так и вызовы для тестировщиков. Свобода, позволяющая тысячам производителей кастомизировать Android, создаёт проблему фрагментации, определяющую QA на Android.
Жизненный цикл Activity
Жизненный цикл Activity — важнейший концепт для тестировщиков Android. Activities (экраны) проходят через специфические переходы состояний, часто вызывающие баги.
Состояния Activity
Created → Started → Resumed → Paused → Stopped → Destroyed
| Callback | Когда вызывается | Фокус тестирования |
|---|---|---|
onCreate | Activity создан впервые | Инициализация, загрузка данных |
onStart | Activity становится видимым | Настройка UI |
onResume | Activity получает фокус | Обновление данных |
onPause | Другой activity выходит на передний план | Сохранение временных данных |
onStop | Activity больше не видим | Освобождение тяжёлых ресурсов |
onDestroy | Activity уничтожается | Очистка |
Изменения конфигурации
При изменении конфигурации устройства Android уничтожает и пересоздаёт Activity:
- Поворот экрана (портрет ↔ ландшафт)
- Смена языка
- Изменение размера шрифта
- Переключение тёмной темы
- Многооконный режим
Это источник №1 Android-специфичных багов. Тестируйте каждый экран после:
- Поворота устройства во время операции
- Изменения размера шрифта в настройках
- Переключения тёмной темы
- Входа и выхода из режима разделённого экрана
Инструменты тестирования Android
ADB (Android Debug Bridge)
ADB — инструмент командной строки для связи с Android-устройствами:
# Управление устройствами
adb devices # Список устройств
adb install app.apk # Установить APK
adb install -r app.apk # Переустановить (сохранить данные)
adb uninstall com.example.app # Удалить
# Скриншоты и запись
adb shell screencap /sdcard/screen.png
adb pull /sdcard/screen.png ./
adb shell screenrecord /sdcard/video.mp4
# Управление приложениями
adb shell am start -n com.example/.MainActivity
adb shell am force-stop com.example
adb shell pm clear com.example
# Отладка
adb logcat # Просмотр логов
adb logcat *:E # Только ошибки
Espresso
Espresso — фреймворк UI-тестирования Google, работающий внутри процесса:
@Test
fun testLoginFlow() {
onView(withId(R.id.emailInput))
.perform(typeText("user@example.com"), closeSoftKeyboard())
onView(withId(R.id.passwordInput))
.perform(typeText("password123"), closeSoftKeyboard())
onView(withId(R.id.signInButton))
.perform(click())
onView(withText("Welcome"))
.check(matches(isDisplayed()))
}
UI Automator
UI Automator работает вне процесса приложения, обеспечивая системное взаимодействие:
@Test
fun testNotificationInteraction() {
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.openNotification()
val notification = device.findObject(UiSelector().text("New message"))
notification.click()
onView(withId(R.id.messageView))
.check(matches(isDisplayed()))
}
Тестирование специфики производителей
Производители Android добавляют кастомное поведение, которое может ломать приложения:
Samsung (One UI)
- Агрессивная оптимизация батареи убивает фоновые приложения
- Кастомная обработка уведомлений
- Взаимодействия с Edge-панелью
- Secure Folder создаёт отдельный экземпляр приложения
Xiaomi (MIUI)
- Разрешение «Автозапуск» необходимо для фоновых процессов
- Кастомный менеджер разрешений
- Агрессивное управление RAM
- Кастомное поведение шторки уведомлений
Huawei (EMUI/HarmonyOS)
- Нет Google Play Services (используется HMS)
- Кастомная система push-уведомлений
- Агрессивное управление энергией
- Список защищённых приложений
Android-специфичные сценарии тестирования
Кнопка «Назад» и навигация
Кнопка «Назад» Android должна тестироваться на каждом экране:
Чек-лист:
□ Назад с каждого экрана ведёт на ожидаемый предыдущий экран
□ Назад с первого экрана выходит из приложения или показывает подтверждение
□ Назад во время операции обрабатывается корректно
□ Назад после deep link открывает правильный родительский экран
□ Жестовая навигация работает идентично кнопке
Тестирование многооконного режима и складных устройств
Сценарии:
□ Приложение в режиме разделённого экрана рендерится корректно
□ Приложение обрабатывает изменение размера окна плавно
□ Данные сохраняются при входе/выходе из разделённого экрана
□ Приложение на складном: макет в сложенном vs разложенном виде
□ Drag and drop между приложениями в разделённом экране
Тестирование Intent-ов и deep links
# Тестирование deep link
adb shell am start -a android.intent.action.VIEW -d "myapp://product/12345" com.example.app
# Тестирование intent-а «Поделиться»
adb shell am start -a android.intent.action.SEND --es android.intent.extra.TEXT "Общий контент" -t text/plain com.example.app
Упражнение: Охота за фрагментацией
Сценарий: Ваше приложение работает идеально на Google Pixel 8, но пользователи сообщают о проблемах на Samsung и Xiaomi.
- Push-уведомления не появляются на устройствах Xiaomi
- Фоновое воспроизведение музыки останавливается через 10 минут на Samsung
- Приложение падает при повороте во время заполнения многошагового формы
Решение
Проблема уведомлений Xiaomi: MIUI требует разрешение «Автозапуск». Приложение должно определять Xiaomi и направлять пользователя для активации.
Фоновый звук Samsung: One UI агрессивно убивает процессы. Приложение нужно добавить в «Неотслеживаемые приложения» или запросить отключение оптимизации батареи.
Краш при повороте: Activity уничтожается и пересоздаётся. Если данные не сохранены в ViewModel, они теряются. Используйте ViewModel для переживания изменений конфигурации.
Советы из продакшен-опыта
Совет 1: Держите ADB в PATH и используйте ежедневно. Очистка данных, симуляция сетевых условий и захват логов через ADB быстрее любого GUI-инструмента.
Совет 2: Тестируйте на Samsung в первую очередь. Samsung представляет 30-40% рынка Android в большинстве регионов. Если работает на Samsung — вы покрыли крупнейший сегмент.
Совет 3: Всегда тестируйте поворот с данными на экране. Поворачивайте при заполнении формы, просмотре видео, в чате или во время оплаты.
Ключевые выводы
- Жизненный цикл Activity и изменения конфигурации — источник №1 платформо-специфичных багов
- ADB — незаменимый инструмент для тестировщиков Android
- Espresso тестирует внутри процесса; UI Automator пересекает границы процессов
- Кастомизации производителей создают девайс-специфичные баги
- Всегда тестируйте поворот экрана, навигацию «Назад» и многооконный режим