carrinho.Adiciona(new Produto("Geladeira", 450.0));
carrinho.Adiciona(new Produto("Jogo de pratos", 70.0));
MaiorEMenor algoritmo = new MaiorEMenor();
algoritmo.Encontra(carrinho);
Console.WriteLine("O menor produto: " +
algoritmo.Menor.Nome);
Console.WriteLine("O maior produto: " +
algoritmo.Maior.Nome);
}
}
7
2.3. O Primeiro Teste de Unidade
Casa do Código
O carrinho contém três produtos: liquidificador, geladeira e jogo de pratos. É
fácil perceber que o jogo de pratos é o produto mais barato (R$ 70,00), enquanto
que a geladeira é o mais caro (R$ 450,00). A saída do programa é exatamente igual
à esperada:
O menor produto: Jogo de pratos
O maior produto: Geladeira
Apesar de aparentemente funcionar, se esse código for para produção, a loja vir-
tual terá problemas.
2.3
O Primeiro Teste de Unidade
A classe MaiorEMenor respondeu corretamente ao teste feito acima, mas ainda não
é possível dizer se ela realmente funciona para outros cenários. Observe o código
abaixo:
public class TestaMaiorEMenor
{
static void main(String[] args)
{
CarrinhoDeCompras carrinho = new CarrinhoDeCompras();
carrinho.Adiciona(new Produto("Geladeira", 450.0));
carrinho.Adiciona(new Produto("Liquidificador", 250.0));
carrinho.Adiciona(new Produto("Jogo de pratos", 70.0));
MaiorEMenor algoritmo = new MaiorEMenor();
algoritmo.Encontra(carrinho);
Console.WriteLine("O menor produto: " +
algoritmo.Menor.Nome);
Console.WriteLine("O maior produto: " +
algoritmo.Maior.Nome);
}
}
O código acima não é tão diferente do anterior. Os produtos, bem como os va-
lores, são os mesmos; apenas a ordem em que eles são inseridos no carrinho foi tro-
cada. Espera-se então que o programa produza a mesma saída. Mas, ao executá-lo,
temos uma exceção.
8
Casa do Código
Capítulo 2. Testes de Unidade
Problema!
Essa não era a saída esperada!
Agora está claro que a classe
MaiorEMenor não funciona bem para todos os cenários. Se os produtos, por algum
motivo, forem adicionados no carrinho em ordem decrescente, a classe não consegue
calcular corretamente.
Uma pergunta importante para o momento é: será que o desenvolvedor, ao es-
crever a classe, perceberia esse bug? Será que ele faria todos os testes necessários
para garantir que a classe realmente funciona?
Como discutido no capítulo anterior, equipes de software tendem a não testar
software, pois o teste leva tempo e, por consequência, dinheiro. Na prática, equi-
pes acabam por executar poucos testes ralos, que garantem apenas o cenário feliz e
mais comum. Todos os problemas da falta de testes, que já foram discutidos ante-
riormente, agora fazem sentido. Imagine se a loja virtual colocasse esse código em
produção. Quantas compras seriam perdidas por causa desse problema?
Para diminuir a quantidade de bugs levados para o ambiente de produção, é ne-
cessário testar o código constantemente. Idealmente, a cada alteração feita, todo o
sistema deve ser testado por inteiro novamente. Mas isso deve ser feito de maneira
sustentável: é impraticável pedir para que seres humanos testem o sistema inteiro a
cada alteração feita por um desenvolvedor.
A solução para o problema é fazer com que a máquina teste o software. A má-
quina executará o teste rapidamente e sem custo, e o desenvolvedor não gastaria mais
tempo executando testes manuais, mas sim apenas em evoluir o sistema.
Escrever um teste automatizado não é tarefa tão árdua. Ele,
na verdade, se parece
muito com um teste manual. Imagine um desenvolvedor que deva testar o compor-
tamento do carrinho de compras da loja virtual quando existem dois produtos lá ca-
dastrados: primeiramente, ele clicaria em comprar em dois produtos, em seguida
iria para o carrinho de compras, e por fim, verificaria a quantidade de itens no
carrinho (deve ser 2) e o o valor total do carrinho (que deve ser a soma dos dois
produtos adicionados anteriormente).
Ou seja, de forma generalizada, o desenvolvedor primeiro pensa em um cenário
(dois produtos comprados), depois executa uma ação (vai ao carrinho de compras),
e por fim, valida a saída (vê a quantidade de itens e o valor total do carrinho). A
figura abaixo mostra os passos que um testador geralmente faz quando deseja testar
uma funcionalidade.
9
2.3. O Primeiro Teste de Unidade
Casa do Código
Um teste automatizado é similar. Ele descreve um cenário, executa uma ação
e valida uma saída. A diferença é que quem fará tudo isso será a máquina, sem
qualquer intervenção humana.
De certa forma, um teste automatizado já foi escrito neste capítulo. Veja o código
abaixo, escrito para testar superficialmente a classe MaiorEMenor:
public class TestaMaiorEMenor
{
static void main(String[] args) {
CarrinhoDeCompras carrinho = new CarrinhoDeCompras();
carrinho.Adiciona(new Produto("Geladeira", 450.0));
carrinho.Adiciona(new Produto("Liquidificador", 250.0));
carrinho.Adiciona(new Produto("Jogo de pratos", 70.0));
MaiorEMenor algoritmo = new MaiorEMenor();
algoritmo.Encontra(carrinho);