Espresso-Intents to rozszerzenie Espresso, które umożliwia weryfikację i podstawianie intencji wysyłanych przez testowaną aplikację. Jest to biblioteka podobna do Mockito, ale przeznaczona do intencji Androida.
Jeśli aplikacja przekazuje funkcje innym aplikacjom lub platformie, możesz użyć Espresso-Intents, aby skupić się na logice własnej aplikacji, zakładając, że inne aplikacje lub platforma będą działać prawidłowo. Za pomocą Espresso-Intents możesz dopasowywać i weryfikować wychodzące intencje, a nawet podawać odpowiedzi zastępcze zamiast rzeczywistych odpowiedzi na intencje.
Uwzględnianie Espresso-Intents w projekcie
W pliku app/build.gradle
aplikacji dodaj ten wiersz wewnątrz
dependencies
:
Groovy
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.6.1'
Kotlin
androidTestImplementation('androidx.test.espresso:espresso-intents:3.6.1')
Espresso-Intents jest zgodny tylko z Espresso w wersji 2.1 lub nowszej oraz z bibliotekami testowymi Androida w wersji 0.3 lub nowszej, więc pamiętaj, aby zaktualizować również te wiersze:
Groovy
androidTestImplementation 'androidx.test:runner:1.6.1' androidTestImplementation 'androidx.test:rules:1.6.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
Kotlin
androidTestImplementation('androidx.test:runner:1.6.1') androidTestImplementation('androidx.test:rules:1.6.1') androidTestImplementation('androidx.test.espresso:espresso-core:3.6.1')
Pisanie reguł testowych
Zanim napiszesz test Espresso-Intents, skonfiguruj IntentsTestRule
. Jest to rozszerzenie klasy ActivityTestRule
, które ułatwia korzystanie z interfejsów Espresso-Intents API w funkcjonalnych testach interfejsu. Klasa IntentsTestRule
inicjuje Espresso-Intents przed każdym testem oznaczonym adnotacją @Test
i zwalnia Espresso-Intents po każdym uruchomieniu testu.
Poniższy fragment kodu to przykład IntentsTestRule
:
Kotlin
@get:Rule val intentsTestRule = IntentsTestRule(MyActivity::class.java)
Java
@Rule public IntentsTestRule<MyActivity> intentsTestRule = new IntentsTestRule<>(MyActivity.class);
Dopasowanie
Biblioteka Espresso-Intents umożliwia przechwytywanie wychodzących intencji na podstawie określonych kryteriów dopasowania, które są definiowane za pomocą narzędzi Hamcrest Matchers. Biblioteka Hamcrest umożliwia:
- Użyj istniejącego narzędzia do dopasowywania intencji: najprostsza opcja, która prawie zawsze powinna być preferowana.
- Wdrożenie własnego narzędzia do dopasowywania intencji: najbardziej elastyczna opcja. Więcej informacji znajdziesz w sekcji „Writing custom matchers” (Pisanie niestandardowych dopasowań) w samouczku Hamcrest.
Espresso-Intents udostępnia metody intended()
i intending()
do odpowiednio weryfikowania i podstawiania intencji. Obie przyjmują jako argument obiekt Hamcrest Matcher<Intent>
.
Poniższy fragment kodu pokazuje weryfikację intencji, która korzysta z dotychczasowych narzędzi do dopasowywania intencji, aby dopasować wychodzącą intencję, która uruchamia przeglądarkę:
Kotlin
assertThat(intent).hasAction(Intent.ACTION_VIEW) assertThat(intent).categories().containsExactly(Intent.CATEGORY_BROWSABLE) assertThat(intent).hasData(Uri.parse("www.google.com")) assertThat(intent).extras().containsKey("key1") assertThat(intent).extras().string("key1").isEqualTo("value1") assertThat(intent).extras().containsKey("key2") assertThat(intent).extras().string("key2").isEqualTo("value2")
Java
assertThat(intent).hasAction(Intent.ACTION_VIEW); assertThat(intent).categories().containsExactly(Intent.CATEGORY_BROWSABLE); assertThat(intent).hasData(Uri.parse("www.google.com")); assertThat(intent).extras().containsKey("key1"); assertThat(intent).extras().string("key1").isEqualTo("value1"); assertThat(intent).extras().containsKey("key2"); assertThat(intent).extras().string("key2").isEqualTo("value2");
Weryfikowanie intencji
Espresso-Intents rejestruje wszystkie intencje, które próbują uruchomić działania z testowanej aplikacji. Korzystając z metody intended()
, która jest podobna do metody Mockito.verify()
, możesz potwierdzić, że dana intencja została zarejestrowana. Espresso-Intents nie zastępuje jednak odpowiedzi na intencje, chyba że wyraźnie skonfigurujesz tę funkcję.
Poniższy fragment kodu to przykładowy test, który weryfikuje wychodzący zamiar uruchamiający zewnętrzną aktywność „phone”, ale nie zastępuje odpowiedzi na niego:
Kotlin
@Test fun validateIntentSentToPackage() { // User action that results in an external "phone" activity being launched. user.clickOnView(system.getView(R.id.callButton)) // Using a canned RecordedIntentMatcher to validate that an intent resolving // to the "phone" activity has been sent. intended(toPackage("com.android.phone")) }
Java
@Test public void validateIntentSentToPackage() { // User action that results in an external "phone" activity being launched. user.clickOnView(system.getView(R.id.callButton)); // Using a canned RecordedIntentMatcher to validate that an intent resolving // to the "phone" activity has been sent. intended(toPackage("com.android.phone")); }
Stubbing
Korzystając z metody intending()
, która jest podobna do Mockito.when()
, możesz podać odpowiedź zastępczą dla działań uruchamianych za pomocą startActivityForResult()
. Jest to szczególnie przydatne w przypadku działań zewnętrznych, ponieważ nie możesz manipulować interfejsem użytkownika działania zewnętrznego ani kontrolować wartości ActivityResult
zwracanej do testowanego działania.
Te fragmenty kodu implementują przykładowy test activityResult_DisplaysContactsPhoneNumber()
, który sprawdza, czy po uruchomieniu przez użytkownika w testowanej aplikacji aktywności „kontakt” wyświetla się numer telefonu kontaktu:
Tworzy wynik, który ma być zwracany po uruchomieniu określonej aktywności. Przykładowy test przechwytuje wszystkie intencje wysyłane do „kontaktów” i zastępuje ich odpowiedzi prawidłowym
ActivityResult
, używając kodu wynikuRESULT_OK
.Kotlin
val resultData = Intent() val phoneNumber = "123-345-6789" resultData.putExtra("phone", phoneNumber) val result = Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)
Java
Intent resultData = new Intent(); String phoneNumber = "123-345-6789"; resultData.putExtra("phone", phoneNumber); ActivityResult result = new ActivityResult(Activity.RESULT_OK, resultData);
Poinstruuj Espresso, aby w odpowiedzi na wszystkie wywołania intencji „contacts” zwracał obiekt wyniku zastępczego:
Kotlin
intending(toPackage("com.android.contacts")).respondWith(result)
Java
intending(toPackage("com.android.contacts")).respondWith(result);
Sprawdź, czy działanie użyte do uruchomienia aktywności daje oczekiwany wynik. W tym przypadku test sprawdza, czy po uruchomieniu „aktywności kontaktów” zwracany i wyświetlany jest numer telefonu „123-345-6789”:
Kotlin
onView(withId(R.id.pickButton)).perform(click()) onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber)))
Java
onView(withId(R.id.pickButton)).perform(click()); onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber)));
Oto pełny activityResult_DisplaysContactsPhoneNumber()
test:
Kotlin
@Test fun activityResult_DisplaysContactsPhoneNumber() { // Build the result to return when the activity is launched. val resultData = Intent() val phoneNumber = "123-345-6789" resultData.putExtra("phone", phoneNumber) val result = Instrumentation.ActivityResult(Activity.RESULT_OK, resultData) // Set up result stubbing when an intent sent to "contacts" is seen. intending(toPackage("com.android.contacts")).respondWith(result) // User action that results in "contacts" activity being launched. // Launching activity expects phoneNumber to be returned and displayed. onView(withId(R.id.pickButton)).perform(click()) // Assert that the data we set up above is shown. onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber))) }
Java
@Test public void activityResult_DisplaysContactsPhoneNumber() { // Build the result to return when the activity is launched. Intent resultData = new Intent(); String phoneNumber = "123-345-6789"; resultData.putExtra("phone", phoneNumber); ActivityResult result = new ActivityResult(Activity.RESULT_OK, resultData); // Set up result stubbing when an intent sent to "contacts" is seen. intending(toPackage("com.android.contacts")).respondWith(result); // User action that results in "contacts" activity being launched. // Launching activity expects phoneNumber to be returned and displayed. onView(withId(R.id.pickButton)).perform(click()); // Assert that the data we set up above is shown. onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber))); }
Dodatkowe materiały
Więcej informacji o używaniu Espresso-Intents w testach Androida znajdziesz w tych materiałach.
Próbki
- IntentsBasicSample:
Podstawowe użycie
intended()
iintending()
. - IntentsAdvancedSample: Symuluje pobieranie przez użytkownika mapy bitowej za pomocą aparatu.