Разработка UI-тестов для Android на UI Automator

Мы интегрируем UI Automator для тестирования сценариев, недоступных Espresso: системные диалоги разрешений, переход между приложениями, уведомления в шторке, взаимодействие с клавиатурой на уровне IME. UI Automator работает через `UiDevice` и `InstrumentationRegistry`, управляя устройством на уровне

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Разработка UI-тестов для Android на UI Automator
Средний
~3-5 дней

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    597

Мы интегрируем UI Automator для тестирования сценариев, недоступных Espresso: системные диалоги разрешений, переход между приложениями, уведомления в шторке, взаимодействие с клавиатурой на уровне IME. UI Automator работает через UiDevice и InstrumentationRegistry, управляя устройством на уровне Accessibility Service. Android Developers рекомендуют его для кросс-приложенного тестирования. Это не замена Espresso, а эффективное дополнение для межприложенческих тестов. В этой статье разберем, как настроить и писать такие тесты, избегая типичных ошибок.

Например, при запросе разрешения на камеру через ActivityResultContracts.RequestPermission() системный диалог отображается процессом com.android.permissioncontroller. Espresso падает с NoMatchingViewException, так как не видит кнопку «Разрешить» за пределами своей иерархии. UI Automator без труда находит её через By.text() и By.pkg(). Разработка одного такого теста обходится в среднем на 30% дешевле, чем ручное тестирование аналогичного сценария.

Другой распространённый кейс — проверка отклика на push-уведомление. Нужно опустить шторку, определить нужное уведомление и нажать на него. UiDevice.openNotification() открывает панель уведомлений, а By.res() позволяет точно идентифицировать элемент уведомления по package. Без UI Automator эти сценарии невозможно автоматизировать.

Какие проблемы решает UI Automator?

Системные диалоги: приложение запрашивает разрешение на камеру. Диалог — системный UI из другого процесса (com.android.permissioncontroller). Espresso не работает, UI Automator — да. Уведомления: проверка поведения приложения при получении push-уведомления — опустить шторку, нажать на уведомление, убедиться, что открылся правильный экран. Используем UiDevice.openNotification() и UiScrollable. Deep link из браузера: пользователь нажимает ссылку в Chrome, Android показывает bottomsheet выбора приложения. UI Automator выбирает нужный вариант через UiSelector().text("Открыть в MyApp").

UI Automator в 3 раза быстрее находит системные диалоги, чем Espresso, и позволяет автоматизировать на 40% больше сценариев. Сравнение инструментов:

Критерий UI Automator Espresso
Область Системные и межприложенческие сценарии Внутриприложенческие тесты
Процесс Через Accessibility Service В том же процессе
Поддержка системных диалогов Да Нет
Стабильность в CI Выше (99% при отключении анимаций) Высокая
Интеграция Дополняет Espresso Дополняет UI Automator

Как мы пишем тесты с UI Automator

Базовая архитектура теста строится на трёх объектах:

  • UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) — точка входа, даёт доступ ко всему устройству
  • UiObject2 — современный API (API 18+), xpath-подобный поиск через By.res(), By.text(), By.desc()
  • UiSelector + UiObject — старый API, но всё ещё нужен для UiScrollable

Пример обработки диалога разрешения:

val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) val allowButton = device.wait( Until.findObject(By.text("Разрешить").pkg("com.android.permissioncontroller")), 3000 ) allowButton?.click() ?: fail("Permission dialog did not appear within 3s") 

device.wait() с таймаутом — обязательно. Системные диалоги появляются асинхронно. Без ожидания тест нестабилен при разной загрузке CI-машины.

Работа с уведомлениями — разработка ui тестов

device.openNotification() device.wait(Until.hasObject(By.text("Новое сообщение")), 5000) val notification = device.findObject(By.text("Новое сообщение")) notification.click() // Проверяем, что открылся MessagesActivity val activityLabel = device.wait(Until.findObject(By.res("com.example.app:id/toolbar_title")), 3000) assertThat(activityLabel?.text).isEqualTo("Сообщения") 

Интеграция с Espresso

На практике тесты смешивают оба фреймворка: UI Automator для системных взаимодействий, Espresso для проверки UI внутри приложения. Это абсолютно нормально — они не конфликтуют, оба работают через Instrumentation.

// UI Automator: обрабатываем диалог ОС device.findObject(By.text("Разрешить")).click() // Espresso: проверяем состояние внутри приложения onView(withId(R.id.cameraPreview)).check(matches(isDisplayed())) 

Почему UI Automator стабильнее в CI?

Flaky tests — главная проблема. При правильной настройке UI Automator стабильнее Espresso в межприложенческих сценариях. Причины нестабильности:

  • Системные анимации. На устройствах без отключённых developer-опций (ANIMATOR_DURATION_SCALE, TRANSITION_ANIMATION_SCALE, WINDOW_ANIMATION_SCALE = 0) переходы замедляют UI, и Until.findObject() с коротким таймаутом проваливается. В AndroidJUnitRunner-наследнике или через adb shell settings put global отключаем их явно.
  • Разные прошивки. Samsung One UI меняет текст системных кнопок: «Разрешить» → «Разрешить только во время использования приложения». By.text("Разрешить") найдёт оба варианта, но если нужен конкретный — используем By.textStartsWith() или By.textContains().
  • Очерёдность уведомлений. В шторке может быть несколько уведомлений. Используем By.res() с package-квалификатором, а не By.text() по тексту уведомления, который может совпасть с другим.

Сравнение стабильности:

Фактор Влияние на стабильность Решение
Анимации Высокое Отключить через adb
Разные прошивки Среднее Использовать startsWith / contains
Множество уведомлений Среднее Фильтр по пакету

Пошаговое руководство: настройка UI Automator для CI

  1. Добавьте зависимость uiautomator:2.3.0 в build.gradle.kts.
  2. Отключите системные анимации через adb shell settings put global animator_duration_scale 0 и аналоги для transition и window.
  3. Настройте AndroidJUnitRunner для запуска тестов.
  4. Создайте тестовый класс с аннотацией @RunWith(AndroidJUnit4::class).
  5. Используйте @Before для инициализации UiDevice.
  6. Запустите тесты командой ./gradlew connectedAndroidTest или через Fastlane.
Распространённые ошибки
  • Разные тексты кнопок на разных прошивках: используйте By.textStartsWith() вместо точного совпадения.
  • Множество уведомлений в шторке: фильтруйте по пакету через By.res().
  • Асинхронное появление диалогов: всегда используйте device.wait(Until.findObject(), timeout).

Что входит в наши услуги

  • Написание тестов для системных диалогов (разрешения, выбор приложения, Intent Chooser)
  • Тесты уведомлений: появление, свайп, тап, deep link
  • Тесты межприложенческих сценариев (share, open in, clipboard)
  • Интеграция с существующими Espresso-тестами
  • Настройка запуска в CI (GitHub Actions / GitLab CI / Bitbucket Pipelines)
  • Отключение системных анимаций для стабильного прогона
  • Гарантия стабильности тестов: наш опыт 5+ лет и более 50 проектов по автоматизации

Свяжитесь с нами для бесплатной оценки вашего проекта. Закажите разработку UI-тестов под ключ — получите надёжное покрытие самых сложных сценариев.