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

Ми інтегруємо UI Automator для тестування сценаріїв, недоступних Espresso: системні діалоги дозволів, перехід між застосунками, сповіщення в шторці, взаємодія з клавіатурою на рівні IME. UI Automator працює через `UiDevice` та `InstrumentationRegistry`, керуючи пристроєм на рівні Accessibility Servi

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

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

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

Часті запитання

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    895
  • 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
    1003
  • 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-тестів під ключ — отримайте надійне покриття найскладніших сценаріїв.