UI-testing met Espresso
Schrijf geautomatiseerde UI-tests met Espresso. Zoek views met onView(), voer interacties uit met perform(), controleer de status met check() en test interacties met RecyclerView.
UI-testing met Espresso is een gratis Android Academy-les op CoddyKit. Dit is les 3 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Android Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Android Academy bevat in totaal 4 lessen.
Wat is Espresso?
Espresso is het officiële framework van Android voor het testen van gebruikersinterfaces. Hiermee schrijf je tests die met de gebruikersinterface van je app werken — op knoppen tikken, tekst typen, door lijsten scrollen — en controleert wat er op het scherm wordt weergegeven.
Espresso wordt uitgevoerd op een apparaat of emulator (een geïnstrumenteerde test) en synchroniseert automatisch met de UI-thread — er zijn geen onbetrouwbare aanroepen van sleep() nodig.
Instellen
Espresso maakt deel uit van de Android-toolkit voor testen. Voeg deze afhankelijkheden toe aan app/build.gradle:
// app/build.gradle:
android {
defaultConfig {
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
}
dependencies {
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.5.1' // RecyclerView
}ActivityScenarioRule
Gebruik ActivityScenarioRule om vóór elke test een Activity te starten en deze daarna te sluiten:
@RunWith(AndroidJUnit4::class)
class LoginActivityTest {
@get:Rule
val activityRule = ActivityScenarioRule(LoginActivity::class.java)
@Test
fun `login button is displayed`() {
onView(withId(R.id.btnLogin))
.check(matches(isDisplayed()))
}
}onView() en ViewMatchers
onView(matcher) zoekt een view in de huidige hiërarchie. Combineer matchers voor meer nauwkeurigheid:
// Match by ID:
onView(withId(R.id.tvTitle))
// Match by text:
onView(withText("Submit"))
// Match by content description (for accessibility):
onView(withContentDescription("Close dialog"))
// Combine matchers:
onView(allOf(withId(R.id.btnSave), isEnabled()))
// Inside a specific parent:
onView(withId(R.id.btnSave)).inRoot(isDialog())ViewActions — werken met views
Voer na het vinden van een view een actie uit met .perform():
// Tap a button:
onView(withId(R.id.btnLogin)).perform(click())
// Type into an EditText:
onView(withId(R.id.etEmail))
.perform(typeText("alice@example.com"), closeSoftKeyboard())
// Clear text and retype:
onView(withId(R.id.etPassword))
.perform(clearText(), typeText("secret123"), closeSoftKeyboard())
// Scroll to a view:
onView(withId(R.id.btnSubmit)).perform(scrollTo(), click())
// Long press:
onView(withId(R.id.ivImage)).perform(longClick())ViewAssertions — toestand controleren
Controleer wat er op het scherm wordt weergegeven met .check():
// View is displayed:
onView(withId(R.id.tvError)).check(matches(isDisplayed()))
// View has specific text:
onView(withId(R.id.tvTitle)).check(matches(withText("Welcome!")))
// View is not displayed (GONE or INVISIBLE):
onView(withId(R.id.progressBar)).check(matches(not(isDisplayed())))
// View is enabled:
onView(withId(R.id.btnSave)).check(matches(isEnabled()))
// View does not exist:
onView(withId(R.id.tvError)).check(doesNotExist())Volledige inlogtest
Een volledige test die inloggegevens typt en op inloggen tikt:
@Test
fun `successful login shows home screen`() {
// Type email
onView(withId(R.id.etEmail))
.perform(typeText("alice@example.com"), closeSoftKeyboard())
// Type password
onView(withId(R.id.etPassword))
.perform(typeText("password123"), closeSoftKeyboard())
// Tap login button
onView(withId(R.id.btnLogin)).perform(click())
// Assert welcome message is shown
onView(withId(R.id.tvWelcome))
.check(matches(withText("Welcome, Alice!")))
}RecyclerView testen
Gebruik RecyclerViewActions uit espresso-contrib om met lijstitems te werken:
import androidx.test.espresso.contrib.RecyclerViewActions
@Test
fun `clicking item opens detail screen`() {
// Scroll to position 5 and click:
onView(withId(R.id.recyclerView))
.perform(RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>(
5, click()
))
// Assert detail screen is shown:
onView(withId(R.id.tvDetailTitle)).check(matches(isDisplayed()))
}Invoervalidatie testen
Controleer of foutmeldingen verschijnen wanneer de invoer ongeldig is:
@Test
fun `empty email shows error message`() {
// Leave email blank, tap login
onView(withId(R.id.btnLogin)).perform(click())
// Assert error is shown
onView(withId(R.id.tilEmail))
.check(matches(hasDescendant(withText("Email is required"))))
}
@Test
fun `short password shows error`() {
onView(withId(R.id.etPassword))
.perform(typeText("123"), closeSoftKeyboard())
onView(withId(R.id.btnLogin)).perform(click())
onView(withId(R.id.tilPassword))
.check(matches(hasDescendant(withText("Minimum 6 characters"))))
}Inactieve bronnen
Espresso wacht automatisch tot de UI-thread inactief is, maar niet op netwerkaanroepen of coroutines. Gebruik IdlingResource om Espresso te laten wachten op je asynchrone werk:
// CountingIdlingResource: increment before async work, decrement when done
val idlingResource = CountingIdlingResource("NetworkCall")
// In your ViewModel/Repository:
idlingResource.increment()
viewModelScope.launch {
loadData()
idlingResource.decrement()
}
// In test setUp:
@Before
fun setUp() {
IdlingRegistry.getInstance().register(idlingResource)
}
@After
fun tearDown() {
IdlingRegistry.getInstance().unregister(idlingResource)
}Espresso-tests uitvoeren
Voer geïnstrumenteerde tests uit op een verbonden apparaat of emulator:
- In Android Studio: klik met de rechtermuisknop op een testklasse → Uitvoeren
- Via de terminal:
./gradlew connectedAndroidTest - Resultaten verschijnen in
app/build/reports/androidTests/
Gebruik Android Emulator API 28+ voor stabiele, snelle testruns. Schakel animaties uit in de ontwikkelaarsinstellingen om instabiele tests te voorkomen.
Snelle controle
Wat is het juiste Espresso-patroon om een view te vinden en de tekst ervan te controleren?
Samenvatting: de gebruikersinterface testen met Espresso
Geautomatiseerd testen van de gebruikersinterface vangt regressies op voordat gebruikers ze tegenkomen:
onView(matcher)— een view zoeken.perform(action)— tikken, typen, scrollen.check(matches(...))— zichtbaarheid, tekst en toestand controlerenRecyclerViewActionsvoor interacties met lijstenIdlingResourcevoor asynchrone bewerkingen- Schakel systeemanimaties uit om instabiele tests te voorkomen
Volgende: debug en profileer je app als een professional.
Leer Kotlin met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 36
- Lessen
- 152
Veelgestelde vragen
Is de les “UI-testing met Espresso” gratis?
Ja — je kunt hier op het web alle 3 lessen van het leerpad Android Academy, waaronder “UI-testing met Espresso”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Android Academy bevat in totaal 4 lessen.
Wat leer ik in “UI-testing met Espresso”?
Schrijf geautomatiseerde UI-tests met Espresso. Zoek views met onView(), voer interacties uit met perform(), controleer de status met check() en test interacties met RecyclerView. Je oefent met Android Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Android Academy te beginnen?
Ervaring vooraf is niet nodig. Android Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.
Hoe lang duurt de les “UI-testing met Espresso”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Android Academy?
Ja. Elke les over Android Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Unit testing met JUnit
- Mocking met Mockito
- UI-testing met Espresso
- Debugging en profiling