UI Automator je framework od Googlu pro automatizované UI testování aplikací pro Android, který pracuje na úrovni systému a může interagovat s prvky rozhraní mimo jednu aplikaci. Na rozdíl od Espressa není UI Automator vázán na proces konkrétní aplikace: může otevírat systémová dialogová okna, panel notifikací a přepínat mezi aplikacemi. Podle Google Android Developers používá UI Automator standardní Accessibility Service pro přístup k UI stromu zařízení.
Hlavní body
UI Automator je framework pro funkcionální UI testování Androidu, který pracuje na úrovni operačního systému. Poskytuje API pro přístup k libovolnému prvku na obrazovce zařízení, bez ohledu na to, ke které aplikaci patří — včetně systémového stavového řádku, dialogů oprávnění, domovské obrazovky a aplikací třetích stran. Díky tomu je nepostradatelný pro testování scénářů, které přesahují jednu aplikaci.
Architektonicky UI Automator používá Accessibility Service — stejnou službu, kterou používají TalkBack, Switch Access a další nástroje pro přístupnost. Prostřednictvím této služby framework získá úplný strom UI komponent aktuální obrazovky a umožňuje na nich provádět akce: kliknutí, posunutí, zadání textu, dlouhé stisknutí.
UI Automator se poprvé objevil v Android 4.3 (API 18) a od té doby je součástí Android Testing Support Library jako oficiální nástroj Googlu pro meziaplikační testování. V AndroidX Test je dostupný jako samostatný artefakt androidx.test.uiautomator:uiautomator verze 2.3.0 (2024), který podporuje všechny verze Android od API 18.
Princip fungování UI Automator je založen na skenování Accessibility stromu aktuální obrazovky. Při volání metody findObject(selector) framework prochází hierarchii View, najde první prvek splňující podmínky UiSelector a vrátí objekt UiObject — proxy pro interakci se skutečným View.
Typický test UI Automator začíná získáním instance UiDevice, která představuje fyzické zařízení. UiDevice poskytuje metody pro vyhledávání prvků, správu stisků tlačítek (Home, Back, Recent), otáčení obrazovky a pořizování snímků obrazovky. Po nalezení prvku pomocí UiSelector se provádějí akce na UiObject.
V níže uvedeném příkladu test otevře aplikaci Settings, najde položku „Baterie“ podle textu a klikne na ni. UI Automator nevyžaduje spuštění Activity — pracuje s libovolnou obrazovkou zařízení, včetně aplikací třetích stran.
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
// Otevřít obrazovku nastavení
device.pressHome()
device.wait(Until.hasObject(UiSelector().text("Nastavení")), 2000)
// Najít položku „Baterie“ a kliknout
val batteryItem = device.findObject(
UiSelector().text("Baterie")
)
batteryItem.clickAndWait(Until.newWindow(), 3000)
UiDevice — hlavní třída pro interakci se zařízením. Poskytuje metody pro vyhledávání prvků, simulaci stisků hardwarových tlačítek (Home, Back, Menu, Volume), správu napájení, pořizování snímků obrazovky a čekání na konkrétní stavy obrazovky. UiDevice se vytváří jednou za test a znovu používá pro všechny operace.
UiSelector — je fluent API pro vyhledávání UI prvků. Na rozdíl od ViewMatchers v Espressu nevyžaduje UiSelector kompilaci — podmínky vyhledávání se tvoří řetězcem metod: text(), className(), description(), resourceId(), index(). Více podmínek se automaticky kombinuje pomocí logického AND.
| Metoda UiSelector | Účel |
|---|---|
| text(String) | Vyhledávání podle přesného textu prvku |
| textContains(String) | Vyhledávání podle části textu |
| resourceId(String) | Vyhledávání podle ID zdroje (např. com.example:id/button) |
| className(String) | Vyhledávání podle názvu třídy View |
| description(String) | Vyhledávání podle content-description |
| childSelector(selector) | Vyhledávání potomka v kontejneru |
Když je na obrazovce více prvků se stejným textem, UiSelector umožňuje kombinovat kritéria: najít kontejner podle ID, poté uvnitř něj — prvek podle textu a třídy. To zaručuje jedinečnou identifikaci požadovaného komponentu. Metoda childSelector zužuje oblast vyhledávání na určený kontejner, což urychluje navigaci v UI stromu.
val scrollView = device.findObject(
UiSelector().resourceId("android:id/list")
)
// V seznamu najděte prvek s textem „Wi-Fi“
val wifiItem = scrollView.findObject(
UiSelector().text("Wi-Fi")
wifiItem.click()
Cross-application (meziaplikační) testování — hlavní funkce, pro kterou se UI Automator vybírá. Framework může přepínat mezi aplikacemi, testovat přihlášení OAuth prostřednictvím prohlížeče, kontrolovat systémová dialogová okna (oprávnění, výběr aplikace) a interagovat se systémovým stavovým řádkem, panelem notifikací a uzamčenou obrazovkou.
Typický scénář cross-app testu: aplikace otevře prohlížeč pro autorizaci OAuth, uživatel zadá uživatelské jméno a heslo, prohlížeč přesměruje zpět do aplikace. UI Automator přepíná mezi procesy, najde vstupní pole v prohlížeči, vyplní je a klikne na „Přihlásit se“.
// Čekání na objevení prohlížeče
device.wait(Until.hasObject(
UiSelector().packageName("com.android.chrome")
), 5000)
// Hledání pole pro zadání emailu v prohlížeči
val emailField = device.findObject(
UiSelector().className("android.widget.EditText").instance(0)
)
emailField.text = "user@example.com"
UI Automator může kontrolovat a zavírat systémová dialogová okna — oprávnění pro geolokaci, notifikace, přístup k souborům. To je klíčové pro testování prvního spuštění aplikace, kdy systém postupně žádá o několik oprávnění. Bez UI Automator nelze takové scénáře automatizovat, protože systémová dialogová okna nepatří do procesu aplikace.
Výběr mezi UI Automatorem a Espressem závisí na scénáři testování. Espresso je optimalizováno pro testování jedné aplikace s automatickou synchronizací a minimálním boilerplate. UI Automator je vhodný pro scénáře, kde je třeba interakce se systémem, prohlížečem nebo více aplikacemi.
| Kritérium | UI Automator | Espresso |
|---|---|---|
| Oblast | Celé zařízení, více aplikací | Jedna aplikace |
| Synchronizace | Ruční (wait, sleep) | Automatická (Idling Resource) |
| Rychlost | Pomalejší (přístup přes službu) | Rychlejší (pracuje uvnitř procesu) |
| System UI | Podporuje (Notifications, Quick Settings) | Nepodporuje |
| Přesnost vyhledávání | UiSelector podle atributů | ViewMatchers podle typu a hierarchie |
| Stabilita | Nižší (závisí na načasování) | Vyšší (automatické čekání) |
V praxi se tyto frameworky často používají spolu: Espresso pokrývá UI testy hlavní aplikace s vysokou stabilitou a UI Automator se připojuje pro scénáře přesahující hranice aplikace — přihlášení OAuth, systémová oprávnění, práce se Share Intent. Tato kombinace poskytuje maximální pokrytí UI při minimálních nákladech na údržbu testů.
Připojení UI Automator se provádí přidáním závislosti v build.gradle. Framework je součástí AndroidX Test a nevyžaduje další oprávnění v manifestu — přístup k Accessibility Service se konfiguruje automaticky při spuštění instrumentálního testu.
Minimální konfigurace zahrnuje artefakt uiautomator a standardní běhový test AndroidJUnitRunner. Testy UI Automator se umisťují do adresáře src/androidTest a spouštějí na emulátoru nebo fyzickém zařízení s Android API 18+.
dependencies {
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0")
androidTestImplementation("androidx.test.ext:junit:1.2.1")
androidTestImplementation("androidx.test:runner:1.6.1")
}
Pro získání instance UiDevice se používá InstrumentationRegistry.getInstrumentation(). UiDevice by měl být vytvořen jednou v metodě setUp() a znovu použit ve všech testech třídy pro úsporu prostředků zařízení. Je důležité si uvědomit, že UiDevice není thread-safe — všechny operace musí být provedeny v jednom vláknu testovací metody. Vytváření nového UiDevice v každém testu vede k režii a zpomalení provádění. Doporučuje se vytvořit UiDevice jednou v metodě beforeClass a znovu jej použít pro všechny testy testovací třídy.
Na rozdíl od Espressa nemá UI Automator automatickou synchronizaci. Pro čekání na výskyt prvků se používá metoda UiDevice.wait(condition, timeout) s objektem Until: Until.findObject(selector), Until.hasObject(selector), Until.gone(selector). Bez správného čekání se testy stávají nestabilními kvůli race condition — prvek se nemusí stihnout objevit na obrazovce do okamžiku vyhledávání. Doporučuje se nastavit časový limit alespoň 3-5 sekund pro stabilitu.
Často kladené otázky
UI Automator pracuje na úrovni Accessibility Service a může interagovat s libovolnými aplikacemi. Espresso pracuje uvnitř procesu jedné aplikace a používá automatickou synchronizaci s UI vláknem. UI Automator je lepší pro meziaplikační scénáře, Espresso — pro stabilní testy jedné aplikace.
Ano, UI Automator funguje na všech zařízeních s Android API 18+. Nevyžaduje root přístup — používá se standardní Accessibility Service, která je aktivována prostřednictvím Instrumentation při spuštění testů.
UI Automator používá Accessibility Service k získání úplného stromu UI komponent aktuální obrazovky. Poté UiSelector prochází tento strom a nachází prvky podle zadaných kritérií: text, třída, ID, content-description nebo jejich kombinace.
Ano, metoda UiDevice.takeScreenshot(storePath) umožňuje pořídit snímek aktuální obrazovky a uložit jej do souboru. To je užitečné pro ladění: při pádu testu lze uložit snímek a analyzovat stav obrazovky.
UI Automator nemá automatickou synchronizaci, proto jsou testy citlivé na načasování. Pokud animace neskončila nebo View nestihl vykreslit, findObject nemusí najít prvek. Řešení — použijte UiDevice.wait() s dostatečným časovým limitem.
Shrnutí
Sada nástrojů UI Automator pokrývá všechny klíčové scénáře meziaplikačního testování a je standardem pro automatizaci Androidu na úrovni systému.
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také