Espresso-Web è un punto di ingresso per lavorare con i componenti UI di Android WebView. Espresso-Web riutilizza gli atomi della popolare API WebDriver per esaminare e controllare il comportamento di una WebView.
Quando utilizzare Espresso-Web
Utilizza Espresso-Web per testare le app ibride, in particolare l'integrazione dei componenti UI nativi dell'app con i componenti UI WebView. Puoi utilizzare l'API Espresso-Web insieme ad altre API Espresso per interagire completamente con gli elementi web all'interno degli oggetti WebView.
Se devi testare solo il WebView stesso e non le
interazioni tra il WebView e i componenti nativi dell'app, valuta la possibilità di
scrivere un test web generale utilizzando un framework come WebDriver. Se utilizzi un framework di test web, non devi utilizzare un dispositivo Android o una Java Virtual Machine, il che rende i test più veloci e affidabili. Detto questo, Espresso-Web ti consente di riutilizzare i tuoi atomi WebDriver personalizzati, il che ti offre molta flessibilità, soprattutto quando scrivi test che prevedi di eseguire sia su app web autonome sia su app che includono un'interfaccia utente Android.
Come funziona
Analogamente al metodo onData()
di Espresso, un'interazione WebView comprende diversi atomi.
Le interazioni WebView utilizzano una combinazione del linguaggio di programmazione Java e di un
bridge JavaScript per svolgere il proprio lavoro. Poiché non esiste la possibilità di introdurre
condizioni di competizione esponendo i dati dall'ambiente JavaScript (tutto ciò che
Espresso vede sul lato basato su Java è una copia isolata), la restituzione dei dati dagli
Web.WebInteraction
oggetti è completamente supportata, il che ti consente di verificare tutti i dati restituiti da
una richiesta.
Che cos'è un atomo WebDriver?
Il framework WebDriver utilizza gli atomi per trovare e manipolare gli elementi web a livello di programmazione. Gli atomi vengono utilizzati da WebDriver per consentire la manipolazione del browser. Un
atomo è concettualmente simile a un
ViewAction, un'unità autonoma
che esegue un'azione nell'interfaccia utente. Espone gli atomi utilizzando un elenco di metodi definiti, come findElement() e getElement(), per controllare il browser dal punto di vista dell'utente. Tuttavia, se utilizzi direttamente il framework WebDriver, gli atomi devono essere orchestrati correttamente, richiedendo una logica piuttosto dettagliata.
In Espresso, le classi Web
e Web.WebInteraction
racchiudono questo boilerplate e danno un aspetto simile a Espresso all'interazione con gli oggetti WebView. Quindi, nel contesto di un WebView, gli atomi vengono utilizzati come
sostituzione dei tradizionali ViewMatchers e ViewActions di Espresso.
L'API ha un aspetto piuttosto semplice:
Kotlin
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion)
Java
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion);
Per saperne di più, consulta la documentazione di Selenium sugli atomi.
Implementare WebView
Segui le indicazioni riportate nelle sezioni seguenti per lavorare con
WebView nei test dell'app.
Pacchetti
Per includere Espresso-Web nel tuo progetto:
- Apri il file
build.gradledell'app. In genere non è il file di primo livello, maapp/build.gradle.build.gradle Aggiungi la seguente riga all'interno delle dipendenze:
Alla moda
androidTestImplementation 'androidx.test.espresso:espresso-web:3.6.1'
Kotlin
androidTestImplementation('androidx.test.espresso:espresso-web:3.6.1')
Espresso-Web è compatibile solo con Espresso 2.2 o versioni successive e con la versione 0.3 o versioni successive della libreria di test, quindi assicurati di aggiornare anche queste righe:
Alla moda
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')
Utilizzo comune dell'API
Il onWebView()
metodo è il punto di ingresso principale quando si lavora con WebView su Android utilizzando
Espresso. Utilizza questo metodo per eseguire test Espresso-Web, ad esempio:
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")));
In questo esempio, Espresso-Web individua un elemento DOM il cui ID è "link_2" e
fa clic su di esso. Lo strumento verifica quindi che WebView invii una richiesta GET
contenente la stringa "navigation_2.html".
Supporto JavaScript
Durante l'esecuzione dei test, il sistema esegue tutte le interazioni WebView utilizzando JavaScript. Pertanto, per supportare la valutazione di JavaScript, JavaScript deve essere abilitato in WebView in fase di test.
Puoi forzare l'abilitazione di JavaScript chiamando
forceJavascriptEnabled()
come azione nell'attività in fase di
test, come mostrato nel
seguente snippet di codice.
@RunWith(AndroidJUnit4::class) class MyTestSuite { @get:Rule val activityScenarioRule = activityScenarioRule<MyWebViewActivity>() @Test fun testWebViewInteraction() { onWebView().forceJavascriptEnabled() } }
Interazioni web comuni
Le interazioni comuni con gli oggetti Web.WebInteraction includono le seguenti:
-
withElement()fa riferimento a un elemento DOM all'interno di WebView.Esempio:
Kotlin
onWebView().withElement(findElement(Locator.ID, "teacher"))
Java
onWebView().withElement(findElement(Locator.ID, "teacher"));
-
withContextualElement()fa riferimento a un elemento DOM con ambito all'interno di WebView, rispetto a un altro elemento DOM. Devi chiamarewithElement()prima per stabilire l'oggetto di riferimentoWeb.WebInteraction(elemento DOM).Esempio:
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()valuta una condizione, assicurandosi che venga risolta intrue.Esempio:
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()esegue un'azione all'interno di una WebView, ad esempio facendo clic su un elemento.Esempio:
Kotlin
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick())
Java
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick());
-
reset()ripristina lo stato iniziale di WebView. Questa operazione è necessaria quando un'azione precedente, ad esempio un clic, introduce una modifica di navigazione che rende inaccessibili gli oggetti ElementReference e WindowReference.Nota: anche se l'utilizzo di
reset()è utile quando si eseguono asserzioni su flussi di lavoro multipagina, ad esempio invii di moduli, in genere l'ambito dei test deve essere limitato e concentrarsi su una singola pagina.Esempio:
Kotlin
onWebView() .withElement(...) .perform(...) .reset()
Java
onWebView() .withElement(...) .perform(...) .reset();
Esempio
L'esempio seguente verifica se, dopo aver inserito il testo in una WebView e aver selezionato un pulsante Invia, lo stesso testo viene visualizzato all'interno di un elemento diverso nella stessa 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))); }
Risorse aggiuntive
Per saperne di più sull'utilizzo di Espresso-Web nei test Android, consulta le seguenti risorse.
Esempi
- WebBasicSample:
Utilizza Espresso-Web per interagire con gli oggetti
WebView.