Introdução
“Nunca teste a profundidade da água com ambos os pés”
–Autor anonimo(Tradução livre).
Esta frase tirada de um dos materiais consultados durante a elaboração deste post me fez pensar em que ela se aplica ao contexto de testes de software e cheguei a conclusão que ela é muito apropriada na medida que nos ensina duas coisas importantes sobre teste:
- Você deve ter um parâmetro de comparação, ou o objetivo do teste. (No caso o pé em terra firme).
- E que se você não possui esse objetivo claro, é fácil você se perder durante o planejamento e execução dos testes. ( Não conseguir medir por ser algo fundo demais).
Porquê testar? E porquê testar antes?
Inicialmente para garantir a qualidade do software. Mas porquê testar desde o começo? O desenvolvedor testar a aplicação desde o começo garante que o programa sempre atenderá aos critérios de funcionamento antes do lançamento do programa.
Tendo uma larga base de aparelhos ativados, a plataforma Android provê um grande potencial de uso para a sua aplicação. Mas se seu software não for bem desenvolvido, e/ou bem testado ele pode conter problemas que estragam uma boa ideia. E com o sistema de avaliações disponível na Google Play Store, dificilmente um aplicativo com uma imagem ruim devido a erros consegue se restabelecer.
Outro motivo para fazer os testes durante o desenvolvimento é o fato deste método possibilitar que as decisões de projeto sejam tomadas em pequenos passos, de modo a satisfazer um caso de teste de cada vez. Assim não é necessário que o desenvolvedor gaste muito tempo pensando em como desenvolver a solução antes do desenvolvimento, e pode fracionar este tempo para pensar em soluções simples de problemas menores.
E, por último, os desenvolvedores criarão os testes sempre, coisa que não ocorre quando se deixa pra testar no final se o programa não apresentar algum erro perceptível. E como os testes sempre são aplicados, o desenvolvedor fica mais responsável pelo código que criou.
Desenvolvimento baseado em testes
O Desenvolvimento baseado em testes, ou Test Driven Development (TDD), consiste basicamente dos seguintes passos:
- Escrever um caso de teste
- Executar todos os testes
- Se não passar, modifique o código e volte ao passo 1
- Se necessitar de refatoração, refatore e volte a passo 1
Ou como visto no diagrama:
Escrevendo um caso de testes
O primeiro passo do TDD é escrever um caso de testes que o programa deverá passar antes de ser declarado funcional. Esta etapa embora pareça simples é de vital importância para o sucesso do processo uma vez que para escrever um caso de testes você deverá compreender o domínio do problema e seus detalhes. Assim, provavelmente, ao escrever um caso de testes você visualizará partes do problema que não tinha compreendido ainda. Esta nova visualização do problema também facilitará os processos de modelagem e codificação.
Podemos considerar, que os primeiros casos de teste a serem escritos derivem dos requisitos do sistema, assim garantindo que o programa atenda os mesmos e seguindo o raciocínio explicitado anteriormente facilitando para que tenhamos uma melhor compreensão dos mesmos.
Esta tática também permite que o programa possa melhor se adaptar a mudanças de requisito, uma vez que quando escrevermos o caso de teste derivado do novo requisito o programa só passará o teste quando estiver cumprindo o requisito alterado, não deixando assim requisitos esquecidos em segundo plano.
Rodando os testes
Próxima etapa, hora de rodar todos os testes. Mas como rodar os testes se estivermos no primeiro ciclo e nenhum código foi escrito? Respeitando o ciclo vai acontecer o esperado, o teste vai falhar, ai então escreve-se código para passas no teste.
Na hora de escrever o código escrevemos só o suficiente para passar no teste. Assim escreveremos nosso programa tomando pequenas decisões para superar cada caso de teste.
Nesta etapa do desenvolvimento usar uma IDE que suporte bem testes pode economizar muito tempo do desenvolvimento. Como estamos desenvolvendo para Android usando Eclipse mas o plugin ADT esta parte não nos preocupará uma vez que o Eclipse suporta bem testes, e o ADT provê a API de testes para Android.
Refatorando o código
Após o código passar em todos os testes que garantam a satisfação dos requisitos, se possível, você deverá refatorar o código. A refatoração permite que você obtenha códigos minimais, eficientes e de fácil entendimento. Após a refatoração do código inserido, os testes devem ser refeitos para garantir que a refatoração não tenha gerado nenhum problema.
API de testes Android
A API de testes do Android possui algumas classes que facilitam os testes dos aplicativos desenvolvidos para esta plataforma. Segue agora uma lista com as principais classes e suas principais funcionalidades.
InstrumentationTestCase
Essa classe é usada direta ou indiretamente como classe base de outros testes. Tem como principais características:
- Inicializa a instrumentação antes do aplicação.
- Permite monitorar a interação.
- Consegue mandar sinais de teclas pressionadas e outros eventos de entrada.
- Controla o ciclo de vida de uma Activity manualmente.
ActivityUnitTestCase
Classe usada para testar uma Activity de forma isolada, possui conexão mínima com sistema. Suas principais características são:
- Usa Mocks (objetos que simulam outros) para resolver as dependências.
- Por possuir conexão mínima com o sistema alguns métodos da Activity não poderão ser invocados.
ActivityInstrumentationTestCase2
Classe que provê o teste funcional de uma activity. Possui como principais características:
- Possui acesso a instrumentação.
- Pode prover um Intent personalizado.
- Cria o AUT (ActivityUnitTest) usando a infraestrutura do sistema.
AndroidTestCase
Classe base para os Casos de Teste de Aplicação, Services e Providers. Suas principais características são:
- Possui acesso aos Contexts.
- Possui acesso aos Resoucers.
- O contexto é armazenado no campo mContext.
- Pode instanciar varias Activitys.
Projeto exemplo
Como exemplo de aplicação dos conceitos de TDD em desenvolvimento Android usaremos o mesmo exemplo de um dos materiais consultados. Faremos um simples, porém bem testado, conversor de temperaturas.
Seguiremos os passos básicos do desenvolvimento de um software começando com a analise dos requisitos e introduzindo as técnicas de desenvolvimento baseado em testes.
Começaremos analisando a lista de requisitos que o nosso conversor de temperaturas deve cobrir.
- Conversão Ceusius para Fahrenheit e vice-versa.
- A interface de usuário deverá possuir dois campos para temperatura, sendo um para temperatura em Ceusius e o outro para temperatura em Fahrenheit.
- Quando for digitada o valor em um dos campos o outro deve ser atualizado com o valor convertido.
- Se ocorrer erros os mesmos devem ser exibidos ao usuário, preferencialmente nos mesmos campos.
- A aplicação dever ter um espaço da tela reservado da tela para o teclado virtual não esconder algum dos campos.
- Os campos são inicializados com 0.
- A entrada sera dada por valores decimais com 2 dígitos após a virgula.
- Dígitos devem ficar alinhados a direita.
- O ultimo valor digitado deve ser mantido quando o programa entra em estado de pausa.
Também temos como base para o nosso projeto uma tela com o conceito de como nosso aplicativo deverá parecer.
Agora que já demos uma olhada nos requisitos vamos criar os projetos. Serão dois projetos, um principal onde o aplicativo será desenvolvido e outro que será o projeto de testes. No Eclipse você deverá criar um projeto, na janela de de novo projeto após preencher os dados básicos você deverá clicar em Next para poder criar o projeto de testes. Selecione a opção Create a Test Project e a Use default location. Os outros valores serão selecionados baseados nos valores escolhidos na tela anterior.
No próximo post iremos trabalhar sobre o ambiente TDD integrado a um projeto Android.
Referencias
Foram usadas como referencias basicamente os materiais disponibilizados pelo Milano bem como o livro escrito pelo mesmo. Segue abaixo os materiais consultados que não só serviram de referencia para este post como de inspiração.
Diego Torres Milano: Android Application Testing Guide
Diego Torres Milano: Android Application Testing: TDD and the Temperature Converter (http://www.packtpub.com/article/android-application-testing-tdd-temperature-converter)
Diego Torres Milano: Introduction to Android Testing – A hands-on approach OSCON 2012 (http://dtmilano.blogspot.com)