Основы тестирования Android

Открытая экосистема Android создаёт как возможности, так и вызовы для тестировщиков. Свобода, позволяющая тысячам производителей кастомизировать Android, создаёт проблему фрагментации, определяющую QA на Android.

Жизненный цикл Activity

Жизненный цикл Activity — важнейший концепт для тестировщиков Android. Activities (экраны) проходят через специфические переходы состояний, часто вызывающие баги.

Состояния Activity

Created → Started → Resumed → Paused → Stopped → Destroyed
CallbackКогда вызываетсяФокус тестирования
onCreateActivity создан впервыеИнициализация, загрузка данных
onStartActivity становится видимымНастройка UI
onResumeActivity получает фокусОбновление данных
onPauseДругой activity выходит на передний планСохранение временных данных
onStopActivity больше не видимОсвобождение тяжёлых ресурсов
onDestroyActivity уничтожаетсяОчистка

Изменения конфигурации

При изменении конфигурации устройства Android уничтожает и пересоздаёт Activity:

  • Поворот экрана (портрет ↔ ландшафт)
  • Смена языка
  • Изменение размера шрифта
  • Переключение тёмной темы
  • Многооконный режим

Это источник №1 Android-специфичных багов. Тестируйте каждый экран после:

  1. Поворота устройства во время операции
  2. Изменения размера шрифта в настройках
  3. Переключения тёмной темы
  4. Входа и выхода из режима разделённого экрана

Инструменты тестирования 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 между приложениями в разделённом экране
# Тестирование 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.

  1. Push-уведомления не появляются на устройствах Xiaomi
  2. Фоновое воспроизведение музыки останавливается через 10 минут на Samsung
  3. Приложение падает при повороте во время заполнения многошагового формы
Решение
  1. Проблема уведомлений Xiaomi: MIUI требует разрешение «Автозапуск». Приложение должно определять Xiaomi и направлять пользователя для активации.

  2. Фоновый звук Samsung: One UI агрессивно убивает процессы. Приложение нужно добавить в «Неотслеживаемые приложения» или запросить отключение оптимизации батареи.

  3. Краш при повороте: Activity уничтожается и пересоздаётся. Если данные не сохранены в ViewModel, они теряются. Используйте ViewModel для переживания изменений конфигурации.

Советы из продакшен-опыта

Совет 1: Держите ADB в PATH и используйте ежедневно. Очистка данных, симуляция сетевых условий и захват логов через ADB быстрее любого GUI-инструмента.

Совет 2: Тестируйте на Samsung в первую очередь. Samsung представляет 30-40% рынка Android в большинстве регионов. Если работает на Samsung — вы покрыли крупнейший сегмент.

Совет 3: Всегда тестируйте поворот с данными на экране. Поворачивайте при заполнении формы, просмотре видео, в чате или во время оплаты.

Ключевые выводы

  • Жизненный цикл Activity и изменения конфигурации — источник №1 платформо-специфичных багов
  • ADB — незаменимый инструмент для тестировщиков Android
  • Espresso тестирует внутри процесса; UI Automator пересекает границы процессов
  • Кастомизации производителей создают девайс-специфичные баги
  • Всегда тестируйте поворот экрана, навигацию «Назад» и многооконный режим