O que a quantidade de asserts em um teste nos diz sobre o código?

O que a quantidade de asserts em um teste nos diz sobre o código?
maniche
maniche

Compartilhe

Todo teste pode ser separado em três: a parte onde você monta o cenário, a parte onde você executa a ação que quer testar, e a parte que você valida que a ação aconteceu da maneira esperada. Por exemplo, veja o código abaixo:

 @Test public void deveCalcularNF() { // 1o: cenário NotaFiscal nf = new NotaFiscal("Mauricio", 2000.0);

// 2o: ação double imposto = nf.calculaImposto();

// 3o: validação assertEquals(250.0, imposto, 0.00001); } 

A quantidade de "asserts" pode ser ilimitada. Podemos ter 1 (como no código acima), 2, 3, ou quantos mais precisarmos. Entretanto, quanto mais código em um método de teste, pior sua legibilidade. Portanto, é fácil perceber que, quanto mais asserts em um teste, mais difícil é lê-lo e entendê-lo.

Banner da Escola de Inovação e Gestão: Matricula-se na escola de Inovação e Gestão. Junte-se a uma comunidade de mais de 500 mil estudantes. Na Alura você tem acesso a todos os cursos em uma única assinatura; tem novos lançamentos a cada semana; desafios práticos. Clique e saiba mais!

Mas uma pergunta cuja resposta pode ser interessante é: será que o desenvolvedor foi "forçado" a escrever muitos asserts porque o código de produção que está sendo testado (em nosso caso, o calculaImposto()) não está bem feito?

Após executarmos um experimento controlado em alguns projetos de código aberto da Apache, concluímos que: não, a baixa qualidade do código de produção não implica em um maior número de asserts por teste.

Mas, durante o experimento, percebemos que contar a quantidade de asserts pode não ser uma boa ideia. Às vezes o desenvolvedor faz uso de mais de um assert porque o objeto foi modificado em mais de um atributo. Por exemplo:

 assertEquals(200.0, nf.getImpostoA(), 0.0001); assertEquals(250.0, nf.getImpostoB(), 0.0001); 

Um outro desenvolvedor poderia ter implementado o teste, usando um assertEquals() apenas, e comparando o objeto inteiro:

 assertEquals(nfEsperada, nf); 

Ou seja, aqui é mais ou menos questão de gosto do desenvolvedor. Nesse momento, levantamos uma outra hipótese: talvez contar a quantidade de asserts não faça sentido, mas sim contar a quantidade de objetos diferentes que recebem asserts em um mesmo teste. Por exemplo, veja o código abaixo, onde temos 3 asserts, mas em 2 objetos diferentes:

 assertEquals(100.0, nf1.getImpostoA()); assertEquals(100.0, nf1.getImpostoB()); assertEquals(250.0, nf2.getImpostoA()); 

Se verificarmos a relação entre a "quantidade de objetos que receberam asserts em um teste" e "qualidade do código de produção", descobrimos que: sim, um código de produção problemático pode implicar em mais de um objeto recebendo assert no teste!

Isso é interessante! Quando o código de produção é muito complicado, os desenvolvedores muitas vezes preferem escrever menos testes, mais complexos, e testar diferentes entradas. Isso serve como um ótimo feedback para você desenvolvedor: se você está fazendo asserções em mais de um objeto, olhe seu código de produção; ele pode ter problemas!

Este trabalho foi apresentado no CSMR 2013, em Gênova, e é uma pequena parte da minha pesquisa de doutorado. Muito do que aprendi está no meu livro sobre TDD e nos cursos de testes automatizados online.

Veja outros artigos sobre Inovação & Gestão