Espresso w sieci

Espresso-Web to punkt wejścia do pracy z komponentami interfejsu Android WebView. Espresso-Web używa atomów z popularnego interfejsu WebDriver API do sprawdzania i kontrolowania działania komponentu WebView.

Kiedy używać Espresso-Web

Używaj Espresso-Web do testowania aplikacji hybrydowych, zwłaszcza integracji natywnych komponentów interfejsu aplikacji z komponentami interfejsu WebView. Możesz używać interfejsu Espresso-Web API w połączeniu z innymi interfejsami Espresso API, aby w pełni korzystać z elementów internetowych w obiektach WebView.

Jeśli musisz przetestować tylko sam komponent WebView, a nie interakcje między nim a natywnymi komponentami w aplikacji, rozważ napisanie ogólnego testu internetowego przy użyciu platformy takiej jak WebDriver.WebView Jeśli używasz frameworka do testowania internetu, nie musisz używać urządzenia z Androidem ani wirtualnej maszyny Java, co przyspiesza i zwiększa niezawodność testów. Espresso-Web umożliwia jednak ponowne używanie niestandardowych atomów WebDriver, co daje dużą elastyczność, zwłaszcza podczas pisania testów, które mają być uruchamiane zarówno w samodzielnych aplikacjach internetowych, jak i w aplikacjach zawierających interfejs Androida.

Jak to działa

Podobnie jak metoda onData() w Espresso, interakcja z WebView obejmuje kilka atomów. WebView interakcje wykorzystują kombinację języka programowania Java i mostka JavaScript. Nie ma możliwości wprowadzenia warunków wyścigu przez udostępnianie danych ze środowiska JavaScript – wszystko, co Espresso widzi po stronie Java, to izolowana kopia. Dlatego w pełni obsługiwane jest zwracanie danych z Web.WebInteraction obiektów, co pozwala weryfikować wszystkie dane zwracane z żądania.

Co to jest atom WebDriver?

Framework WebDriver używa atomów do programowego znajdowania i manipulowania elementami internetowymi. WebDriver używa atomów do manipulowania przeglądarką. Atom jest koncepcyjnie podobny do ViewAction – samodzielnej jednostki, która wykonuje działanie w interfejsie. Atomy udostępniasz za pomocą listy zdefiniowanych metod, takich jak findElement() i getElement(), aby sterować przeglądarką z punktu widzenia użytkownika. Jeśli jednak używasz platformy WebDriver bezpośrednio, atomy muszą być odpowiednio administrowane, co wymaga dość rozbudowanej logiki.

W Espresso klasy Web i Web.WebInteraction opakowują ten kod i sprawiają, że interakcja z obiektami WebView przypomina interakcję z Espresso. W kontekście WebView atomy są używane jako zamiennik tradycyjnych elementów Espresso ViewMatchers i ViewActions.

Interfejs API wygląda wtedy dość prosto:

Kotlin

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

Java

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

Więcej informacji znajdziesz w dokumentacji Selenium na temat atomów.

Implementowanie WebView

Aby pracować z WebView w testach aplikacji, postępuj zgodnie z instrukcjami podanymi w kolejnych sekcjach.

Pakiety

Aby uwzględnić Espresso-Web w projekcie, wykonaj te czynności:

  1. Otwórz plik build.gradle aplikacji. Zwykle nie jest to plik build.gradle najwyższego poziomu, ale app/build.gradle.
  2. Dodaj ten wiersz w sekcji zależności:

    Dynamiczny

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

    Kotlin

        androidTestImplementation('androidx.test.espresso:espresso-web:3.6.1')
        
  3. Espresso-Web jest zgodne tylko z Espresso w wersji 2.2 lub nowszej oraz z biblioteką testową w wersji 0.3 lub nowszej, więc zaktualizuj też te wiersze:

    Dynamiczny

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

Typowe użycie interfejsu API

Metoda onWebView() to główny punkt wejścia podczas pracy z WebView na Androidzie przy użyciu Espresso. Używasz tej metody do wykonywania testów Espresso-Web, takich jak te:

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

W tym przykładzie Espresso-Web lokalizuje element DOM o identyfikatorze "link_2" i klika go. Następnie narzędzie sprawdza, czy WebView wysyła żądanie GET zawierające ciąg znaków "navigation_2.html".

Obsługa JavaScriptu

Podczas wykonywania testów system przeprowadza wszystkie interakcje z WebView za pomocą JavaScriptu. Aby obsługiwać ocenę JavaScriptu, w testowanym komponencie WebView musi być włączony JavaScript.

Możesz wymusić włączenie JavaScriptu, wywołując forceJavascriptEnabled() jako działanie w testowanej aktywności, jak pokazano w tym fragmencie kodu.

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @get:Rule val activityScenarioRule =
        activityScenarioRule<MyWebViewActivity>()

    @Test fun testWebViewInteraction() {
        onWebView().forceJavascriptEnabled()
    }
}

Typowe interakcje internetowe

Typowe interakcje z obiektami Web.WebInteraction obejmują:

  • withElement() odwołuje się do elementu DOM w WebView.

    Przykład:

    Kotlin

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

    Java

    onWebView().withElement(findElement(Locator.ID, "teacher"));
  • withContextualElement() odwołuje się do elementu DOM w WebView w określonym zakresie względem innego elementu DOM. Najpierw wywołaj withElement() aby utworzyć odwołanie do obiektu Web.WebInteraction (elementu DOM).

    Przykład:

    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() ocenia warunek, upewniając się, że przyjmuje on wartość true.

    Przykład:

    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() wykonuje działanie w WebView, np. kliknięcie elementu.

    Przykład:

    Kotlin

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

    Java

    onWebView()
        .withElement(findElement(Locator.ID, "teacher"))
        .perform(webClick());
  • reset() przywraca WebView do stanu początkowego. Jest to konieczne, gdy poprzednie działanie, np. kliknięcie, powoduje zmianę nawigacji, która uniemożliwia dostęp do obiektów ElementReference i WindowReference.

    Uwaga: używanie reset() jest przydatne podczas sprawdzania asercji w przepływach pracy obejmujących wiele stron, np. przesyłania formularzy, ale testy powinny być zwykle ograniczone do jednej strony.

    Przykład:

    Kotlin

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

    Java

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

Przykład

Ten przykład sprawdza, czy po wpisaniu tekstu w WebView i kliknięciu przycisku Prześlij ten sam tekst pojawi się w innym elemencie w tym samym 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)));
}

Dodatkowe materiały

Więcej informacji o używaniu Espresso-Web w testach na Androida znajdziesz w tych materiałach.

Przykłady

  • WebBasicSample: Użyj Espresso-Web do interakcji z obiektami WebView.