Android Testing- Parte 1 (Arquitectura)

No post anterior falei sobre como utilizar o Firebase Crash Reporting para que possamos ter um relatório dos erros/excepções que os utilizadores costumam encontrar depois da app ser publicada no playstore.

Apesar do poder oferecido por esta ferramenta, se a nossa aplicação tiver vários erros e recorrentes, os utilizadores continuarão a ter uma péssima experiência e o Crash Reporting apenas irá nos mostrar o quão maus programadores nos somos.

Como podemos garantir que uma app tem o menor número de erros possíveis?

Garantir que uma aplicação tenha uma alta qualidade com o menor número de erros possíveis requer simplesmente que esta seja devidamente testada.

O android possui a biblioteca android Android Testing Support library que oferece ferramentas necessárias para realizar testes Unitários e Instrumentais em uma aplicação android.

Testes Unitários | UnitTests

Os testes unitários (de agora em diante unit tests) são testes em que nos preocupamos apenas em testar a funcionalidade de uma pequena parte do nosso código de forma independente do resto das outras funções existentes.

Se tomarmos como exemplo a calculadora que esta no nosso dispositivo, poderíamos utilizar unit tests para testar a funcionalidade das diferentes operações que esta pode realizar (soma, multiplicação, subtracção, etc) de forma independente uma das outras.

Teste Instrumentais | Instrumental Tests

Os testes instrumentais(de agora em diante instrumental tests) permitem que possamos testar se os componentes da nossa interface gráfica estão a comportar-se como esperado ao receber uma determinada interacção do utilizador. Exemplo: Ao invés de executar a app e fazer manualmente, podemos escrever testes que verificam o que acontece sempre que um botão é clicado ou se o texto é passado devidamente a um TextView entre outros tipos de interações.

Escrever testes é muito importante para garantir a boa qualidade de uma aplicação mas é ainda mais importante saber como escrever bons testes.
Sendo assim, o desenvolvimento de uma aplicação deve começar tendo em conta que serão necessários escrever testes e não decidir no meio do projecto só porque alguém(como Eu ) disse que era bom.

É preciso garantir que a aplicação tem as devidas fundações sólidas antes mesmo de escrever qualquer linha de código.

Arquitectura de uma app Android

A alguns anos atrás quando comecei a desenvolver apps para android lembro-me que o que sempre fiz foi abrir o eclipse na altura, utilizar o wizzard e criar um novo projecto onde com o meu conhecimento limitado sobre Activities e Fragments aventurava-me a escrever código a torta e a direita para que tivesse algo a mostrar na UI e realizar alguma operação ao interagir com ela. 
Tamanha ingenuidade, resultou em alguns projectos não muito maus mas com muito código junto, complexo e extremamente dificil de manter e muito menos testar.

Para evitar que muitos “Eus” no passado fossem replicados e tornar um mundo de desenvolvedores melhor, vários padrões de arquitecturas de software foram criados para garantir que:

  • Possamos fazer a devida separação de responsabilidades as diferentes componentes de um software .
  • Tenhamos um código limpo e fácil de manter.
  • Tenhamos um código fácil de testar.

Existem vários padrões de arquitectura de software como a arquitectura em camadas, Model-View-Controller(MVC), Model-View-Presenter(MVP), Model View View Model(MVVM) etc.

Para escrever sobre cada um desses padrões seriam necessários posts dedicados e por esse motivo, neste post iremos focar-nos só no MVP.
(Link para um ebook que achei interessante sobre o tema)

Model View Presenter(MVP)

O Model-View-Presenter(doravante denominado apenas por MVP) é um padrão de arquitectura de desenvolvimento de software que pressupõe que um determinado software terá 3 componentes distintas nomeadamente:

Model

O Model é responsável pela representação dos dados e os mecanismos de leitura e escrita de dados. 
Tomando como exemplo uma simples aplicação de e-commerce, teríamos como o Model as classes que representam os Items e o repositório de dados de onde estes são escritos ou lidos.(Repositório = API, Internal Storage, Ficheiro ,etc).

View

O view como o nome já sugere, é a componente responsável por lidar com a apresentação da informação ao utilizador a partir da interface gráfica (Desenhar os componentes, actualizar os valores entre outras operações).

Presenter

O presenter é o componente intermediário entre o View e o Model. 
O seu maior papel é garantir que a informação que ele recebe do model, é devidamente processada antes de ser apresentada ao utilizador e assim como o processo inverso de processamento da informação inserida pelo utilizador antes desta ser armazenada no Model.

Levando o MVP para o Android, este padrão permite que tenhamos uma separação muito definida daquilo que são os limites de actuação de componentes como Fragment e Activities garantindo que estes actuem apenas como Views responsáveis por realizar operações de Interface gráfica para apresentar a informação aos utilizadores.

Como mostra a imagem acima, a comunicação entre os componentes é feita por meio de implementação de interfaces permitindo que cada um dos componentes tenha a sua implementação independente de todos os outros, isto é, a View não sabe sobre como está implementado o Presenter e desde que qualquer Presenter implemente a interface que define o contracto de comunicação com ela, esta continuará a funcionar como esperado.

Com esta separação muito clara dos papéis , já podemos facilmente escrever testes instrumentais que testem a interacção da interface gráfica isolados dos testes unitários que testem as funcionalidades do presenter.

E com a breve introdução sobre o Testes no android e o MVP terminamos mais um post, com a esperança de que irei entrar em mais detalhes e mostrar como é uma aplicação com a arquitectura MVP no próximo post!

Ate a próxima :)

DM