Espresso-Intents — это расширение для Espresso, которое позволяет проверять и заглушать намерения , отправляемые тестируемым приложением. Оно похоже на Mockito , но для Android Intents.
Если ваше приложение делегирует функции другим приложениям или платформе, вы можете использовать Espresso-Intents, чтобы сосредоточиться на логике своего приложения, предполагая, что другие приложения или платформа будут работать корректно. Espresso-Intents позволяет сопоставлять и проверять исходящие намерения или даже предоставлять заглушки вместо реальных ответов на намерения.
Включите Espresso-Intents в свой проект
В файле app/build.gradle
вашего приложения добавьте следующую строку в dependencies
:
Круто
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.6.1'
Котлин
androidTestImplementation('androidx.test.espresso:espresso-intents:3.6.1')
Espresso-Intents совместим только с библиотеками тестирования Android Espresso 2.1+ и версии 0.3+, поэтому обязательно обновите и эти строки:
Круто
androidTestImplementation 'androidx.test:runner:1.6.1' androidTestImplementation 'androidx.test:rules:1.6.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
Котлин
androidTestImplementation('androidx.test:runner:1.6.1') androidTestImplementation('androidx.test:rules:1.6.1') androidTestImplementation('androidx.test.espresso:espresso-core:3.6.1')
Напишите тестовые правила
Перед написанием теста Espresso-Intents настройте правило IntentsTestRule
. Это расширение класса ActivityTestRule
упрощает использование API Espresso-Intents в функциональных UI-тестах. Правило IntentsTestRule
инициализирует Espresso-Intents перед каждым тестом, аннотированным @Test
, и освобождает Espresso-Intents после каждого запуска теста.
Следующий фрагмент кода является примером IntentsTestRule
:
Котлин
@get:Rule val intentsTestRule = IntentsTestRule(MyActivity::class.java)
Ява
@Rule public IntentsTestRule<MyActivity> intentsTestRule = new IntentsTestRule<>(MyActivity.class);
Соответствовать
Espresso-Intents позволяет перехватывать исходящие намерения на основе определённых критериев соответствия, определяемых с помощью Hamcrest Matchers. Hamcrest позволяет:
- Использовать существующий сопоставитель намерений: самый простой вариант, который почти всегда следует выбирать.
- Реализуйте собственный сопоставитель намерений: самый гибкий вариант. Подробнее см. в разделе «Написание собственных сопоставителей» руководства Hamcrest .
Espresso-Intents предлагает методы intended()
и intending()
для проверки намерений и создания заглушек соответственно. Оба метода принимают в качестве аргумента объект Hamcrest Matcher<Intent>
.
В следующем фрагменте кода показана проверка намерений, которая использует существующие сопоставители намерений, соответствующие исходящему намерению, запускающему браузер:
Котлин
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")
Ява
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");
Проверить намерения
Espresso-Intents регистрирует все намерения, пытающиеся запустить действия из тестируемого приложения. Используя метод intended()
, аналогичный Mockito.verify()
, можно подтвердить, что заданное намерение было обнаружено. Однако Espresso-Intents не заглушает ответы на намерения, если только вы явно не настроите его соответствующим образом.
Следующий фрагмент кода представляет собой пример теста, который проверяет, но не блокирует ответы на исходящее намерение, запускающее внешнюю «телефонную» активность:
Котлин
@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")) }
Ява
@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")); }
Заделывание
Используя метод intending()
, аналогичный Mockito.when()
, вы можете предоставить ответ-заглушку для действий, запускаемых с помощью startActivityForResult()
. Это особенно полезно для внешних действий, поскольку вы не можете манипулировать пользовательским интерфейсом внешнего действия или контролировать ActivityResult
, возвращаемый тестируемому действию.
В следующих фрагментах кода реализован пример теста activityResult_DisplaysContactsPhoneNumber()
, который проверяет, что когда пользователь запускает действие «контакт» в тестируемом приложении, отображается номер телефона контакта:
Создайте результат, возвращаемый при запуске определённой активности. В примере теста перехватываются все намерения, отправленные контактам, и их ответы заглушаются корректным
ActivityResult
с кодом результатаRESULT_OK
Котлин
val resultData = Intent() val phoneNumber = "123-345-6789" resultData.putExtra("phone", phoneNumber) val result = Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)
Ява
Intent resultData = new Intent(); String phoneNumber = "123-345-6789"; resultData.putExtra("phone", phoneNumber); ActivityResult result = new ActivityResult(Activity.RESULT_OK, resultData);
Дайте Espresso указание предоставить объект-заглушку результата в ответ на все вызовы намерения «contacts»:
Котлин
intending(toPackage("com.android.contacts")).respondWith(result)
Ява
intending(toPackage("com.android.contacts")).respondWith(result);
Убедитесь, что действие, используемое для запуска активности, даёт ожидаемый результат-заглушку. В данном случае пример теста проверяет, что номер телефона «123-345-6789» возвращается и отображается при запуске активности «Контакты»:
Котлин
onView(withId(R.id.pickButton)).perform(click()) onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber)))
Ява
onView(withId(R.id.pickButton)).perform(click()); onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber)));
Вот полный тест activityResult_DisplaysContactsPhoneNumber()
:
Котлин
@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))) }
Ява
@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))); }
Дополнительные ресурсы
Дополнительную информацию об использовании Espresso-Intents в тестах Android можно найти в следующих ресурсах.
Образцы
- IntentsBasicSample : Базовое использование
intended()
иintending()
. - IntentsAdvancedSample : имитирует получение пользователем растрового изображения с помощью камеры.