Эспрессо Веб

Espresso-Web — это точка входа для работы с компонентами пользовательского интерфейса Android WebView. Espresso-Web повторно использует Atoms из популярного API WebDriver для проверки и управления поведением WebView.

Когда использовать Espresso-Web

Используйте Espresso-Web для тестирования гибридных приложений, особенно интеграции собственных компонентов пользовательского интерфейса вашего приложения с компонентами пользовательского интерфейса WebView . Вы можете использовать Espresso-Web API в сочетании с другими API-интерфейсами Espresso для полного взаимодействия с веб-элементами внутри объектов WebView .

Если вам нужно протестировать только сам WebView , а не взаимодействие между WebView и собственными компонентами вашего приложения, рассмотрите возможность написания общего веб-теста с использованием такой платформы, как WebDriver . Если вы используете платформу веб-тестирования, вам не нужно использовать устройство Android или виртуальную машину Java, что делает ваши тесты более быстрыми и надежными. При этом Espresso-Web позволяет вам повторно использовать ваши собственные атомы WebDriver, что дает вам большую гибкость, особенно при написании тестов, которые вы планируете запускать как для автономных веб-приложений, так и для приложений, включающих пользовательский интерфейс Android.

Как это работает

Подобно методу onData() в Espresso, взаимодействие WebView состоит из нескольких атомов. Взаимодействия WebView для выполнения своей работы используют комбинацию языка программирования Java и моста JavaScript. Поскольку нет никакой возможности возникновения условий гонки путем предоставления данных из среды JavaScript — все, что Espresso видит на стороне Java, является изолированной копией — возврат данных из объектов Web.WebInteraction полностью поддерживается, что позволяет вам проверять все возвращаемые данные. из запроса.

Что такое атом WebDriver?

Платформа WebDriver использует Atoms для программного поиска и управления веб-элементами. Атомы используются WebDriver для управления браузером. Atom концептуально похож на ViewAction — автономную единицу, которая выполняет действие в вашем пользовательском интерфейсе. Вы предоставляете Atoms, используя список определенных методов, таких как findElement() и getElement() , чтобы управлять браузером с точки зрения пользователя. Однако если вы используете платформу WebDriver напрямую, Atoms необходимо правильно организовать, требуя довольно многословной логики.

В Espresso классы Web и Web.WebInteraction оборачивают этот шаблон и создают ощущение, подобное Espresso, при взаимодействии с объектами WebView. Таким образом, в контексте WebView Atoms используются в качестве замены традиционных ViewMatchers и ViewActions Espresso.

Тогда API выглядит довольно просто:

Котлин

onWebView()
    .withElement(Atom)
    .perform(Atom)
    .check(WebAssertion)

Ява

onWebView()
    .withElement(Atom)
    .perform(Atom)
    .check(WebAssertion);

Чтобы узнать больше, прочтите документацию Selenium по Atoms .

Реализация веб-представления

Следуйте инструкциям, приведенным в следующих разделах, для работы с 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")))

Ява

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.

    Пример:

    Котлин

    onWebView().withElement(findElement(Locator.ID, "teacher"))
    

    Ява

    onWebView().withElement(findElement(Locator.ID, "teacher"));
    
  • withContextualElement() ссылается на элемент DOM с заданной областью внутри WebView относительно другого элемента DOM. Сначала вам следует вызвать withElement() , чтобы установить ссылочный объект Web.WebInteraction (элемент DOM).

    Пример:

    Котлин

    .withElement(findElement(Locator.ID, "teacher"))
        .withContextualElement(findElement(Locator.ID, "person_name"))
    

    Ява

    .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")))
    

    Ява

    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())
    

    Ява

    onWebView()
        .withElement(findElement(Locator.ID, "teacher"))
        .perform(webClick());
    
  • reset() возвращает WebView в исходное состояние. Это необходимо, когда предыдущее действие, например щелчок, приводит к изменению навигации, которое делает объекты ElementReference и WindowReference недоступными.

    Примечание. Хотя использование reset() полезно при создании утверждений для многостраничных рабочих процессов, таких как отправка форм, ваши тесты обычно должны быть ограничены по объему и сосредоточены на одной странице.

    Пример:

    Котлин

    onWebView()
        .withElement(...)
        .perform(...)
        .reset()
    

    Ява

    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)))
    }
}

Ява

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 .