Espresso w sieci

Espresso-Web to punkt wejścia do pracy z komponentami interfejsu Android WebView. Espresso-Web ponownie wykorzystuje elementy 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 chcesz przetestować tylko WebView, a nie interakcje między WebView a komponentami natywnymi w aplikacji, rozważ napisanie ogólnego testu internetowego przy użyciu platformy takiej jak WebDriver. Jeśli używasz platformy do testowania stron internetowych, nie musisz korzystać z urządzenia z Androidem ani z wirtualnej maszyny Java, co sprawia, że testy działają szybciej i bardziej niezawodnie. Espresso-Web umożliwia jednak ponowne używanie niestandardowych atomów WebDrivera, co daje dużą elastyczność, zwłaszcza podczas pisania testów, które mają być uruchamiane zarówno w przypadku samodzielnych aplikacji internetowych, jak i aplikacji zawierających interfejs Androida.

Jak to działa

Podobnie jak w przypadku metody Espresso onData(), WebView interakcja składa się z kilku elementów Atom. WebView interakcje wykorzystują język programowania Java i most 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 odizolowana kopia. Dlatego zwracanie danych z obiektów Web.WebInteraction jest w pełni obsługiwane, co pozwala weryfikować wszystkie dane zwracane z żądania.

Co to jest WebDriver Atom?

Platforma WebDriver używa atomów do programowego znajdowania elementów internetowych i manipulowania nimi. Atomy są używane przez WebDrivera do manipulowania przeglądarką. Atom jest koncepcyjnie podobny do ViewAction, czyli samodzielnej jednostki, która wykonuje działanie w interfejsie. Atomy są udostępniane za pomocą listy zdefiniowanych metod, takich jak findElement()getElement(), aby sterować przeglądarką z punktu widzenia użytkownika. Jeśli jednak używasz bezpośrednio platformy WebDriver, musisz odpowiednio skoordynować atomy, co wymaga dość rozbudowanej logiki.

W Espresso klasy WebWeb.WebInteraction zawierają ten kod i sprawiają, że interakcja z obiektami WebView przypomina korzystanie z Espresso. W kontekście WebView atomy są używane jako zamiennik tradycyjnych testów Espresso ViewMatchersViewActions.

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 korzystać z WebView w testach aplikacji, postępuj zgodnie ze wskazówkami podanymi w sekcjach poniżej.

Pakiety

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

  1. Otwórz plik build.gradle aplikacji. Zwykle nie jest to plik najwyższego poziomu build.gradle, ale app/build.gradle.
  2. W sekcji dependencies dodaj ten wiersz:

    Groovy

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

    Kotlin

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

    Groovy

        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 zastosowania interfejsu API

Metoda onWebView() jest głównym punktem wejścia podczas pracy z WebView na Androidzie przy użyciu Espresso. Ta metoda służy do przeprowadzania testów Espresso-Web, takich jak:

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, którego identyfikator to "link_2", i klika go. Narzędzie sprawdza następnie, czy element 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 komponentem WebView za pomocą JavaScriptu. Dlatego, aby obsługiwać ocenę JavaScriptu, testowany widok WebView musi mieć włączoną obsługę JavaScriptu.

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

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

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

Typowe interakcje w internecie

Typowe interakcje z obiektami Web.WebInteraction to:

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

    Przykład:

    Kotlin

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

    Java

    onWebView().withElement(findElement(Locator.ID, "teacher"));
  • withContextualElement() odwołuje się do elementu DOM o określonym zakresie w ramach WebView, względem innego elementu DOM. Najpierw wywołaj funkcję withElement(), aby utworzyć obiekt odniesienia Web.WebInteraction (element 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, sprawdzając, czy jego wynikiem jest 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 komponencie WebView, np. klika element.

    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 wcześniejsze 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 przepływów 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

W tym przykładzie sprawdzamy, czy po wpisaniu tekstu w komponencie WebView i kliknięciu przycisku Prześlij ten sam tekst pojawi się w innym elemencie w tym samym komponencie 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:

Próbki

  • WebBasicSample: Użyj Espresso-Web, aby wchodzić w interakcje z obiektami WebView.