Espresso Web

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 aplicativos híbridos, especialmente a integração dos seus os componentes da interface nativa do app com os WebView componentes de IU. É possível usar a API do Espresso-Web com outras APIs do Espresso para interagir completamente com elementos da Web em objetos WebView.

Se você precisar testar apenas o WebView, e não o interações entre WebView e componentes nativos no seu app, considere criar um teste geral da Web usando um framework como o WebDriver. Se você usa um framework de teste da Web, usar um dispositivo Android ou uma máquina virtual Java, o que facilita os testes para que sejam executados com mais rapidez e confiança. Com isso em mente, o Espresso-Web permite reutilizar seus átomos personalizados do WebDriver, o que proporciona muita flexibilidade, ao escrever testes que você planeja executar em aplicativos da Web autônomos e apps que incluem uma interface do Android.

Como funciona

Da mesma forma que o onData() do Espresso uma interação WebView compreende vários Atoms. As interações WebView usam uma combinação da linguagem de programação Java e uma JavaScript para fazer seu trabalho. Como não há chance de introduzir condições de corrida ao expor dados do ambiente JavaScript, O Espresso vê no lado baseado em Java uma cópia isolada que retorna dados do Web.WebInteraction é totalmente compatível, o que permite verificar todos os dados retornados de uma solicitação.

O que é um Atom do WebDriver?

O framework do WebDriver usa Atoms para localizar e manipular elementos da Web programaticamente. Os Atoms são usados pelo WebDriver para permitir a manipulação do navegador. Um Conceitualmente, o Atom é semelhante a um O ViewAction, uma plataforma que executa uma ação na interface. Você expõe Atoms usando uma lista de métodos definidos, como findElement() e getElement(), para direcionar o do navegador do ponto de vista do usuário. No entanto, se você usar o WebDriver diretamente o framework, os Atoms precisam ser devidamente orquestrados, exigindo lógica que é bem prolixo.

No Espresso, as classes Web e Web.WebInteraction unir esse código clichê e proporcionar uma experiência semelhante à do Expresso para interagir com a WebView. objetos. Portanto, no contexto de uma WebView, os Atoms são usados como Uma substituição para as ViewMatchers e ViewActions do Espresso.

A API é bastante simples:

onWebView()
   
.withElement(Atom)
   
.perform(Atom)
   
.check(WebAssertion)
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 a seguir para trabalhar WebView nos testes do app.

Pacotes

Para incluir o Espresso-Web no projeto, siga estas etapas:

  1. Abra o arquivo build.gradle do seu app. Geralmente, não é a no arquivo build.gradle de nível superior, app/build.gradle.
  2. Adicione a seguinte linha nas dependências:

        androidTestImplementation 'androidx.test.espresso:espresso-web:3.6.1'
       
        androidTestImplementation('androidx.test.espresso:espresso-web:3.6.1')
       
  3. O Espresso-Web é compatível somente com o Espresso 2.2 ou posterior e para a versão 0.3 ou superior da biblioteca de teste. com as seguintes linhas:

        androidTestImplementation 'androidx.test:runner:1.6.1'
        androidTestImplementation
    'androidx.test:rules:1.6.1'
        androidTestImplementation
    'androidx.test.espresso:espresso-core:3.6.1'
       
        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 onWebView() é o principal ponto de entrada ao trabalhar com a WebView no Android usando Use esse método para realizar testes do Espresso-Web, como o seguintes:

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

Neste exemplo, o Espresso-Web localiza um elemento DOM com ID "link_2" e clicar nela. A ferramenta verifica se o WebView envia uma solicitação GET que contém a string "navigation_2.html".

Compatibilidade com JavaScript

Ao executar seus testes, o sistema realiza todas as interações do WebView usando JavaScript. Portanto, para oferecer suporte à avaliação do JavaScript, o WebView em teste o JavaScript precisa estar ativado.

É possível forçar a ativação do JavaScript chamando forceJavascriptEnabled() como uma ação em sua atividade em teste, conforme mostrado no snippet de código a seguir.

@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:

    onWebView().withElement(findElement(Locator.ID, "teacher"))
    onWebView().withElement(findElement(Locator.ID, "teacher"));
  • withContextualElement() faz referência a um elemento DOM com escopo na WebView, em relação a outro elemento DOM. Você deve chamar withElement() primeiro para estabelecer a referência Web.WebInteraction (elemento DOM).

    Exemplo:

    .withElement(findElement(Locator.ID, "teacher"))
       
    .withContextualElement(findElement(Locator.ID, "person_name"))
    .withElement(findElement(Locator.ID, "teacher"))
       
    .withContextualElement(findElement(Locator.ID, "person_name"));
  • check() avalia uma condição para garantir que ela seja resolvida para true.

    Exemplo:

    onWebView()
       
    .withElement(findElement(Locator.ID, "teacher"))
       
    .withContextualElement(findElement(Locator.ID, "person_name"))
       
    .check(webMatches(getText(), containsString("Socrates")))
    onWebView()
       
    .withElement(findElement(Locator.ID, "teacher"))
       
    .withContextualElement(findElement(Locator.ID, "person_name"))
       
    .check(webMatches(getText(), containsString("Socrates")));
  • O perform() executa uma ação dentro de um WebView, como clicando em um elemento.

    Exemplo:

    onWebView()
       
    .withElement(findElement(Locator.ID, "teacher"))
       
    .perform(webClick())
    onWebView()
       
    .withElement(findElement(Locator.ID, "teacher"))
       
    .perform(webClick());
  • reset() reverte o WebView ao estado inicial. Isso é necessário quando uma uma ação, como um clique, introduz uma mudança na navegação que facilita Objetos ElementReference e WindowReference inacessíveis.

    Observação:embora o uso de reset() seja útil quando fazer declarações em relação a fluxos de trabalho de várias páginas, como envios de formulário, Em geral, os testes precisam ter escopo limitado e foco em uma única página.

    Exemplo:

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

Exemplo

O exemplo a seguir testa se, depois de inserir texto em um WebView, selecionando um botão Enviar, o mesmo texto aparecerá em um elemento diferente no a mesma WebView:

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)))
   
}
}
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 mais informações sobre o uso do Espresso-Web em testes do Android, consulte a recursos a seguir.

Amostras

  • WebBasicSample (em inglês): Usar o Espresso-Web para interagir com objetos WebView.