Espresso-Web é um ponto de entrada para trabalhar com componentes de IU do Android WebView. O Espresso-Web reutiliza Atoms da conhecida API WebDriver (em inglês) para examinar e controlar o comportamento de um WebView.
Quando usar o Espresso-Web
Use o Espresso-Web para testar seus apps híbridos, especialmente a integração dos
componentes da interface nativa do app com os componentes
da interface WebView
. Você pode usar a API do Espresso-Web com outras
APIs do Espresso para interagir de maneira completa com os elementos da Web dentro de objetos WebView
.
Se for necessário testar apenas o WebView
, e não as
interações entre o WebView
e os componentes nativos do app, crie
um teste da Web geral usando um framework como o WebDriver. Se você usa um framework de teste da Web, não
precisa usar um dispositivo Android ou uma máquina virtual Java, o que torna os testes
mais rápidos e confiáveis. Dito isso, o Espresso-Web permite reutilizar
os atoms personalizados do WebDriver, o que oferece muita flexibilidade, especialmente
ao programar testes que você planeja executar em apps da Web autônomos e
que incluem uma interface do Android.
Como funciona
Assim como o método onData()
do Espresso, uma interação WebView
compreende vários Atoms.
As interações de WebView
usam uma combinação da linguagem de programação Java e uma
ponte JavaScript para realizar o trabalho. Como não há possibilidade de introduzir
disputas expondo dados do ambiente JavaScript, porque tudo
que o Espresso vê no lado baseado em Java é uma cópia isolada, o retorno de dados de
objetos Web.WebInteraction
é totalmente compatível, permitindo que você verifique todos os dados retornados de
uma solicitação.
O que é um Atom do WebDriver?
O framework do WebDriver usa Atoms para encontrar e manipular elementos da Web
de maneira programática. Os Atoms são usados pelo WebDriver para permitir a manipulação do navegador. Conceitualmente, um
Atom é semelhante a uma
ViewAction
, uma unidade independente
que executa uma ação na interface. Para expor Atoms, use uma lista de
métodos definidos, como findElement()
e getElement()
, para direcionar o
navegador do ponto de vista do usuário. No entanto, se você usar o framework
WebDriver diretamente, os Atoms precisarão ser orquestrados corretamente, o que exige uma lógica
muito detalhada.
No Espresso, as classes Web
e Web.WebInteraction
encapsulam esse código boilerplate e proporcionam uma experiência semelhante à do Espresso para interagir com objetos
WebView. Portanto, no contexto de um WebView
, os Atoms são usados como
uma substituição dos métodos tradicionais ViewMatchers
e ViewActions
do Espresso.
A API é bastante simples:
Kotlin
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion)
Java
onWebView() .withElement(Atom) .perform(Atom) .check(WebAssertion);
Para saber mais, leia a documentação do Selenium sobre Atoms (em inglês).
Implementar o WebView
Siga as orientações mostradas nas seções abaixo para trabalhar com o
WebView
nos testes do app.
Pacotes
Para incluir o Espresso-Web no projeto, siga estas etapas:
- Abra o arquivo
build.gradle
do seu app. Geralmente, esse não é o arquivobuild.gradle
de nível superior, masapp/build.gradle
. Adicione a seguinte linha nas dependências:
Groovy
androidTestImplementation 'androidx.test.espresso:espresso-web:3.6.1'
Kotlin
androidTestImplementation('androidx.test.espresso:espresso-web:3.6.1')
O Espresso-Web é compatível apenas com o Espresso 2.2 ou mais recente e versão 0.3 ou mais recente da biblioteca de testes. Portanto, atualize essas linhas também:
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')
Uso comum da API
O método onWebView()
é o principal ponto de entrada ao trabalhar com o WebView no Android usando o
Espresso. Use esse método para realizar testes do Espresso-Web, como
estes:
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")));
Nesse exemplo, o Espresso-Web localiza um elemento DOM cujo ID é "link_2"
e clica nele. Em seguida, a ferramenta verifica se a WebView envia uma solicitação GET
contendo a string "navigation_2.html"
.
Compatibilidade com JavaScript
Ao executar seus testes, o sistema realiza todas as interações da WebView usando JavaScript. Portanto, para oferecer suporte à avaliação do JavaScript, o WebView em teste precisa ter o JavaScript ativado.
É possível forçar a ativação do JavaScript chamando
forceJavascriptEnabled()
como uma ação na sua atividade em
teste, conforme mostrado no
snippet de código abaixo.
@RunWith(AndroidJUnit4::class) class MyTestSuite { @get:Rule val activityScenarioRule = activityScenarioRule<MyWebViewActivity>() @Test fun testWebViewInteraction() { onWebView().forceJavascriptEnabled() } }
Interações comuns na Web
As interações comuns com objetos Web.WebInteraction
incluem o seguinte:
-
withElement()
faz referência a um elemento DOM na WebView.Exemplo:
Kotlin
onWebView().withElement(findElement(Locator.ID, "teacher"))
Java
onWebView().withElement(findElement(Locator.ID, "teacher"));
-
withContextualElement()
faz referência a um elemento DOM com escopo no WebView, em relação a outro elemento DOM. ChamewithElement()
primeiro para estabelecer o objetoWeb.WebInteraction
de referência (elemento DOM).Exemplo:
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()
avalia uma condição para garantir que ela seja resolvida comotrue
.Exemplo:
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()
executa uma ação dentro de uma WebView, como clicar em um elemento.Exemplo:
Kotlin
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick())
Java
onWebView() .withElement(findElement(Locator.ID, "teacher")) .perform(webClick());
-
reset()
reverte a WebView para o estado inicial. Isso é necessário quando uma ação anterior, como um clique, introduz uma mudança na navegação que torna os objetos ElementReference e WindowReference inacessíveis.Observação:embora usar
reset()
seja útil ao fazer declarações em relação a fluxos de trabalho de várias páginas, como envios de formulários, seus testes geralmente precisam ter escopo limitado e foco em uma única página.Exemplo:
Kotlin
onWebView() .withElement(...) .perform(...) .reset()
Java
onWebView() .withElement(...) .perform(...) .reset();
Exemplo
O exemplo abaixo testa se, depois de inserir texto em uma WebView e selecionar o botão Submit, o mesmo texto aparece em um elemento diferente na mesma 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))); }
Outros recursos
Para saber mais sobre o uso do Espresso-Web em testes do Android, consulte os recursos abaixo.
Exemplos
- WebBasicSample: use o Espresso-Web para interagir com objetos
WebView
.