-
-
Save klauswuestefeld/1215891 to your computer and use it in GitHub Desktop.
Penso da mesma forma.. inclusive escrevi sobre isso também: http://www.loogica.net/blog/2010/09/21/testes-nao-obrigado/
Oi Klaus,
Chegando um pouco atrasado na discussão, mas vamos lá. Acho que temos que testar 100% do que escrevemos, mas precisamos sempre lembrar que testes de unidade não é o único nível de teste -- temos vários outros e devemos usar o que fizer mais sentido.
No código que você escreveu acima, também acho que testes de unidade não fazem sentido. Mas não pq esse código é simples; mas sim pq esse código simplesmente "controla" o fluxo das coisas. Ele não contém regras de negócio ou coisa do tipo. Um exemplo mais natural para a maioria dos desenvolvedores é justamente o código de um "controller" bem escrito. Ele basicamente invoca coisas em uma ordem determinada.
Se eu fizer um teste de unidade pra esses caras, no fim, vou testar se os métodos foram invocados na ordem que eu preciso. Não sei se vale a pena gastar tempo escrevendo isso (e é chato, pq é basicamente trabalhar com mocks). Acredito que um teste de integração/sistema me traria mais feedback sobre a qualidade do mesmo.
Agora, com certeza tuas classes Deployer e Trigger contém regras de negócio e a meu ver, muito provavelmente, deverão ser testadas de maneira isolada.
O que acha?
É tudo sobre contratos. Sua classe SimployMainLoop depende das implementações de Trigger e Deployer? Então por que as interfaces?
class FailTrigger implements Trigger {
public void waitFor() {
try {
Thread.sleep(1 << 30);
} catch (InterruptedException e) {
}
}
}
class FailDeployer implements Deployer {
public void deployNewBuild() {
throw new RuntimeException("gotta catch'em all");
}
}
Aliás, @felipecruz, acho que o @klauswuestefeld não quis dizer o que você escreveu no seu post:
"construir um sistema de informação com pouca lógica de negócio usando TDD não funciona"
eu vejo como uma critica ao 'over-testing'
e realmente.. TDD em um sistema basicamente de CRUD, nao faz sentido..
ps: editei um erro de port :)
Pelo que entendi, ele disse que podem existir partes de um sistema que não precisam de testes unitários.
Não disse que sistemas inteiros não precisam de testes unitários, nem que existem partes de sistema que não precisam de teste nenhum.
se vc faz um sistema de catalogo de filmes, apenas um catalogo, qual o sentido testar alguma coisa?
testar se o model, entity o que quer que seja é salvo no banco pelo ORM? testar se uma query "all" vem como todos os resultados?
se a unica regra de negocio de um catalogo é cadastrar, buscar, listar, editar e apagar, o que precisa ser testado?
existem trechos de codigo que nao precisam de testes.. assim como podem existir sistemas mais simples que nao precisam de testes.. Qual o sentido de tesdtar se o save do JPA ou do django realmente cria uma linha no banco? ele ja nao foi testado pelo proprio ORM?
e repara que ele ta falando de testes unitarios..
queria saber de onde no blog voce tirou que eu disse isso
"Não disse que sistemas inteiros não precisam de testes unitários, nem que existem partes de sistema que não precisam de teste nenhum."
Agora, com certeza tuas classes Deployer e Trigger contém regras de negócio e a
meu ver, muito provavelmente, deverão ser testadas de maneira isolada. O que acha?
Hoje ainda faço testes unitários para muitas unidades, mas me pergunto se não faltou simplificá-las mais, a ponto da maioria das unidades não precisar mais de teste...
@juanlopes - Não entendi sua pergunta.
@klauswuestefeld
Nesse caso acho que dá mesmo pra ficar sem testes.... mas... sempre o mas.... mas deployer.deployGoodBuild(), trigger.waitFor() e deployer.deployNewBuild() devem ter sidos testados em algum lugar.
Eu tenho uma situação que imagino ser similar ao que você descreve:
public List<?> list(HttpServletRequest request) {
return list( FilterFactory.newFilter( GivenSituationFilter.class, request ) );
}
protected List<?> list(GivenSituationFilter filter) {
//logica de vedade
}
Temos testes para o FilterFactory.newFilter() e testes para o list(GivenSituationFilter) protected. Agora o list(HttpServletRequest) public ficou sem testes.
(2 anos atrasado, kkkkk)
Testes unitários são prejudiciais em alguns casos, como o abaixo, e, nesses casos*, não devem ser feitos.
.* Não quero ninguém saíndo por aí falando: "Nós nunca fazemos testes porque o Klaus falou q não precisa!" :P
Testes unitário trazem pelo menos cinco benefícios:
Esta é uma classe minha, q uso em produção, num sistema de deploy contínuo q fiz chamado Simploy:
Esse código é util? Ele pode ser considerado uma unidade?
Se sim, encontramos pelo menos um exemplo em que considero melhor NÃO fazer testes unitários.
Escreva, como exercício, os testes unitários para a classe acima. Dica: é necessário usar mocks. Considere:
1 - Corretude - Os testes q vc escreveu trouxeram algum ganho de corretude, algum ganho de cobertura que testes automatizados de integração ou funcionais já não trazem para uma unidade tão simples? Numa unidade tão ridiculamente simples, um bug não seria gritante aos olhos?
2 e 3 - Refatoração e Otimização - É questionável a necessidade de segurança para simplificar ou otimizar uma unidade que já está na sua forma mais simples e mais otimizada, na opinião de todos os que a estudaram (ou então sugira uma forma mais simples ou mais otimizada). Mesmo assim, a cobertura fornecida por testes de integração ou funcionais desta unidade já são segurança suficiente.
4 - Guia para Design - As vezes vemos uma solução de fora para dentro, as vezes de dentro para fora. Nesse último caso, não precisamos do teste para guiar o design. Se, porém, uma unidade simples dessas for descoberta de fora para dentro, usando teste unitário, na sequência o teste unitário deve ser APAGADO (motivos abaixo). Os testes de integração e funcionais já garantem q o design é usável para os clientes da unidade (mais, até, q o teste unitário).
5 - Exemplos para Entendimento - Os testes q vc escreveu tornam mais simples ou mais complicado entender o q faz a classe acima? Um novo colega não entenderia a classe mais rápido lendo ela diretamente, em vez de tentar decifrar as mockisses dos testes q vc escreveu?
Os custos de um teste unitário, são:
A) Escrever o teste a 1a vez.
B) Reler/Re-entender o teste a cada novo cara q precisa aprender ou relembrar aquela unidade.
C) Manutenção do teste toda vez q a unidade precisa ser alterada por:
D) Tempo de execução do teste.
Escrever o teste a primeira vez (A) é investimento relativamente pequeno.
Tempo de execução (D) é insignificante num ambiente com bom controle de dependências, pq o teste unitário só precisa ser rodado, por definição, quando a unidade é alterada. Pra grande maioria das equipes, porém, que ainda não tem esse controle, o tempo de execução é super relevante.
Assim como ler um comentário óbvio de código, que deveria ter sido apagado, dá raiva perder tempo lendo um teste óbvio ou um teste que é >muito< mais complicado de entender q a unidade em si (B).
Por último, o mais importante é o seguinte: o custo de adaptar os testes unitários pra acompanhar mudanças nas unidades (C) é uma força que atua não só contra a produtividade (novos requisitos) mas também CONTRA A QUALIDADE do sistema, causando arrasto contra refatorações de sistema que precisam realocar responsabilidades em unidades diferentes.
Será que o código acima é exceção, raridade ou será que a maioria dos casos pode ser refatorada para unidades tão simples?
Repetindo: Não quero ninguém saindo por aí falando q nunca faz teste pq "o Klaus falou" q nao precisa.
Vc pode deixar de fazer teste unitário somente para as unidades que:
Falou, Klaus