Az UI Automator egy Google által fejlesztett keretrendszer Android-alkalmazások automatizált UI-teszteléséhez, amely rendszerszinten működik és képes egy alkalmazáson túli interfész elemekkel interakcióba lépni. Az Espresso-val ellentétben az UI Automator nem kötődik egy adott alkalmazás folyamatához: képes rendszerdialógusokat megnyitni, az értesítési panelt kezelni és alkalmazások között váltani. A Google Android Developers szerint az UI Automator a szabványos Accessibility Service-t használja az eszköz UI-fájának eléréséhez.
Főbb pontok
Az UI Automator egy funkcionális Android UI-tesztelési keretrendszer, amely az operációs rendszer szintjén működik. API-t biztosít az eszköz képernyőjén lévő bármely elem eléréséhez, függetlenül attól, hogy melyik alkalmazáshoz tartozik — beleértve a rendszer állapotsort, engedélydialógusokat, kezdőképernyőt és harmadik féltől származó alkalmazásokat. Ez nélkülözhetetlenné teszi az egy alkalmazáson túl mutató forgatókönyvek teszteléséhez.
Architektúráját tekintve az UI Automator az Accessibility Service-t használja — ugyanazt a szolgáltatást, amelyet a TalkBack, a Switch Access és más akadálymentesítési eszközök használnak. Ezen a szolgáltatáson keresztül a keretrendszer megszerzi az aktuális képernyő teljes UI-komponensfáját, és lehetővé teszi műveletek végrehajtását rajtuk: kattintás, lapítás, szövegbevitel, hosszú nyomva tartás.
Az UI Automator először az Android 4.3-ban (API 18) jelent meg, és azóta az Android Testing Support Library része, mint a Google hivatalos eszköze alkalmazásközi teszteléshez. Az AndroidX Test-ben külön androidx.test.uiautomator:uiautomator 2.3.0 (2024) verziójú artefaktumként érhető el, amely az API 18-tól kezdve az Android összes verzióját támogatja.
Az UI Automator működési elve az aktuális képernyő Accessibility-fájának beolvasásán alapul. A findObject(selector) metódus meghívásakor a keretrendszer bejárja a View-hierarchiát, megtalálja az UiSelector feltételeinek megfelelő első elemet, és visszaad egy UiObject objektumot — egy proxyt a valódi View-val való interakcióhoz.
Egy tipikus UI Automator teszt a fizikai eszközt reprezentáló UiDevice példány megszerzésével kezdődik. A UiDevice metódusokat biztosít elemek kereséséhez, gombnyomások kezeléséhez (Home, Back, Recent), a képernyő elforgatásához és képernyőképek készítéséhez. Miután az elem megtalálásra került a UiSelector segítségével, műveletek hajthatók végre a UiObject-en.
Az alábbi példában a teszt megnyitja a Settings alkalmazást, megtalálja az „Akkumulátor” elemet szöveg alapján, és rákattint. Az UI Automator nem igényli az Activity elindítását — az eszköz bármely képernyőjével működik, beleértve a harmadik féltől származó alkalmazásokat.
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
// Nyissa meg a beállítások képernyőjét
device.pressHome()
device.wait(Until.hasObject(UiSelector().text("Beállítások")), 2000)
// Keresse meg az „Akkumulátor” elemet és kattintson rá
val batteryItem = device.findObject(
UiSelector().text("Akkumulátor")
)
batteryItem.clickAndWait(Until.newWindow(), 3000)
UiDevice — a fő osztály az eszközzel való interakcióhoz. Metódusokat biztosít elemek kereséséhez, hardveres gombok lenyomásának szimulálásához (Home, Back, Menu, Volume), energiaellátás kezeléséhez, képernyőkép készítéséhez és bizonyos képernyőállapotokra való várakozáshoz. A UiDevice tesztelként egyszer jön létre, és az összes művelethez újrahasználódik.
UiSelector — egy folyamatos (fluent) API UI-elemek kereséséhez. Az Espresso ViewMatchers-eivel ellentétben a UiSelector nem igényel fordítást — a keresési feltételek metódusok láncával alakíthatók ki: text(), className(), description(), resourceId(), index(). Több feltétel automatikusan kombinálódik logikai ÉS segítségével.
| UiSelector metódus | Rendeltetés |
|---|---|
| text(String) | Keresés az elem pontos szövege alapján |
| textContains(String) | Keresés a szöveg része alapján |
| resourceId(String) | Keresés erőforrás ID alapján (pl. com.example:id/button) |
| className(String) | Keresés a View osztály neve alapján |
| description(String) | Keresés content-description alapján |
| childSelector(selector) | Gyermek elem keresése egy konténerben |
Amikor több azonos szövegű elem van a képernyőn, a UiSelector lehetővé teszi a kritériumok kombinálását: a konténer megkeresése ID alapján, majd azon belül — az elem szöveg és osztály alapján. Ez garantálja a szükséges komponens egyedi azonosítását. A childSelector metódus a keresési területet a megadott konténerre szűkíti, ami felgyorsítja az UI-fában való navigációt.
val scrollView = device.findObject(
UiSelector().resourceId("android:id/list")
)
// A lista belsejében keresse meg az „Wi-Fi” szövegű elemet
val wifiItem = scrollView.findObject(
UiSelector().text("Wi-Fi")
wifiItem.click()
Cross-application (alkalmazásközi) tesztelés — a fő funkció, amíért az UI Automator-t választják. A keretrendszer képes alkalmazások között váltani, OAuth-bejelentkezést tesztelni a böngészőn keresztül, rendszerdialógusokat (engedélyek, alkalmazásválasztás) ellenőrizni és interakcióba lépni a rendszer állapotsorával, értesítési panelial és a zárképernyővel.
Egy tipikus cross-app teszt forgatókönyv: az alkalmazás megnyitja a böngészőt OAuth-hitelesítéshez, a felhasználó megadja a felhasználónevet és jelszót, a böngésző visszairányít az alkalmazásba. Az UI Automator folyamatok között vált, megtalálja a beviteli mezőket a böngészőben, kitölti azokat, és rákattint a „Bejelentkezés” gombra.
// Várakozás a böngésző megjelenésére
device.wait(Until.hasObject(
UiSelector().packageName("com.android.chrome")
), 5000)
// Email beviteli mező keresése a böngészőben
val emailField = device.findObject(
UiSelector().className("android.widget.EditText").instance(0)
)
emailField.text = "user@example.com"
Az UI Automator képes ellenőrizni és bezárni a rendszerdialógusokat — helymeghatározási engedélyek, értesítések, hozzáférés fájlokhoz. Ez kritikus az alkalmazás első indításának teszteléséhez, amikor a rendszer egymás után több engedélyt kér. UI Automator nélkül az ilyen forgatókönyvek nem automatizálhatók, mert a rendszerdialógusok nem tartoznak az alkalmazás folyamatához.
A választás az UI Automator és az Espresso között a tesztelési forgatókönyvtől függ. Az Espresso egyetlen alkalmazás tesztelésére van optimalizálva automatikus szinkronizációval és minimális boilerplate-tel. Az UI Automator olyan forgatókönyvekhez alkalmas, ahol interakcióra van szükség a rendszerrel, a böngészővel vagy több alkalmazással.
| Szempont | UI Automator | Espresso |
|---|---|---|
| Hatókör | Teljes eszköz, több alkalmazás | Egy alkalmazás |
| Szinkronizáció | Kézi (wait, sleep) | Automatikus (Idling Resource) |
| Sebesség | Lassabb (hozzáférés szolgáltatáson keresztül) | Gyorsabb (folyamaton belül működik) |
| System UI | Támogatja (Notifications, Quick Settings) | Nem támogatja |
| Keresési pontosság | UiSelector attribútumok alapján | ViewMatchers típus és hierarchia alapján |
| Stabilitás | Alacsonyabb (időzítéstől függ) | Magasabb (automatikus várakozás) |
A gyakorlatban ezek a keretrendszerek gyakran együtt használatosak: az Espresso magas stabilitással fedi le a fő alkalmazás UI-tesztjeit, az UI Automator pedig az alkalmazás határain túlmutató forgatókönyvekhez — OAuth-bejelentkezés, rendszerengedélyek, Share Intent használata — csatlakozik. Ez a kombináció maximális UI-lefedettséget biztosít minimális tesztkarbantartási költség mellett.
Csatlakoztatás az UI Automator a build.gradle fájlban történő függőség hozzáadásával történik. A keretrendszer az AndroidX Test része, és nem igényel további engedélyeket a manifestben — az Accessibility Service elérése automatikusan konfigurálódik az instrumentális teszt indulásakor.
A minimális konfiguráció magában foglalja az uiautomator artefaktumot és a szabványos AndroidJUnitRunner tesztfuttatót. Az UI Automator tesztek a src/androidTest könyvtárba kerülnek, és Android API 18+ rendszerű emulátoron vagy fizikai eszközön futnak.
dependencies {
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0")
androidTestImplementation("androidx.test.ext:junit:1.2.1")
androidTestImplementation("androidx.test:runner:1.6.1")
}
A UiDevice példány megszerzéséhez az InstrumentationRegistry.getInstrumentation() használható. A UiDevice-et egyszer kell létrehozni a setUp() metódusban, és újra felhasználni az osztály összes tesztjében az eszköz erőforrásainak megtakarítása érdekében. Fontos megjegyezni, hogy a UiDevice nem thread-safe — minden műveletet a tesztmetódus egy szálában kell végrehajtani. Új UiDevice létrehozása minden tesztben túlterheléshez és a végrehajtás lelassulásához vezet. Javasolt a UiDevice egyszeri létrehozása a beforeClass metódusban és újrahasználata a tesztosztály összes tesztjéhez.
Az Espresso-val ellentétben az UI Automator nem rendelkezik automatikus szinkronizációval. Az elemek megjelenésére való várakozáshoz a UiDevice.wait(condition, timeout) metódust használjuk az Until objektummal: Until.findObject(selector), Until.hasObject(selector), Until.gone(selector). Helyes várakozás nélkül a tesztek instabillá válnak a versenyhelyzet miatt — előfordulhat, hogy az elem nem jelenik meg a képernyőn a keresés pillanatában. A stabilités érdekében javasolt legalább 3-5 másodperces időtúllépést beállítani.
Gyakran ismételt kérdések
Az UI Automator az Accessibility Service szintjén működik és képes interakcióba lépni bármely alkalmazással. Az Espresso egy alkalmazás folyamatán belül működik és automatikus szinkronizációt használ az UI-szállal. Az UI Automator jobb alkalmazásközi forgatókönyvekhez, az Espresso — egy alkalmazás stabil tesztjeihez.
Igen, az UI Automator minden Android API 18+ rendszerű eszközön működik. Nem igényel root-hozzáférést — a szabványos Accessibility Service-t használja, amely a tesztek indításakor az Instrumentation-en keresztül aktiválódik.
Az UI Automator az Accessibility Service-t használja az aktuális képernyő teljes UI-komponensfájának megszerzéséhez. Ezután a UiSelector bejárja ezt a fát és megtalálja az elemeket a megadott kritériumok alapján: szöveg, osztály, ID, content-description vagy ezek kombinációja.
Igen, a UiDevice.takeScreenshot(storePath) metódus lehetővé teszi az aktuális képernyőről készült kép mentését fájlba. Ez hasznos a hibakereséshez: teszt hibája esetén a képernyőkép elmenthető és a képernyő állapota elemezhető.
Az UI Automator nem rendelkezik automatikus szinkronizációval, ezért a tesztek érzékenyek az időzítésre. Ha az animáció nem fejeződött be, vagy a View nem rajzolódott ki időben, a findObject nem találhatja meg az elemet. Megoldás — használjon UiDevice.wait() metódust megfelelő timeouttal.
Összefoglaló
Az UI Automator eszközkészlet lefedi az összes kulcsfontosságú alkalmazásközi tesztelési forgatókönyvet, és szabványnak számít az Android rendszerszintű automatizálásában.
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is