Espresso-Web — это точка входа для работы с компонентами пользовательского интерфейса Android WebView. Espresso-Web повторно использует атомы из популярного API WebDriver для изучения и управления поведением WebView.
Когда использовать Espresso-Web
Используйте Espresso-Web для тестирования гибридных приложений, особенно интеграции нативных компонентов пользовательского интерфейса вашего приложения с компонентами WebView . Вы можете использовать API Espresso-Web в сочетании с другими API Espresso для полноценного взаимодействия с веб-элементами внутри объектов WebView .
Если вам нужно протестировать только сам WebView , а не взаимодействие между WebView и нативными компонентами вашего приложения, рассмотрите возможность написания общего веб-теста с использованием фреймворка, такого как WebDriver . При использовании фреймворка для веб-тестирования вам не потребуется устройство Android или виртуальная машина Java, что сделает ваши тесты более быстрыми и надежными. При этом Espresso-Web позволяет повторно использовать ваши пользовательские атомы WebDriver, что дает вам большую гибкость, особенно при написании тестов, которые вы планируете запускать как для автономных веб-приложений, так и для приложений, включающих пользовательский интерфейс Android.
Как это работает
Подобно методу onData() в Espresso, взаимодействие WebView состоит из нескольких атомов (Atom). Взаимодействие WebView использует комбинацию языка программирования Java и моста JavaScript для выполнения своей работы. Поскольку нет риска возникновения состояний гонки при передаче данных из среды JavaScript — все, что Espresso видит на стороне Java, является изолированной копией — полностью поддерживается возврат данных из объектов Web.WebInteraction , что позволяет проверять все данные, возвращаемые запросом.
Что такое WebDriver Atom?
Фреймворк WebDriver использует атомы (Atoms) для программного поиска и манипулирования веб-элементами. Атомы используются WebDriver для обеспечения возможности управления браузером. Атом концептуально похож на ViewAction — самодостаточный модуль, выполняющий действие в пользовательском интерфейсе. Вы предоставляете доступ к атомам с помощью списка определенных методов, таких как findElement() и getElement() , чтобы управлять браузером с точки зрения пользователя. Однако, если вы используете фреймворк WebDriver напрямую, атомы необходимо должным образом координировать, что требует довольно многословной логики.
В Espresso классы Web и Web.WebInteraction оборачивают этот шаблонный код и придают взаимодействию с объектами WebView ощущение, схожее с Espresso. Таким образом, в контексте WebView атомы используются в качестве замены традиционных ViewMatchers и ViewActions из Espresso.
В таком случае API выглядит довольно просто:
Котлин
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. Добавьте следующую строку в раздел зависимостей:
Классный
androidTestImplementation 'androidx.test.espresso:espresso-web:3.6.1'
Котлин
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'
Котлин
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, например, следующих:
Котлин
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 с ID "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.Пример:
Котлин
onWebView().withElement(findElement(Locator.ID, "teacher"))
Java
onWebView().withElement(findElement(Locator.ID, "teacher"));
withContextualElement()ссылается на элемент DOM с ограниченной областью видимости внутри `WebView` относительно другого элемента DOM. Для установления ссылки на объектWeb.WebInteraction(элемент DOM) следует сначала вызватьwithElement()`.Пример:
Котлин
.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.Пример:
Котлин
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, например, щелчок по элементу.Пример:
Котлин
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick())
Java
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick());
reset()возвращает WebView в исходное состояние. Это необходимо, когда предыдущее действие, например, щелчок мышью, вносит изменения в навигацию, делая объекты ElementReference и WindowReference недоступными.Примечание: Хотя использование
reset()полезно при проверке многостраничных рабочих процессов, таких как отправка форм, ваши тесты, как правило, должны быть ограничены по объему и сосредоточены на одной странице.Пример:
Котлин
onWebView() .withElement(...) .perform(...) .reset()
Java
onWebView() .withElement(...) .perform(...) .reset();
Пример
В следующем примере проверяется, отображается ли тот же текст в другом элементе того же самого WebView после ввода текста в WebView и нажатия кнопки «Отправить» :
Котлин
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.