Эспрессо Веб

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 в свой проект, выполните следующие шаги:

  1. Откройте файл build.gradle вашего приложения. Обычно это не главный файл build.gradle а файл app/build.gradle .
  2. Добавьте следующую строку в раздел зависимостей:

    Классный

        androidTestImplementation 'androidx.test.espresso:espresso-web:3.6.1'
        

    Котлин

        androidTestImplementation('androidx.test.espresso:espresso-web:3.6.1')
        
  3. 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 .