Espresso-Web to punkt wejścia do pracy ze komponentami UI Android WebView. Espresso-Web wykorzystuje atom z popularnego interfejsu WebDriver API do badania i kontrolowania działania komponentu WebView.
Kiedy używać Espresso-Web
Skorzystaj z Espresso-Web, by przetestować swoje aplikacje hybrydowe, zwłaszcza integrację natywnych komponentów UI aplikacji z komponentami jej WebView
. Interfejsu Espresso-Web API możesz używać w połączeniu z innymi interfejsami API Espresso, by w pełni korzystać z elementów sieciowych wewnątrz obiektów WebView
.
Jeśli chcesz przetestować tylko interfejs WebView
, a nie interakcje między komponentem WebView
a komponentami natywnymi w aplikacji, możesz utworzyć ogólny test witryny, używając platformy takiej jak WebDriver. Jeśli korzystasz ze środowiska do testowania stron internetowych, nie musisz używać urządzenia z Androidem ani maszyny wirtualnej w języku Java, dzięki czemu testy przebiegają szybciej i niezawodnie. Espresso-Web umożliwia ponowne wykorzystywanie niestandardowych atomów WebDriver, co zapewnia dużą elastyczność, zwłaszcza podczas pisania testów, które zamierzasz przeprowadzić zarówno w przypadku samodzielnych aplikacji internetowych, jak i aplikacji zawierających interfejs użytkownika Androida.
Jak to działa
Podobnie jak w przypadku metody onData()
Espresso, interakcja WebView
składa się z kilku obiektów Atom.
Interakcje WebView
wykorzystują połączenie języka programowania Java i mostu JavaScript. Nie ma możliwości wprowadzenia warunków wyścigu przez ujawnienie danych ze środowiska JavaScript, więc wszystko, co Espresso widzi po stronie języka Java, to izolowana kopia. W pełni obsługiwane są zwracane dane z obiektów Web.WebInteraction
, dzięki czemu możesz zweryfikować wszystkie dane zwracane z żądania.
Co to jest WebDriver Atom?
Platforma WebDriver wykorzystuje zasoby Atoms do programowego znajdowania elementów sieciowych i manipulowania nimi. Atrybut Atom jest używany przez WebDriver do umożliwienia manipulacji przeglądarką. Atom jest koncepcyjnie podobny do ViewAction
– samodzielnej jednostki, która wykonuje działanie w interfejsie użytkownika. Ujawniasz Atoms za pomocą listy zdefiniowanych metod, takich jak findElement()
czy getElement()
, aby sterować przeglądarką z perspektywy użytkownika. Jeśli jednak używasz platformy WebDriver bezpośrednio, musisz zadbać o odpowiednią administrację i wymagać logiki, która jest dość obszerna.
W Espresso klasy Web
i Web.WebInteraction
opakowują ten stały szablon, nadając im wrażenie interakcji z obiektami WebView w stylu espresso. W kontekście elementu WebView
atrybuty Atom są używane jako zamiennik tradycyjnego 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 Senenium na temat Atoms.
Implementowanie komponentu WebView
Aby podczas testów aplikacji korzystać z narzędzia WebView
, postępuj zgodnie ze wskazówkami podanymi w sekcjach poniżej.
Pakiety
Aby uwzględnić Espresso-Web w swoim projekcie, wykonaj te czynności:
- Otwórz plik
build.gradle
aplikacji. Zwykle nie jest to plikbuild.gradle
najwyższego poziomu, aleapp/build.gradle
. Dodaj ten wiersz w zależnościach:
Odlotowy
androidTestImplementation 'androidx.test.espresso:espresso-web:3.6.1'
Kotlin
androidTestImplementation('androidx.test.espresso:espresso-web:3.6.1')
Espresso-Web jest zgodny tylko z Espresso 2.2 lub nowszym oraz z biblioteką testową w wersji 0.3 lub nowszej, więc pamiętaj o zaktualizowaniu tych wierszy:
Odlotowy
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 zastosowanie 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 wykonywania 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 go klika. Następnie narzędzie sprawdzi, czy WebView wysyła żądanie GET zawierające ciąg tekstowy "navigation_2.html"
.
Obsługa JavaScriptu
Podczas testów system wykonuje wszystkie interakcje z komponentem WebView przy użyciu JavaScriptu. Dlatego, aby umożliwić ocenę JavaScriptu, testowany komponent WebView musi mieć włączony język JavaScript.
Możesz wymusić włączenie JavaScriptu, wywołując metodę forceJavascriptEnabled()
jako działanie w testowanej aktywności, jak widać 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 komponencie 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 zakresie ograniczonym w komponencie WebView w stosunku do innego elementu DOM. Należy najpierw wywołaćwithElement()
, aby ustanowić referencyjny obiektWeb.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 przyjmuje 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 komponencie WebView, na przykład 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, takie jak kliknięcie, spowoduje zmianę nawigacji, przez co obiekty ElementReference i WindowReference staną się niedostępne.Uwaga: chociaż użycie
reset()
jest przydatne podczas tworzenia asercji dotyczących przepływów pracy na wielu stronach, takich jak przesyłanie formularzy, powinno być zwykle ograniczone i koncentrować się na jednej stronie.Przykład:
Kotlin
onWebView() .withElement(...) .perform(...) .reset()
Java
onWebView() .withElement(...) .perform(...) .reset();
Przykład
W tym przykładzie sprawdzisz, czy po wpisaniu tekstu w komponencie WebView i wybraniu przycisku Prześlij ten sam tekst pojawia 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 korzystaniu z Espresso-Web w testach na Androidzie znajdziesz w tych materiałach.
Próbki
- WebbasicSample: używa Espresso-Web do interakcji z obiektami
WebView
.