UI Automator är ett ramverk från Google för automatiserad UI-testning av Android-applikationer som fungerar på systemnivå och kan interagera med gränssnittselement utanför en enskild applikation. Till skillnad från Espresso är UI Automator inte bundet till en specifik applikations process: det kan öppna systemdialogrutor, notifikationspanelen och växla mellan applikationer. Enligt Google Android Developers använder UI Automator den vanliga Accessibility Service för att få tillgång till enhetens UI-träd.
Huvudpunkter
UI Automator är ett ramverk för funktionell UI-testning av Android som fungerar på operativsystemsnivå. Det tillhandahåller ett API för att få tillgång till vilket element som helst på enhetens skärm, oavsett vilken applikation det tillhör — inklusive systemets statusfält, behörighetsdialogrutor, hemskärmen och tredjepartsapplikationer. Detta gör det oumbärligt för att testa scenarier som sträcker sig utanför en enda applikation.
Arkitektoniskt använder UI Automator Accessibility Service — samma tjänst som används av TalkBack, Switch Access och andra hjälpmedelsverktyg. Genom denna tjänst får ramverket det fullständiga UI-komponentträdet för den aktuella skärmen och gör det möjligt att utföra åtgärder på dem: klick, svep, textinmatning, lång tryckning.
UI Automator första gången i Android 4.3 (API 18) och har sedan dess varit en del av Android Testing Support Library som Googles officiella verktyg för tvär-applikationell testning. I AndroidX Test är det tillgängligt som en separat artefakt androidx.test.uiautomator:uiautomator version 2.3.0 (2024), som stödjer alla Android-versioner från API 18.
Funktionsprincipen för UI Automator är baserad på avsökning av Accessibility-trädet för den aktuella skärmen. När metoden findObject(selector) anropas, går ramverket igenom View-hierarkin, hittar det första elementet som uppfyller UiSelector-villkoren och returnerar ett UiObject-objekt — en proxy för interaktion med den verkliga Viewn.
Ett typiskt UI Automator-test börjar med att få en instans av UiDevice, som representerar den fysiska enheten. UiDevice tillhandahåller metoder för att söka efter element, hantera knapptryckningar (Home, Back, Recent), rotera skärmen och ta skärmbilder. När elementet har hittats via UiSelector utförs åtgärder på UiObject.
I exemplet nedan öppnar testet appen Settings, hittar objektet ”Batteri” via text och klickar på det. UI Automator kräver inte att en Activity startas — det fungerar med vilken skärm som helst på enheten, inklusive tredjepartsapplikationer.
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
// Öppna inställningsskärmen
device.pressHome()
device.wait(Until.hasObject(UiSelector().text("Inställningar")), 2000)
// Hitta objektet ”Batteri” och klicka
val batteryItem = device.findObject(
UiSelector().text("Batteri")
)
batteryItem.clickAndWait(Until.newWindow(), 3000)
UiDevice — huvudklassen för interaktion med enheten. Det tillhandahåller metoder för att söka efter element, simulera hårdvaruknapptryckningar (Home, Back, Menu, Volume), hantera strömförsörjning, ta skärmbilder och vänta på specifika skärmtillstånd. UiDevice skapas en gång per test och återanvänds för alla operationer.
UiSelector — är ett flytande (fluent) API för att söka efter UI-element. Till skillnad från ViewMatchers i Espresso kräver UiSelector ingen kompilering — sökvillkoren formas genom en kedja av metoder: text(), className(), description(), resourceId(), index(). Flera villkor kombineras automatiskt genom logiskt OCH.
| UiSelector-metod | Ändamål |
|---|---|
| text(String) | Sökning efter elementets exakta text |
| textContains(String) | Sökning efter en del av texten |
| resourceId(String) | Sökning efter resurs-ID (t.ex. com.example:id/button) |
| className(String) | Sökning efter View-klassens namn |
| description(String) | Sökning efter content-description |
| childSelector(selector) | Sökning av underordnat element i en behållare |
När det finns flera element med samma text på skärmen, gör UiSelector det möjligt att kombinera kriterier: hitta behållaren via ID, sedan inuti den — elementet via text och klass. Detta garanterar unik identifiering av den nödvändiga komponenten. Metoden childSelector begränsar sökområdet till den angivna behållaren, vilket snabbar upp navigeringen i UI-trädet.
val scrollView = device.findObject(
UiSelector().resourceId("android:id/list")
)
// I listan, hitta elementet med texten ”Wi-Fi”
val wifiItem = scrollView.findObject(
UiSelector().text("Wi-Fi")
wifiItem.click()
Cross-application (mellan applikationer) testning — den huvudsakliga funktionen för vilken UI Automator väljs. Ramverket kan växla mellan applikationer, testa OAuth-inloggning via webbläsaren, kontrollera systemdialogrutor (behörigheter, val av applikation) och interagera med systemets statusfält, notifikationspanelen och låsskärmen.
Ett typiskt cross-app-testscenario: applikationen öppnar webbläsaren för OAuth-autorisering, användaren anger användarnamn och lösenord, webbläsaren omdirigerar tillbaka till applikationen. UI Automator växlar mellan processer, hittar inmatningsfält i webbläsaren, fyller i dem och klickar på ”Logga in”.
// Vänta på att webbläsaren visas
device.wait(Until.hasObject(
UiSelector().packageName("com.android.chrome")
), 5000)
// Sök efter e-postinmatningsfält i webbläsaren
val emailField = device.findObject(
UiSelector().className("android.widget.EditText").instance(0)
)
emailField.text = "user@example.com"
UI Automator kan kontrollera och stänga systemdialogrutor — geolokaliseringsbehörigheter, notifikationer, åtkomst till filer. Detta är avgörande för att testa den första starten av applikationen, när systemet efter varandra begär flera behörigheter. Utan UI Automator kan sådana scenarier inte automatiseras eftersom systemdialogrutor inte tillhör applikationens process.
Valet mellan UI Automator och Espresso beror på testscenariot. Espresso är optimerat för att testa en enskild applikation med automatisk synkronisering och minimal boilerplate. UI Automator är lämpligt för scenarier där interaktion med systemet, webbläsaren eller flera applikationer krävs.
| Kriterium | UI Automator | Espresso |
|---|---|---|
| Område | Hela enheten, flera applikationer | En applikation |
| Synkronisering | Manuell (wait, sleep) | Automatisk (Idling Resource) |
| Hastighet | Långsammare (åtkomst via tjänst) | Snabbare (fungerar inom processen) |
| System UI | Stödjer (Notifications, Quick Settings) | Stödjer inte |
| Söknoggrannhet | UiSelector baserat på attribut | ViewMatchers baserat på typ och hierarki |
| Stabilitet | Lägre (beroende av timing) | Högre (automatisk väntan) |
I praktiken används dessa ramverk ofta tillsammans: Espresso täcker UI-testerna för huvudapplikationen med hög stabilitet, och UI Automator kopplas in för scenarier som går utanför applikationens gränser — OAuth-inloggning, systembehörigheter, arbete med Share Intent. Denna kombination ger maximal UI-täckning med minimala underhållskostnader för tester.
Anslutning av UI Automator görs genom att lägga till ett beroende i build.gradle. Ramverket är en del av AndroidX Test och kräver inga extra behörigheter i manifestet — åtkomst till Accessibility Service konfigureras automatiskt när det instrumentella testet startar.
Den minimala konfigurationen inkluderar artefakten uiautomator och den vanliga testköraren AndroidJUnitRunner. UI Automator-tester placeras i katalogen src/androidTest och körs på en emulator eller fysisk enhet med 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")
}
För att få en UiDevice-instans används InstrumentationRegistry.getInstrumentation(). UiDevice bör skapas en gång i setUp()-metoden och återanvändas i alla tester i klassen för att spara enhetsresurser. Det är viktigt att notera att UiDevice inte är trådsäkert — alla operationer måste utföras i en enda tråd i testmetoden. Att skapa en ny UiDevice i varje test leder till overhead och långsammare exekvering. Det rekommenderas att skapa UiDevice en gång i beforeClass-metoden och återanvända den för alla tester i testklassen.
Till skillnad från Espresso har UI Automator ingen automatisk synkronisering. För att vänta på att element ska visas används metoden UiDevice.wait(condition, timeout) med objektet Until: Until.findObject(selector), Until.hasObject(selector), Until.gone(selector). Utan korrekt väntan blir tester instabila på grund av race condition — elementet kanske inte hinner visas på skärmen vid söktillfället. Det rekommenderas att ställa in en timeout på minst 3-5 sekunder för stabilitet.
Vanliga frågor
UI Automator fungerar på Accessibility Service-nivån och kan interagera med alla applikationer. Espresso fungerar inom en applikations process och använder automatisk synkronisering med UI-tråden. UI Automator är bättre för tvär-applikationella scenarier, Espresso — för stabila tester av en applikation.
Ja, UI Automator fungerar på alla enheter med Android API 18+. Det kräver ingen root-åtkomst — den vanliga Accessibility Service används, som aktiveras via Instrumentation vid teststart.
UI Automator använder Accessibility Service för att få det fullständiga UI-komponentträdet för den aktuella skärmen. Sedan går UiSelector igenom detta träd och hittar element baserat på givna kriterier: text, klass, ID, content-description eller en kombination av dessa.
Ja, metoden UiDevice.takeScreenshot(storePath) gör det möjligt att ta en skärmbild av den aktuella skärmen och spara den i en fil. Detta är användbart för felsökning: när ett test misslyckas kan skärmbilden sparas och skärmens tillstånd analyseras.
UI Automator har ingen automatisk synkronisering, därför är tester känsliga för timing. Om en animation inte har slutförts eller en View inte har hunnit renderas, kanske findObject inte hittar elementet. Lösning — använd UiDevice.wait() med tillräcklig timeout.
Sammanfattning
UI Automator-verktygssatsen täcker alla viktiga tvär-applikationella testscenarier och är standarden för Android-automatisering på systemnivå.
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också