Blog > Integração Contínua para Testadores - Parte 2

12/nov

Nesta segunda parte sobre Integração Contínua para Testadores falaremos sobre Testes de Unidade, como eles funcionam no ciclo de integração contínua e como tirar proveito, como testador, das falhas encontradas efetuando uma análise para criar mais testes e dar suporte o time de desenvolvimento.

Introdução

Neste segundo post da séria Integração Contínua para Testadores aprenderemos a como analisar os resultados de uma ferramenta de integração contínua, como interpretá-los e como ajudar o programador a desenvolver e pensar mais em teste.

Jenkins

Jenkins é um sistema que implementa os conceitos de Integração Contínua. É através dele que na maioria dos casos, de forma automática, todo o processo de build, testes e deploy será executado. Ele provê um painel onde os projetos, que são chamados de jobs, são apresentados e um indicativo visual nos dá o feedback de sucesso ou falha daquele projeto (job).

É possível analisar mais detalhadamente o resultado dos jobs e comparar dados históricos da execução dos testes.

Como é o processo de execução de Testes de Unidade em um Ambiente de Integração Contínua? 

A execução dos Testes de Unidade é feito automaticamente geralmente por um Sistema de Build. Sistemas de Build criam algum tipo de abordagem de configuração para que tarefas dentro do desenvolvimento do software sejam feitas de forma automática, como o processo de compilação do código-fonte ou mesmo a execução dos testes unitários. Os sistemas mais conhecidos são ANTMavenGradle.

Nos exemplos que veremos utilizaremos o Maven.

No projeto configurado como exemplo, e também disponível no GitHub da Qualister, a configuração de execução dos testes são todos os testes que contém o texto UnitTest.java.
Este processo é executado durante a build do projeto e acionado quando informamos ao Maven que queremos executar um teste (palavra-chave test no Build Lifecycle do Maven)

Os testes podem ser executados da mesma forma na máquina de qualquer pessoa do time, e é feito durante o desenvolvimento do software. Lembre-se que a execução pelo Jenkins é a do código-fonte integrado com os dos outros desenvolvedores.

Como os resultados são apresentados ao time?

Duas são as formas de apresentação dos resultados da build e execução dos testes:

  • Ícone de Status no painel geral do Jenkins
  • Resultados de Teste dentro do projeto (job)

O Ícone de Status no painel geral do Jenkins é apresentado no Dashboard, com as possíveis cores informativas:

  • Azul para sucesso
  • Vermelho para erro no processo de build
  • Amarelo como instável (algum teste executou com falha)

Os Resultados de Teste dentro do projeto (job) são resultados da execução de teste. Eles são agregados automaticamente e, a cada build/execução, mostram a base histórica em comparação com as outras execuções. Há um gráfico geral e é possível verificar cada teste.

Nota para o testador

Você pode ver o detalhe dos erros ou saber exatamente os testes que executaram. Isso pode te auxiliar para visualizar o cenário de teste atual e criar mais testes para aumentar a cobertura do código. Mas lembre-se que o "criar mais testes" é apenas o caso de teste. O programador irá implementar o teste unitário.

Cobertura de Código, saiba tirar proveito dela

Uma ótima forma de ajudar o programador a melhorar a qualidade do código, remover gaps e aumentar ainda mais a cobertura de teste e confiabilidade na aplicação (a famosa "rede de segurança") é analisar a cobertura de código.

Atenção: eu (Elias Nogueira) não julgo correto analisar a cobertura de código colocando uma meta de cobertura, pois a mesma pode ser facilmente alterada/mascarada e pode criar testes que não trazem valor para o negócio

No exemplo a seguir veremos como analisar a cobertura de código proveniente de uma ferramenta chamada Emma, que apresenta além de indicadores sobre a cobertura, também apresenta os trechos de código-fonte que não estão cobertos por testes.

O projeto contido no GitHub, que classifica um triângulo através de seus lados, apresenta o seguinte código:

Note que há 5 possíveis testes (nós testadores conseguimos enxergar isso fácil, não é mesmo?):

  • Se um dos lados é nulo
  • Se um dos lados é menor ou igual a zero
  • Se o triângulo é equilátero (três lados iguais)
  • Se o triângulo é isósceles (dois lados iguais)
  • Se o triângulo é escaleno (todos os lados diferentes)

Como um testador que se preocupa com a qualidade (e qualidade não é somente teste manual ou automatizado na interface gráfica, também é qualidade de código) eu iria analisar o relatório da cobertura de código.  E eis que ele está abaixo:

Podemos ver no relatório que o pacote br.com.qualister.triangulo não está 100% coberto por testes. Isso não quer dizer que, a principio, esteja bom ou ruim. Primeiro precisamos analisar.
A cobertura de testes que está sendo aplicada na classe TrianguloNaoPreenchidoException.java é de 0% (sem cobertura) e da classe Triângulo.java (do código acima) é de 100% para a classe, 50% para os métodos e 75% para linha. Isso ainda não nos diz muita coisa.

É preciso então uma ação mais apurada. Clicando no link dentro do relatório para a classe Triângulo.java podemos ver isso:

Agora nós temos uma noção maior da cobertura de testes para a classe Triângulo.java.
Dois dos possíveis testes a serem aplicados (e que deveriam) não foram desenvolvidos: se um dos lados é nulo e se um dos lados é menor ou igual a zero.

Agora já temos subsídios para conversar com o programador e sugerir alguns testes....

Se você desejar acessar o mesmo relatório apresentado nas telas acima, utilize o seguinte link:
http://qualister.info/posts_blog/integracao-continua-testadores/emma/

Pareamento, uma ferramenta poderosa para entender os Testes Unitários e criar mais testes

Com base na nossa análise podemos agora conversar com o programador e mostrar o que nós encontramos de gap. Vamos resumir em:

  • Está faltando teste para quando um dos lados for nulo
  • Está faltando teste para quando um dos lados for menor ou igual a zero

Neste momento é a hora de conversar com o programador e apresentar estes gaps. Conversar com ele sobre novas possibilidades de teste e pedir para que ele implemente estes testes. Podemos aproveitar também para analisar outros testes que ele estava fazendo ou mesmo terminando, não com o sentido de verificar se ele fez ou não fez mas com o intuito de melhorar a qualidade do código. E isso pode previnir muitos defeitos futuros.

Este pareamento pode nos trazer diversos benefícios...

Aprendizado mútuo
Apenas pareando e passando a nossa visão de teste o programador começa a pensar diferente.
Ele poderia pensar em apenas criar um teste validando somente um dos lados como nulo, mas na visão do testador teremos que testar todos os lados nulos (os três).
O testador pode aprender algum aspecto importante daquela funcionalidade e, o mais importante, diminuir a barreira da comunicação.

Resolução de problemas de forma colaborativa
Há problemas que parecem semelhante não é? Durante um pareamento podemos lembrar de um mesmo modo de operação/utilização de uma funcionalidade que já tinha um defeito antes. Isso pode nos levar a investigar a causa raiz do por que ocorreu aquele defeito ou simplesmente criar mais um teste para previnir que ele ocorra.

Resumo

Neste segundo post tivemos um olhar com um foco maior em garantia de qualidade. Nós conseguimos ajudar o programador e o time como um todo a melhorar ainda mais o código em fase de criação e execução de testes unitários apenas fazendo algumas análises:

  • Analisando os indicadores básicos do dashboard do sistema de gerenciamento de integração contínua e resultados de teste
  • Analisando os relatórios de cobertura de código, a fim de ajudar o programador a preencher possíveis gaps de teste unitário

Até o próximo post!

POSTS RELACIONADOS

AGENDA

CURSOS RELACIONADOS