você está aqui: Home  → Arquivo de Mensagens

Dicas de Programação - Como fazer um bom teste unitário?

Colaboração: Ricardo Takemura

Data de Publicação: 05 de fevereiro de 2016

Para quem não sabe o que é um teste unitário...

Define-se "teste unitário", em síntese, todo teste feito na menor unidade de uma aplicação (por exemplo, em funções e/ou procedimentos (código-fonte) de um programa).

Dadas as explicações, agora voltamos a pergunta: Como fazer um bom teste unitário? Antes de fazer um teste unitário, existem algumas coisas a se pensar:

Primeiro, precisamos definir o domínio da função ou procedimento (Hã? Matemática?), ou seja, definir um conjunto de valores válidos ("entrada") para esta função.

Se definimos o domínio, agora precisamos definir o contra-domínio desta (Matemática de novo? Isso não deveria ser informática? :P ), em termos gerais, vamos definir um conjunto de valores válidos para o resultado ("saída") da função.

Para os matemáticos de plantão, isso significa que na função y = F(x), se x pertence ao domínio da função, então y pertence ao contra-domínio. Se x não pertencer ao domínio, então y não é um resultado válido.

Para facilitar as coisas, vamos ao exemplo:

Vamos criar uma função que calcula a média de notas de duas provas (a primeira de peso um, a segunda de peso dois) em uma escola:

  function media(primeira: integer, segunda: integer): integer
     media = (primeira + 2 * segunda) / 3;
  
  //Teste Unitário
  ...
  var resultado: integer;
  resultado = media(5,5);
  assertEquals(resultado, 5);
  ...

Parece que a função calcula corretamente e que o teste unitário esta passando, certo?

Errado! :P

Hã, como assim?

Vamos a alguns questionamentos que podem existir:

  • Existe nota negativa?
  • Existe nota maior que 10?
  • Existe nota com valor "quebrado" (5.5, por exemplo)?
  • Se não existe, a nota deve ser arredondada para cima ou para baixo? A partir de que valor?

Perceba que, como não foi definido um conjunto de valores válidos de entrada (domínio) e saída (contra-domínio), ficamos com um monte de dúvidas e não sabemos os valores que devemos testar...

Agora, se definirmos o domínio desta função:

As variáveis "primeira" e "segunda" pertence ao conjunto dos números inteiros, tal que, "primeira" e "segunda" são valores maiores ou iguais a 0 e menores ou iguais a 10.

E o contra-domínio desta:

O resultado da função pertence ao conjunto dos números inteiros, tal que, este é um valor maior ou igual a 0 e menor ou igual a 10, sendo resultante do seguinte calculo (primeira + 2 * segunda) / 3, com valores arredondados para baixo, em caso de um resultado pertencente ao conjunto dos números reais.

Agora que sabemos quais os valores são válidos e não válidos para a função, podemos definir os seguintes testes:

  //Valores maiores que 10 (domínio)
  ...
  try
     resultado = media(11,21);
     fail();
  except
     assertTrue(true);
  ...
  
  //Valores menores que 0 (dominio)
  ...
  try
     resultado = media(-1,-1);
     fail();
  except
     assertTrue(true);
  ...
  
  //Valor com um resultado quebrado (contra-domínio)
  ...
  resultado = media(2,7);
  assertEquals(resultado, 5);
  ...

Isso tornar o teste unitário um pouco mais "eficaz".



Veja a relação completa dos artigos de Ricardo Takemura