Confira nossa série sobre testes automatizados no Android:
- Por que devo testar minhas aplicações
- Testes automatizados no Android
- Ambiente controlado para testes – Parte 1: Mockito e Injeção de dependência
- Ambiente controlado para testes – Parte 2: MockWebserver
- Ambiente controlado para testes – Parte 3: Testando run time permissions no Espresso
- UI tests – Espresso + Robot Pattern
- Usos práticos da suíte de testes – Jacoco e CI
Testes de UI
Os testes de UI são parte importantíssima na garantia de que um aplicativo segue funcional. Eles basicamente tentam reproduzir o que seria feito por um humano em testes manuais. Eles são mais custosos pois precisam de um emulador ou de um device Android para serem executados e fazem uma série de interações com a tela, que apesar de serem mais rápidas que a interação normal de um ser humano interagindo com o aplicativo, ainda assim levam certo tempo.
A grande vantagem desse tipo de teste, é que ele de fato emula um usuário final utilizando seu aplicativo. Portanto quando bem escritos, testes de tela pegam rapidamente falhas de funcionamento e quebras de expectativa do usuário no aplicativo. A ferramenta mais utilizada para a criação desses testes é o Espresso, que te permite fazer interações com a tela da mesma forma que um usuário, só que via código.
Conhecendo o Espresso
Através do Espresso, fica muito simples fazer interações com a tela como um clique em um botão por exemplo. São duas etapas necessárias:
Primeiro você precisa selecionar o item com qual gostaria de interagir. Uma das formas mais comuns de fazer isso, é através do id do componente definido no xml.
Depois definimos qual interação que gostaríamos de fazer com o componente. Para fazer o click podemos usar o seguinte código:
Além de ações com os componentes, podemos também fazer verificações, como por exemplo verificar se um componente está visível como no trecho abaixo:
Ou até mesmo atuar em algumas funções da tela, como fechar o teclado por exemplo:
Robot Pattern
O código do Espresso é relativamente simples, mas em testes maiores ou mais complexos, pode se tornar repetitivo ou mesmo difícil de ler. Para melhorar a organização dos testes e também evitar código duplicado, foi criado por Jake Wharton, um Pattern para testes de tela chamado Robot.
A ideia desse pattern é omitir dos testes a parte complexa de como interagir com os componentes da tela. Essa responsabilidade fica para a classe robot, que dá acesso a métodos bem mais intuitivos e diretos como “enterTextIntoView” ou em um robot específico de uma tela de login por exemplo, poderíamos ter um método “inputPassword”.
É bacana que seja definido uma robot base que faz as coisas de forma genérica do tipo “clickIntoButton”, “enterTextIntoView”, que vão ter as lógicas do Espresso, e ter robots para cada tela, que estendem do robot base que terão as informações específicas da tela em questão como ids e mensagens que serão usadas para os asserts e as interações específicas do fluxo da tela que será testada.
Uma outra “sacada” desse pattern, é o uso de um formato vindo de outro pattern, o build pattern. Todos os métodos retornam a própria classe, permitindo assim que várias chamadas de métodos sejam feitas em sequência, deixando o código ainda mais limpo:
Conclusão
E é isso! Combinando Espresso com Robot pattern, construir testes de tela fica muito mais simples e rápido! Você só vai precisar focar na sua regra de negócio e nos cenários que pretende testar, e não em detalhes de implementação do Espresso, pois os robots já farão o “trabalho sujo” para você. Além de tudo, os códigos dos seus testes ficam super auto explicativos e mesmo alguém que nem conheça a tela que está sendo testada, facilmente entenderia qual o fluxo que está sendo testado só de olhar o código de teste, que fica super simplificado.
Lembrando que esse tipo de pattern não é exclusivo para o Espresso, para Android ou até mesmo para testes de tela. Para qualquer situação onde você tem códigos repetitivos e que não tem tanta relevância em um determinado contexto, vale analisar a possibilidade de extrair para uma classe separada que “esconderia” essa complexidade desnecessária naquele contexto.