Espresso-Web – это точка входа для работы с компонентами интерфейса Android WebView. Espresso-Web повторно использует атомы из популярного WebDriver API для проверки и контроля поведения WebView.
Когда использовать Espresso-Web
Используйте Espresso-Web для тестирования гибридных приложений, особенно интеграции нативных компонентов интерфейса приложения с компонентами интерфейса WebView. Вы можете использовать Espresso-Web API вместе с другими Espresso API, чтобы полностью взаимодействовать с веб-элементами внутри объектов WebView.
Если вам нужно протестировать только WebView, а не взаимодействие между WebView и нативными компонентами приложения, напишите общий веб-тест с помощью фреймворка, например WebDriver. Если вы используете фреймворк для веб-тестирования, вам не нужно использовать устройство Android или виртуальную машину Java, что делает ваши тесты более быстрыми и надежными. При этом Espresso-Web позволяет повторно использовать собственные атомы WebDriver, что дает большую гибкость, особенно при написании тестов, которые вы планируете запускать как для отдельных веб-приложений, так и для приложений, включающих пользовательский интерфейс Android.
Принцип работы
Как и в случае с методом onData() в Espresso, взаимодействие WebView состоит из нескольких атомов.
Взаимодействие с WebView осуществляется с помощью языка программирования Java и моста JavaScript. Поскольку при раскрытии данных из среды JavaScript нет риска возникновения состояния гонки (все, что Espresso видит на стороне Java, является изолированной копией), возврат данных из объектов Web.WebInteraction полностью поддерживается. Это позволяет проверять все данные, возвращаемые по запросу.
Что такое WebDriver Atom?
Фреймворк WebDriver использует атомы для поиска веб-элементов и программного управления ими. Атомы используются WebDriver для управления браузером. Атом концептуально похож на ViewAction – автономный блок, который выполняет действие в пользовательском интерфейсе. Вы можете использовать атомы с помощью списка определенных методов, таких как findElement() и getElement(), чтобы управлять браузером от лица пользователя. Однако если вы используете фреймворк WebDriver напрямую, атомы должны быть правильно организованы, что требует довольно подробной логики.
В Espresso классы Web и Web.WebInteraction оборачивают этот шаблонный код и обеспечивают взаимодействие с объектами WebView в стиле Espresso. Таким образом, в контексте WebView атомы используются вместо традиционных ViewMatchers и ViewActions Espresso.
В этом случае API выглядит довольно просто:
Kotlin
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion)
Java
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion);
Подробную информацию вы найдете в документации Selenium по атомам.
Как реализовать WebView
Чтобы использовать WebView в тестах приложения, следуйте инструкциям в разделах ниже.
Пакеты
Чтобы включить Espresso-Web в проект, выполните следующие действия:
- Откройте файл
build.gradleсвоего приложения. Обычно это не файлbuild.gradleверхнего уровня, аapp/build.gradle. Добавьте в dependencies следующую строку:
Яркий
androidTestImplementation 'androidx.test.espresso:espresso-web:3.6.1'
Kotlin
androidTestImplementation('androidx.test.espresso:espresso-web:3.6.1')
Espresso-Web совместим только с Espresso 2.2 или более поздней версии и версией 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'
Kotlin
androidTestImplementation('androidx.test:runner:1.6.1') androidTestImplementation('androidx.test:rules:1.6.1') androidTestImplementation('androidx.test.espresso:espresso-core:3.6.1')
Типичные сценарии использования API
Метод onWebView() – основная точка входа при работе с WebView на Android с помощью Espresso. Этот метод используется для выполнения тестов Espresso-Web, например:
Kotlin
onWebView() .withElement(findElement(Locator.ID, "link_2")) // similar to onView(withId(...)) .perform(webClick()) // Similar to perform(click()) // Similar to check(matches(...)) .check(webMatches(getCurrentUrl(), containsString("navigation_2.html")))
Java
onWebView() .withElement(findElement(Locator.ID, "link_2")) // similar to onView(withId(...)) .perform(webClick()) // Similar to perform(click()) // Similar to check(matches(...)) .check(webMatches(getCurrentUrl(), containsString("navigation_2.html")));
В этом примере Espresso-Web находит элемент DOM с идентификатором "link_2" и нажимает на него. Затем инструмент проверяет, отправляет ли компонент WebView GET-запрос, содержащий строку "navigation_2.html".
Поддержка JavaScript
При выполнении тестов система взаимодействует с WebView с помощью JavaScript. Поэтому для поддержки оценки JavaScript в тестируемом WebView должен быть включен JavaScript.
Вы можете принудительно включить JavaScript, вызвав forceJavascriptEnabled() как действие в тестируемом действии, как показано в следующем фрагменте кода.
@RunWith(AndroidJUnit4::class) class MyTestSuite { @get:Rule val activityScenarioRule = activityScenarioRule<MyWebViewActivity>() @Test fun testWebViewInteraction() { onWebView().forceJavascriptEnabled() } }
Распространенные взаимодействия на сайте
Вот примеры распространенных взаимодействий с объектами Web.WebInteraction:
-
withElement()ссылается на элемент DOM в WebView.Пример:
Kotlin
onWebView().withElement(findElement(Locator.ID, "teacher"))
Java
onWebView().withElement(findElement(Locator.ID, "teacher"));
-
withContextualElement()ссылается на элемент DOM в WebView относительно другого элемента DOM. Сначала вызовитеwithElement(), чтобы создать объектWeb.WebInteraction(элемент DOM).Пример:
Kotlin
.withElement(findElement(Locator.ID, "teacher")) .withContextualElement(findElement(Locator.ID, "person_name"))
Java
.withElement(findElement(Locator.ID, "teacher")) .withContextualElement(findElement(Locator.ID, "person_name"));
-
check()оценивает условие, чтобы убедиться, что оно разрешается вtrue.Пример:
Kotlin
onWebView() .withElement(findElement(Locator.ID, "teacher")) .withContextualElement(findElement(Locator.ID, "person_name")) .check(webMatches(getText(), containsString("Socrates")))
Java
onWebView() .withElement(findElement(Locator.ID, "teacher")) .withContextualElement(findElement(Locator.ID, "person_name")) .check(webMatches(getText(), containsString("Socrates")));
-
perform()выполняет действие в WebView, например нажимает на элемент.Пример:
Kotlin
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick())
Java
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick());
-
reset()возвращает WebView в исходное состояние. Это необходимо, когда предыдущее действие, например клик, приводит к изменению навигации, из-за которого объекты ElementReference и WindowReference становятся недоступными.Примечание. Хотя метод
reset()полезен при проверке многостраничных рабочих процессов, таких как отправка форм, обычно тесты должны быть ограничены по объему и сосредоточены на одной странице.Пример:
Kotlin
onWebView() .withElement(...) .perform(...) .reset()
Java
onWebView() .withElement(...) .perform(...) .reset();
Пример
В следующем примере проверяется, появляется ли текст, введенный в WebView, в другом элементе того же WebView после нажатия кнопки Отправить.
Kotlin
const val MACCHIATO = "Macchiato" @RunWith(AndroidJUnit4::class) class MyEspressoWebTestSuite { @Test fun typeTextInInput_clickButton_SubmitsForm() { // Create an intent that displays a web form. val webFormIntent = Intent() // ... // Lazily launch the Activity with a custom start Intent per test. ActivityScenario.launchActivity(webFormIntent) // Selects the WebView in your layout. If you have multiple WebView // objects, you can also use a matcher to select a given WebView, // onWebView(withId(R.id.web_view)). onWebView() // Find the input element by ID. .withElement(findElement(Locator.ID, "text_input")) // Clear previous input and enter new text into the input element. .perform(clearElement()) .perform(DriverAtoms.webKeys(MACCHIATO)) // Find the "Submit" button and simulate a click using JavaScript. .withElement(findElement(Locator.ID, "submitBtn")) .perform(webClick()) // Find the response element by ID, and verify that it contains the // entered text. .withElement(findElement(Locator.ID, "response")) .check(webMatches(getText(), containsString(MACCHIATO))) } }
Java
public static final String MACCHIATO = "Macchiato"; @Test public void typeTextInInput_clickButton_SubmitsForm() { // Create an intent that displays a web form. Intent webFormIntent = new Intent(); // ... // Lazily launch the Activity with a custom start Intent per test. ActivityScenario.launchActivity(webFormIntent); // Selects the WebView in your layout. If you have multiple WebView objects, // you can also use a matcher to select a given WebView, // onWebView(withId(R.id.web_view)). onWebView() // Find the input element by ID. .withElement(findElement(Locator.ID, "text_input")) // Clear previous input and enter new text into the input element. .perform(clearElement()) .perform(DriverAtoms.webKeys(MACCHIATO)) // Find the "Submit" button and simulate a click using JavaScript. .withElement(findElement(Locator.ID, "submitBtn")) .perform(webClick()) // Find the response element by ID, and verify that it contains the // entered text. .withElement(findElement(Locator.ID, "response")) .check(webMatches(getText(), containsString(MACCHIATO))); }
Дополнительные ресурсы
Дополнительную информацию об использовании Espresso-Web в тестах Android можно найти в следующих ресурсах.
Образцы
- WebBasicSample – используйте Espresso-Web для взаимодействия с объектами
WebView.