Testowanie interfejsu z Espresso
Pisz automatyczne testy interfejsu za pomocą Espresso. Wyszukuj widoki przez onView(), wchodź z nimi w interakcje za pomocą perform(), sprawdzaj stan przez check() i testuj interakcje z RecyclerView.
Testowanie interfejsu z Espresso to bezpłatna lekcja Android Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Android Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Android Academy zawiera 4 lekcji w sumie.
Czym jest Espresso?
Espresso to oficjalny framework Androida do testowania interfejsu użytkownika. Umożliwia pisanie testów, które wchodzą w interakcję z interfejsem aplikacji — klikają przyciski, wpisują tekst, przewijają listy — i sprawdzają, co jest wyświetlane na ekranie.
Espresso działa na urządzeniu lub emulatorze (jako test instrumentacyjny) i automatycznie synchronizuje się z wątkiem interfejsu użytkownika — nie trzeba używać zawodnych wywołań sleep().
Konfiguracja
Espresso jest częścią zestawu narzędzi do testowania Androida. Dodaj te zależności do 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
Użyj ActivityScenarioRule, aby uruchamiać Activity przed każdym testem i zamykać je po jego zakończeniu:
@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() i ViewMatchers
onView(matcher) wyszukuje widok w bieżącej hierarchii. Połącz matchery, aby precyzyjniej określić widok:
// 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 — interakcja z widokami
Po znalezieniu widoku wykonaj działanie za pomocą .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 — sprawdzanie stanu
Sprawdź, co jest wyświetlane na ekranie, za pomocą .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())Kompletny test logowania
Pełny test, który wpisuje dane logowania i klika przycisk logowania:
@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!")))
}Testowanie RecyclerView
Użyj RecyclerViewActions z espresso-contrib, aby wchodzić w interakcję z elementami listy:
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()))
}Testowanie walidacji danych wejściowych
Sprawdź, czy komunikaty o błędach pojawiają się, gdy dane wejściowe są nieprawidłowe:
@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"))))
}Idling Resources
Espresso automatycznie czeka, aż wątek interfejsu użytkownika będzie bezczynny, ale nie czeka na wywołania sieciowe ani korutyny. Użyj IdlingResource, aby poinformować Espresso, że ma zaczekać na zakończenie pracy asynchronicznej:
// 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)
}Uruchamianie testów Espresso
Uruchamiaj testy instrumentacyjne na podłączonym urządzeniu lub emulatorze:
- W Android Studio: kliknij klasę testową prawym przyciskiem myszy → Run
- W terminalu:
./gradlew connectedAndroidTest - Wyniki pojawią się w
app/build/reports/androidTests/
Używaj emulatora Androida z API 28 lub nowszym, aby testy działały stabilnie i szybko. Wyłącz animacje w ustawieniach deweloperskich, aby zapobiec niestabilności testów.
Szybki test
Jaki wzorzec Espresso prawidłowo wyszukuje widok i sprawdza jego tekst?
Podsumowanie: testowanie interfejsu użytkownika z Espresso
Automatyczne testy interfejsu użytkownika wykrywają regresje, zanim zrobią to użytkownicy:
onView(matcher)— wyszukiwanie widoku.perform(action)— klikanie, wpisywanie tekstu i przewijanie.check(matches(...))— sprawdzanie widoczności, tekstu i stanuRecyclerViewActionsdo interakcji z listamiIdlingResourcedo operacji asynchronicznych- Wyłącz animacje systemowe, aby zapobiec niestabilności testów
Następnie: debugowanie i profilowanie aplikacji jak profesjonalista.
Często zadawane pytania
Czy lekcja „Testowanie interfejsu z Espresso” jest bezpłatna?
Tak — pełny tekst „Testowanie interfejsu z Espresso” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Android Academy, przejdź na CoddyKit PRO. Kurs Android Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Testowanie interfejsu z Espresso”?
Pisz automatyczne testy interfejsu za pomocą Espresso. Wyszukuj widoki przez onView(), wchodź z nimi w interakcje za pomocą perform(), sprawdzaj stan przez check() i testuj interakcje z RecyclerView. Ćwiczysz Android Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Android Academy?
Nie wymagamy żadnego doświadczenia. Android Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Testowanie interfejsu z Espresso”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Android Academy?
Tak. Każda lekcja Android Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Testy jednostkowe z JUnit
- Mockowanie za pomocą Mockito
- Testowanie interfejsu z Espresso
- Debugowanie i profilowanie