Concrete Logo
Hamburger button

Testes no Android com Espresso – Parte 3

  • Blog
  • 14 de Setembro de 2016

*Este post foi originalmente publicado no Medium pessoal do autor. Veja aqui.

Na semana passada, começamos aqui no Blog uma série sobre Testes no Android com Espresso. Se você ainda não viu, clique aqui para ver a primeira parte, quando fizemos nosso primeiro teste de login, e aqui para ver a segunda. Hoje, na terceira parte, vamos testar intents. Se você quiser começar daqui, utilize o branch ‘part_2’ do projeto.

Simulando resultados de intents

Vamos escrever o teste para o seguinte cenário:

  • Quando username e password não são vazios e o usuário clica no botão de login, o app deve abrir a tela principal (MainActivity).

Poderíamos escrever um teste que preencha os dois campos, clique no botão de login e em seguida verifique se o layout da MainActivity estará visível, algo deste tipo:

Porém, isso é errado por dois motivos. O primeiro pode ser considerado mais uma dica:

Evite fazer testes que façam navegações por meio do app, inicie as activities diretamente no estado desejado.

O segundo motivo é que a MainActivity faz uma requisição para a API, o que torna este teste dependente de um recurso externo. E aí vai outra dica, que na verdade, deve ser uma regra:

Os testes devem ser isolados de qualquer dependência externa.

Para testarmos se uma activity é iniciada, devemos testar se a intent desta activity é lançada, afinal de contas, quem define qual activity será iniciada é a intent. Para podermos validar a intent, devemos adicionar a seguinte dependência no nosso arquivo build.gradle:

Essa é uma extensão do Espresso que nos permite trabalhar com intents (mais informações neste link).

Antes de escrevermos o teste, vamos analisar o trecho do código que inicia a nossa MainActivity (LoginActivity.java, linha 53).

A intent que estamos montando é bem simples, possui apenas o nome da classe (MainActivity.class) e o contexto como parâmetros. Vamos utilizar o nome da classe para validar nossa intent. O nosso teste ficará assim:

Vamos analisar o código:

  • Linha 3: estamos iniciando a gravação das intents com o método init();
  • Linhas 5 e 6: nada de novo, apenas preenchendo os campos username password;
  • Linha 8: usamos o método IntentMatchers.hasComponent(String className) passando como parâmetro o nome da classe MainActivity, que é a activity que será iniciada;
  • Linha 10: fazemos o click no botão de login;
  • Linha 12: o método intended(Matcher<Intent> matcher) verifica que o matcher passado como parâmetro é o que a activity em teste irá lançar, garantindo também que esta intent seja única;
  • Linha 14: o método release() limpa os estados das intents.

O que estamos fazendo é falar para o Espresso: “Cara, quando eu preencher estes dois campos e clicar no botão de login, o app deve lançar uma intent para abrir a MainActivity”. Simples assim.

Se rodarmos o teste, ele passa. Porém ainda há algo errado nele. Repare que a MainActivity ainda abre. E faz sentido, afinal de contas, a única coisa que fizemos foi garantir que a intent lançada é a correta, não fizemos nada para impedir que a MainActivity se inicie.

Para garantir que o nosso teste esteja isolado e evitar a navegação pelo app, vamos simular o resultado desta intent. Refatorando o teste, vai ficar assim:

Foram adicionadas duas linhas:

  • Linha 8: estamos criando um objeto ActivityResult que irá simular o resultado da activity;
  • Linha 9: usamos o método intending() para devolver um resultado assim que a intent for lançada.

Um ponto importante na documentação do Espresso sobre esse método:

  • Linha 9: chamamos o método respondWith(), passando como parâmetro o nosso objeto ActivityResult definido na linha 8.

Novamente, o que estamos falando para o Espresso é: “Quando esta intent for lançada, responda com esse resultado”, evitando que a MainActivity inicie.

Rode o teste, ele deve passar sem problemas e a MainActivity não será iniciada. Se algo deu errado, retome os passos anteriores ou deixe um comentário abaixo para eu poder te ajudar.

Ótimo, agora que já cobrimos nossa primeira tela com testes, podemos seguir em frente. Antes, verifique se o seu código está parecido com o que está na branch ‘part_3’ do repositório.

Se tiver alguma dúvida, sugestão, ou se encontrou um erro no post, deixe um comentário abaixo. Na semana que vem eu volto com a quarta e última parte da série, na qual vamos mockar requisições para a API. Até lá!