Testování UI ověřuje správnost zobrazení a interakce prvků uživatelského rozhraní mobilní aplikace — tlačítek, textových polí, seznamů a navigačních komponent. Na rozdíl od jednotkových testů, které ověřují business logiku, UI testy emulují akce uživatele: dotyky, tažení, zadávání textu a kontrolují reakci rozhraní. Podle výzkumu Android Developers, 2024, testování UI pokrývá 70% kritických uživatelských scénářů a umožňuje odhalit defekty rozvržení, které nejsou přístupné logickým kontrolám.
Hlavní body
Testování UI je typ automatizované kontroly, při které testovací kód interaguje s grafickým rozhraním aplikace stejně, jako by to dělal skutečný uživatel. Test najde na obrazovce prvek — tlačítko, textové pole, seznam — provede na něm akci a zkontroluje očekávanou reakci rozhraní. Například po zadání nesprávného hesla UI test zkontroluje, zda se na obrazovce objevila chybová zpráva se správným textem.
Hlavní rozdíl mezi UI testy a jinými typy automatizace je v tom, že pracují prostřednictvím vrstvy Accessibility operačního systému, nikoli prostřednictvím interních API aplikace. To znamená, že UI testy vidí rozhraní přesně tak, jako uživatel a systém čtení obrazovky. Díky tomu UI testy kontrolují nejen funkčnost, ale i přístupnost prvků — soulad s požadavky WCAG.
Podle průzkumu JetBrains Developer Ecosystem 2023 používá 58% mobilních týmů UI testy ve svém CI/CD pipeline. Průměrné pokrytí UI testy v komerčních projektech je 30–40% obrazovek aplikace. Projekty s UI testy dostávají o 25% méně negativních recenzí v obchodech s aplikacemi souvisejících s pády rozhraní.
Hlavní rozdíl mezi UI testy a jednotkovými testy je úroveň abstrakce. Jednotkové testy pracují s jednotlivými třídami a funkcemi, izolovanými od frameworku Android nebo iOS. Provádějí se na JVM (pro Android) bez spuštění emulátoru a trvají milisekundy. UI testy běží na skutečném zařízení nebo emulátoru, interagují se systémovými službami a vyžadují sekundy nebo minuty na jeden scénář.
Liší se také cílové publikum testů. UI testy kontrolují komplexní uživatelské scénáře — registraci, zadání objednávky, vyhledávání. Jednotkové testy pokrývají business logiku: výpočty, validaci, transformaci dat. UI test nekontroluje správnost výpočtu daně — kontroluje, zda je konečná částka zobrazena na obrazovce. Samotný výpočet je ověřen jednotkovým testem.
Podle Google Testing Blog (2020) by optimální poměr testů v projektu měl následovat pravidlo testovací pyramidy: 70% jednotkových testů, 20% integračních testů a 10% UI testů. Porušení tohoto poměru ve prospěch UI testů vede k prodloužení doby provádění a křehkosti testovací sady, protože UI testy jsou citlivé na změny v rozvržení obrazovek.
Pro Android je dominantním frameworkem Espresso — knihovna od Google zabudovaná do AndroidX Test. Espresso se automaticky synchronizuje s vláknem UI a čeká na dokončení animací a úloh na pozadí před provedením další kontroly. Pro Jetpack Compose se používá rozšíření Compose UI Test, které pracuje prostřednictvím sémantických uzlů místo tradičních identifikátorů zobrazení.
Pro iOS je hlavním nástrojem XCUITest, který je součástí Xcode. Testy se píší v Swift a používají identifikátory Accessibility pro nalezení prvků. XCUITest podporuje nahrávání testů pomocí funkce record a integraci s CI systémy přes xcodebuild. Pro multiplatformní projekty se používá Appium, založený na protokolu WebDriver, který umožňuje spouštět stejné testy na Android a iOS s minimálními změnami v kódu.
Espresso pracuje s tradičním systémem View prostřednictvím onView a identifikátorů zdrojů id. Compose UI Test používá sémantickou vrstvu, což činí testy méně závislými na hierarchii zobrazení. Například hledání tlačítka v Espresso: onView(withId(R.id.submit)), v Compose: onNodeWithTag(„submit”). Compose testy automaticky zpracovávají rekompozici a nevyžadují explicitní čekání na nečinný stav.
XCUITest používá XCUIApplication jako vstupní bod. Každý prvek rozhraní se hledá prostřednictvím vlastností Accessibility: accessibilityIdentifier pro programový přístup a accessibilityLabel pro VoiceOver. Framework podporuje nahrávání testů pomocí funkce record v Xcode — vývojář provádí akce na simulátoru a Xcode generuje testovací kód. Hotové testy se spouštějí přes xcodebuild test.
Appium je založen na protokolu WebDriver a podporuje libovolný jazyk: Java, Python, JavaScript. Pro hledání prvků se používají strategie id, xpath, class name a accessibility id. Appium vyžaduje instalaci serveru a konfiguraci Desired Capabilities — platformName, deviceName, appPackage. Alternativou je Maestro, který používá YAML scénáře a nevyžaduje kompilaci testovacího kódu.
Podívejme se na UI testy pro stejný scénář — přihlášení do aplikace — ve třech různých frameworkových: Espresso pro Android, XCUITest pro iOS a Appium pro multiplatformní přístup. Scénář: zadejte uživatelské jméno a heslo, stiskněte tlačítko přihlášení, zkontrolujte zobrazení uvítací zprávy.
Test v Espresso používá onView pro nalezení prvku podle identifikátoru a perform pro provedení akce. Metoda check s matcherem isDisplayed potvrzuje, že je prvek viditelný na obrazovce.
@RunWith(AndroidJUnit4::class)
class LoginUiTest {
@Rule
@JvmField
val composeTestRule = createComposeRule()
@Test
fun login_withValidCredentials_showsWelcome() {
composeTestRule
.onNodeWithTag("emailField")
.performTextInput("user@example.com")
composeTestRule
.onNodeWithTag("passwordField")
.performTextInput("secret123")
composeTestRule
.onNodeWithTag("loginButton")
.performClick()
composeTestRule
.onNodeWithText("Vítejte, Uživateli!")
.assertIsDisplayed()
}
}
XCUITest používá XCUIApplication pro přístup k prvkům rozhraní prostřednictvím identifikátorů Accessibility. Metody tap() a exists zajišťují interakci a kontrolu.
class LoginUITests: XCTestCase {
let app = XCUIApplication()
override func setUp() {
continueAfterFailure = false
app.launch()
}
func testLogin_withValidCredentials_showsWelcome() {
app.textFields["emailField"].tap()
app.textFields["emailField"].typeText("uzivatel@example.com")
app.secureTextFields["passwordField"].tap()
app.secureTextFields["passwordField"].typeText("tajne123")
app.buttons["loginButton"].tap()
XCTAssertTrue(app.staticTexts["Welcome, User!"].exists)
}
}
První zásada — používejte identifikátory Accessibility místo textových štítků pro hledání prvků. Text tlačítka se může změnit při lokalizaci, zatímco identifikátor zůstane stabilní. V Android je to vlastnost contentDescription, v iOS — accessibilityIdentifier. Tento přístup činí testy nezávislými na jazyce rozhraní a snížuje náklady na údržbu při změně copywritingu.
Vyhýbejte se sleep() a pevným zpožděním — používejte vestavěné mechanizmy čekání frameworku. Espresso automaticky čeká na dokončení animací a úloh na pozadí. XCUITest poskytuje XCTAssertTrue s timeoutem. Explicitní pauzy zpomalují testy a činí je méně stabilními, zejména na pomalých zařízeních v CI prostředí.
Seskupujte testy podle kritičnosti: smoke testy (3–5 klíčových scénářů) se spouštějí při každém commitu, kompletní sada UI testů — před vydáním. Podle Google Testing Blog (2022) UI testy, které trvají déle než 30 minut v CI, snižují frekvenci spouštění o 40%, což snižuje jejich efektivitu jako nástroje pro včasnou detekci regresí.
UI testy mají řadu omezení. Citlivost na změny rozvržení: změna identifikátoru, hierarchie nebo typu prvku rozbije test i při nezměněné funkčnosti. Řešení — použití vzoru Page Object, který centralizuje selektery prvků v samostatných třídách. Při změně rozvržení se opraví jeden soubor Page Object, nikoli desítky testů.
Doba provádění: spuštění na skutečném zařízení nebo emulátoru trvá 10–50krát déle než jednotkový test. Řešení — paralelní spouštění UI testů na několika zařízeních prostřednictvím Firebase Test Lab nebo AWS Device Farm. Nestabilita (flakiness) — častý problém CI spuštění způsobený animacemi, síťovým zpožděním nebo stavem emulátoru. Pro boj s flakiness se používá automatický restart neúspěšných testů a analýza stability každého testovacího scénáře.
Často kladené otázky
Pro běžnou obrazovku stačí 3–5 UI testů: happy path, validace chyb, prázdný stav, změna orientace a kontrola Accessibility. Složité obrazovky s mnoha stavy — formuláře objednávky, nastavení — mohou vyžadovat 10–15 testů pro úplné pokrytí klíčových scénářů.
Ano, Appium a Maestro umožňují spouštět stejné scénáře na obou platformách. Nicméně nativní frameworky — Espresso a XCUITest — poskytují lepší stabilitu, rychlost a přístup k možnostem platformy, které nejsou dostupné přes WebDriver proxy.
Pro Compose se používá knihovna Compose UI Test se sémantickými matchery: onNodeWithText, onNodeWithTag, onNodeWithContentDescription. Sémantická vrstva Compose abstrahuje hierarchii zobrazení, což činí testy méně křehkými ve srovnání s tradičním Espresso pro systém View.
Základní spouštění UI testů se provádí na emulátorech v CI — je rychlé a levné. Konečnou verifikaci před vydáním se doporučuje provádět na fyzických zařízeních prostřednictvím Firebase Test Lab, aby se zohlednily vlastnosti reálného hardwaru: různá rozlišení, verze OS a výkon.
Používejte paralelní spouštění na více zařízeních, vypněte animace na emulátoru přes Developer Options, postavte modulární architekturu testů a spouštějte smoke sadu při každém commitu a úplný regresní běh podle plánu nebo před vydáním.
Shrnutí
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é