Mudanças entre as edições de "Padrão de Desenvolvimento - Testes Unitários"
(Criou página com '== Como escrever um bom teste unitário == '''Princípio Básico:''' Sempre utilizar Test Driven Development (TDD) para criação de novos códigos Caso você já tenha con...') |
|||
Linha 1: | Linha 1: | ||
+ | [[Padrões de Desenvolvimento|'''Voltar''']] | ||
+ | <br/><br/> | ||
== Como escrever um bom teste unitário == | == Como escrever um bom teste unitário == | ||
'''Princípio Básico:''' Sempre utilizar Test Driven Development (TDD) para criação de novos códigos | '''Princípio Básico:''' Sempre utilizar Test Driven Development (TDD) para criação de novos códigos |
Edição das 14h37min de 4 de maio de 2021
Índice
Como escrever um bom teste unitário
Princípio Básico: Sempre utilizar Test Driven Development (TDD) para criação de novos códigos
Caso você já tenha conhecimento do TDD, isso já é 80% do caminho para que seu teste seja bem escrito. Mas para que o princípio do TDD seja complementado e então os testes sejam melhores organizados e menos propensos a falhas é recomendável seguir os três princípios abaixo:
- Crie o cenário, popule o(s) objeto(s) a serem utilizados no seu teste
- Execute a unidade a ser testada
- Verifique se o teste é aprovado através dos asserts
Tendo em mente os princípios citados acima vemos no código abaixo um exemplo de código que os demonstra:
class Avaliador { private double maiorDeTodos = Double.NEGATIVE_INFINITY; private double menorDeTodos = Double.POSITIVE_INFINITY; public void avalia(Leilao leilao) { for(Lance lance : leilao.getLances()) { if(lance.getValor() > maiorDeTodos) { maiorDeTodos = lance.getValor(); } else if(lance.getValor() < menorDeTodos) { menorDeTodos = lance.getValor(); } } } public double getMaiorLance() { return maiorDeTodos; } public double getMenorLance() { return menorDeTodos; } } |
import org.junit.Assert; class AvaliadorTest { @Test public void deveEntenderLancesEmOrdemCrescente() { //1 - populando o objeto Usuario joao = new Usuario("Joao"); Usuario jose = new Usuario("José"); Usuario maria = new Usuario("Maria"); Leilao leilao = new Leilao("Playstation 3 Novo"); leilao.propoe(new Lance(maria,250.0)); leilao.propoe(new Lance(joao,300.0)); leilao.propoe(new Lance(jose,400.0)); //2 - Executando a unidade a ser testada Avaliador leiloeiro = new Avaliador(); leiloeiro.avalia(leilao); double maiorEsperado = 400; double menorEsperado = 250; //3 - Verificando se o teste é aprovado através dos asserts Assert.assertEquals(maiorEsperado, leiloeiro.getMaiorLance(), 0.0001); Assert.assertEquals(menorEsperado, leiloeiro.getMenorLance(), 0.0001); } } |
Nomenclatura e localização da classe de teste
Nome das classes
Toda classe de teste deve ter a como nome o mesmo nome que foi utilizado na classe origem seguido do sufixo "Test". Desta forma temos o seguinte exemplo:
Classe de Origem: DoadorDao
Classe de Teste: DoadorDaoTest
Nome do método
O nome do teste sempre deve ter a ver exatamente com o que é testado dentro dele de forma que quem o ler saiba exatamente o que está sendo verificado, sem a necessidade de entender o que foi codificado no teste. Veja o exemplo:
Método de origem: salva()
Método de teste: salvaNomeNulo()
Atenção: Verifique todas as possibilidades, não somente o "Caminho Feliz =D"
No exemplo anterior utilizamos uma classe de leilão. Dentro desta classe é possível verificar que os objetos de Usuário e Leilão são populados e posteriormente testados, mas não há nenhum tipo de previsão no código para caso haja algum tipo de excessão ou erro. Ou seja, caso o valor do lance seja nullo ou menor que zero nosso sistema gerará uma excessão. Desta forma torna-se necessário realizar testes para todos os caminhos possíveis em nosso código antes de então ele ser dado como testado. Verifique no exemplo com um teste mais abrangente:
import org.junit.Assert; class AvaliadorTest { @Test public void deveEntenderLancesEmOrdemCrescente() { //1 - populando o objeto Usuario joao = new Usuario("Joao"); Usuario jose = new Usuario("José"); Usuario maria = new Usuario("Maria"); Leilao leilao = new Leilao("Playstation 3 Novo"); leilao.propoe(new Lance(maria,250.0)); leilao.propoe(new Lance(joao,300.0)); leilao.propoe(new Lance(jose,400.0)); //verificação do caminho infeliz =\ Assert.assertNotNull(leilao.getPropostas()); //2 - Executando a unidade a ser testada Avaliador leiloeiro = new Avaliador(); leiloeiro.avalia(leilao); double maiorEsperado = 400; double menorEsperado = 250; //3 - Verificando se o teste é aprovado através dos asserts Assert.assertEquals(maiorEsperado, leiloeiro.getMaiorLance(), 0.0001); Assert.assertEquals(menorEsperado, leiloeiro.getMenorLance(), 0.0001); } } |
Utilização da classe Assert
A classe assert tem todos os métodos necessários para realizar os testes do projeto, desta forma evite fazer comparações boleanas utilizando o método assert. Exemplo de má utilização:
Assert.assertTrue(leilao.getPropostas() != null);
Material Complementar
- Test-driven development,IBM Cloud Garage Method, 2017.
- Escreva Testes Melhores em 5 Passos, ThoughWorks, 2014.