YvGa:
O TDD nao eh simplista, ele eh simples mesmo e, a não ser que eu não esteja entendendo, o Mark não está discordando de você.
Embora as premissas de TDD pareçam simples ela é uma das técnicas mais difíceis que já fiz tanto que no inicio é extremamente comum não segui-lo e, se você leu o livro do Kent Beck, vê que até para ele em alguns momentos a técnica não é fácil! E isso está relacionado a maneira como aprendemos a programar. No mesmo livro ele diz que TDD é extremamente natural para sua filha porque ele ensinou para ela a técnica enquanto a ensinava a programar.
YvGa:
Além de que eu concordo com ele quando ele diz que o conceito de TDD é usar o código antes dele existir. Essa é a premissa principal, que inclusive dá nome a técnica (test first) e é esse conceito que te permite implementar a lógica do ponto de vista de um usuário da classe que está sendo criada/alterada. De quebra você tem um teste que garante que o resultado do que voce implementou era aquilo que você esperava que fosse.
Esse o conceito está errado. A técnica não é usar o código antes de ele existir pois se você usa o código antes de ele existir então já tem o código na sua cabeça e sem tem na sua cabeça é só criar o método e coloca-lo dentro e, desse modo, tanto faz se você cria o método de teste antes ou depois pois você já projetou toda a lógica e o teste acaba só sendo uma forma de garantir que aquilo que você projetou está correto! Sendo assim a premissa inicial do colega é valida pois o teste só serve para garantir que o que foi feito esta certo e eu posso ter um TDD sem testes!
Isso é natural porque estamos condicionados a pensar assim pois fomos ensinados assim! Sempre nós projetamos na nossa cabeça e depois implementamos só que TDD não é isso pois nesse caso o desenvolvimento não está sendo dirigido pelo teste e sim pela forma que achamos que aquilo deve funcionar!
Embora isso até pareca correto (e em alguns momentos podemos usar isso com práticas TDD) este não é o cerne da finalidade do teste. A ideia é que o teste ajude no projeto da lógica e, nesse caso, a lógica não está na sua cabeça. Você não usa a lógica antes, você projeta a lógica a partir do teste. Para ilustrar isso vou usar o mesmo exemplo da média acima e vou partir do pressuposto que nunca calculei uma média antes. Na minha lista de teste eu adicionei o seguinte:
Calcular a média de 2 numeros.
Então o que faço primeiro é:
@Test
public void testaMedia()
int mediaExperada;
assertEquals(mediaExperada, media.resultado());
}
Ai eu penso, como calculo uma média (ou vou na wikipedia)? Eu lembro que uma media é a soma de um conjunto de números dividido pelo número de elementos da soma. Então eu faço:
@Test
public void testaMedia(){
int mediaExperada = Soma / numeroDeElemendoDaSoma;
assertEquals(mediaExperada, media.resultado());
}
Blz mas qual o número de elementos da soma? Bom nesse caso eu sei pelo que foi especificado na lista de teste que é dois então eu faço:
@Test
public void testaMedia(){
int soma = elemento1 + elemento2;
int numeroDeElementos = 2;
int mediaExperada = soma / numeroDeElemendoDaSoma;
assertEquals(mediaExperada, media.resultado());
}
Eu olho para o código e só falta declarar os elementos então:
@Test
public void testaMedia(){
int elemento1 = 10;
int elemento2 = 12;
int soma = elemento1 + elemento2;
int numeroDeElementos = 2;
int mediaExperada = soma / numeroDeElemendoDaSoma;
assertEquals(mediaExperada, media.resultado());
}
Esse foi um exemplo bem step by step do que é o
"dirigido" por testes e que a finalidade fundamental do teste é ajudar ajudar a projetar a logica.
Desse modo o teste também faz com que se obtenha feedback do que foi implementado está certo e por consequência o acaba ajudando a garantir a qualidade porém essas não são as principais finalidades dele!
Claro que se eu sei a lógica eu não preciso fazer tão passo a passo e posso ir direto para a última implementação, mas, nesse caso, só estou preocupado em obter o feedback positivo e em garantir a qualidade e, embora isso faça parte de TDD, eu estou usando somente o "Desenvolvimento" e o "Teste" porém fica faltando o faltando o "Dirigido" ai!
Buscar somente o feedback e garantir a qualidade ocorre muito durante a pratica de TDD pois muitas vezes sabe-se como implementar algo (em outras ocasiões você vai ter tanta confiança em algo que não vai nem se dar ao trabalho de implementar um teste) e, embora essas ações não sejam as principais finalidades do teste não é errado faze-lo pois TDD não é um contrato fixo que diz que você obrigado a projetar a lógica usando o teste.
YvGa:
Pra quem nunca ouviu falar, triangulação é uma prática na qual você cria um teste (por exemplo que te diz que a media de 2 e 4 é 3, faz com que seu método retorne 3 (return 3; ) e depois cria outro teste para o mesmo método dizendo que a média de 2 e 6 é 4. A partir dai a implementação que existe retornando 3 não é suficiente e você precisa alterá-la para que os dois testes passem.
Depois você escreve outro para outra situação e vai cercando a implementação com as possibilidades que existirem. É muito útil, mas em casos simples você pode dar passos maiores.
Isso está correto, mas ele não está relacionado ao número de passos e sim na confiança no que você projetou! Ele deve ser usado quando você tem duvidas sobre a logica que implementou (independente de ela ser simples ou complexa)! Se você tem dúvida sobre alguma coisa use triangulação.
YvGa:
Voltando ao conceito de TDD eu sempre repito o mesmo, ele eh muito simples, muito fácil. Se está complicado é porque você tem problemas no código que está sendo testado, não nos testes.
Isso soa estranho pois se você usa TDD da maneira correta não deveria ter problemas com o código testado pois projetou o código a partir do teste sendo assim o problema estaria no seu teste!
Pela experiência que tenho quando se está tendo problemas com os testes o problema com certeza está no código mas é por você não está usando TDD da maneira correta!
Isso não quer dizer que as coisas não vão ficar estranhas quando se está usando TDD da maneira correta, pelo contrário, mas nesses casos você esta projetando com ajuda do teste então tem feedback antes de implementar a classe ou método!
Nesse momento você vê começa a se questionar se seus testes representam fielmente o dominio da aplicação! Pega a lista de testes revê cada um dos testes já implementados e começa a criar testes alternativos de modo a criar um modelo mais fidedigno e isso é muito legal pois você acaba por criar novos testes e a descartar testes antigos o que leva a uma grande refatoração no sistema para um modelo mais rico!