- Vermelho: escrever um teste que não funciona;
- Verde: fazer o teste passar, escrevendo uma pequena mudança no código, mesmo que não seja a mais adequada;
- Refatora: melhorar o código, eliminando todas as duplicidades e mantendo-o verde.
Ao meu ver a essência está correta, porém talvez faltasse deixar claro que TDD não se trata apenas de escrever testes antes do código. Esta é a primeira visão que a maioria dos iniciantes têm sobre desenvolvimento orientado a testes: que basta escrever todos os testes antes e pronto. Isto é compreensível, já que escrever testes antes do código já causa um choque por si só. Porém, TDD foi definido pelo Kent Beck com a seguinte fórmula:
TDD = Test-First + Design Incremental
E a parte do design incremental ficou um pouco confusa na continuação do texto:
‘…O processo de desenvolvimento usando TDD é muito simples:
1 - Escolha a classe e o método que você que codificar e pense em todos os testes possíveis para ela;
2- Antes de escrever a classe, codifique os testes que você pensou…’
Seguindo estas instruções (escrever todos os testes possíveis antes) pode-se perder um pouco de um dos maiores benefícios de TDD, que é prover feedback rápido sobre o que está sendo implementado. Aí que entra o design incremental. A ideia é que a solução seja criada em pequenos passos (Baby Steps), seguindo a rotina descrita no livro TDD by Example:
1 - Escreva um pequeno teste que falhe, e talvez até mesmo sequer compile inicialmente;
2 - Faça o teste passar da maneira rápida, cometendo qualquer ‘pecado’ durante este processo;
3 - Refatore: elimine toda duplicação criada para fazer os testes passarem.
Desta forma, não é preciso pensar na solução completa (sequer numa classe inteira) antes de começar, basta pensar em um teste apenas e fazê-lo passar. Com o conhecimento adquirido é possível então passar para o próximo teste com mais segurança, e assim avançar até que a solução esteja completa.
Outra noção comum é pensar que TDD trata apenas de testes de unidade.Embora sejam bem pontuais, observar estes detalhes pode ajudar no uso mais eficiente de TDD.”
Para iniciar o planejamento dos testes, temos que partir de um problema específico e usaremos um caso clássico denominado problema FizzBuzz. O FizzBuzz consiste em exibir uma lista de 1 a 30, um em cada linha, e filtrar todos os números respeitando as regras:
Retorno do Fizz Buzz |
números divisíveis por 5 devem retornar “Buzz”
números divisíveis por 3 e 5 devem retornar “FizzBuzz”
Fonte: Elaborado pela autora
Antes de começar a escrever os testes, é preciso definir o que precisa ser testado, para isso deve-se criar uma lista com todos os testes que sejam necessários. No nosso utilizaremos a seguinte lista para os testes:
[1] Retornar 1 ao passar 1;
[2] Retornar 2 ao passar 2;
[3] Retornar Fizz ao passar 3;
[4] Retornar 4 ao passar 4;
[5] Retornar Buzz ao passar 5;
[6] Retornar Fizz ao passar 6;
[7] Retornar 7 ao passar 7;
[8] Retornar 8 ao passar 8;
[9] Retornar Fizz ao passar 9;
[10] Retornar Buzz ao passar 10;
[11] Retornar FizzBuzz ao passar 15;
[12] Retornar FizzBuzz ao passar 30.
O teste [1] da lista deve ser implementado e retornar 1 quando passado 1 como parâmetro. O método que executa este teste é:
@Test
public void retornaUmParaUm(){
Fizzbuzz fizzbuzz = new Fizzbuzz();
assertEquals("1", fizzbuzz.verificaFizzbuzz(1));
}
Ao executar o teste é apresentado o seguinte resultado:
Nenhum teste passou, 1 teste causou 1 erro (0,99 s)
retornaUmParaUm causou um Erro: Uncompilable source code – Erroneous tree type: <any>
Na primeira tentativa, o teste não vai passar porque não existe a classe Fizzbuzz nem o método verificaFizzbuzz(). Assim, o próximo passo é fazer o teste passar com o mínimo de código. Para isto, deve ser implementada a classe Fizzbuzz e o método verificaFizzbuzz retornando 1, atendendo ao teste [1] da lista.
public class Fizzbuzz {
public String verificaFizzbuzz(Integer numero){
return "1";
}
}
Como resultado da execução do teste [1], obtém-se a seguinte saída:
O teste passou (0,98 s)
Agora é necessário implementar o teste [2] da lista, que retorna 2 quando passado 2 como parâmetro.
@Test
public void retornaDoisParaDois(){
Fizzbuzz fizzbuzz = new Fizzbuzz();
assertEquals("2", fizzbuzz.verificaFizzbuzz(2));
}
Ao executar esse teste, é apresentado um erro, pois o método verificaFizzbuzz vai retornar sempre 1. Executando o teste, é apresentado o seguinte resultado:
1 teste passou, 1 teste falhou. (0,123 s)
retornaDoisParaDois Falhou: expected <[2]> but was
<[1]>
É necessário refatorar o código para fazê-lo passar. As mudanças apresentadas são:
public String verificaFizzbuzz(Integer numero){
return numero.toString();
}
Com essas mudanças, o teste [2] passou. Como resultado da execução foi apresentada a seguinte saída:
Ambos os testes passaram. (0,108 s)
Nenhum comentário:
Postar um comentário