0Pricing
Android Academy · Lekcja

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 stanu
  • RecyclerViewActions do interakcji z listami
  • IdlingResource do 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

  1. Testy jednostkowe z JUnit
  2. Mockowanie za pomocą Mockito
  3. Testowanie interfejsu z Espresso
  4. Debugowanie i profilowanie
← Powrót do Android Academy