Como introduzir TDD à minha vida?

O exemplo possui problemas.

chegando um pouco atrasado neste tópico, mas foi um tópico que muita gente estava esperando acontecer.

no meu caso consegui introduzir à minha vida sim não 100%, mas não no projeto no qual faço parte, sendo o maior motivo falta de maturidade da equipe neste aspecto e sendo um pouco menos produtivo em relação aos outros desenvolvedores visando este aspecto, apesar de que na época, na pressa ninguém enxergava isto como lucro e sim a coisa funcionando. hoje, a cada release a galera pina para não dar um erro inesperado em uma manutenção que foi efetuada em uma operação que estava funcionando.

na verdade ainda existe um pouco de dificuldade nisto, no meu caso por exemplo, sobre uma forma interessante para uso e implementação de arquitetura utilizando dbunit ou outro framework. O tratamento, configuração e gerenciamento para manter os dados íntegros e específicos para se manter o teste funcionando, conforme mudanças foi um dos casos por eu não ter utilizado no início do projeto. Alguém teria alguma motivação e/ou referência a respeito disto?

quando mencionei acima não, fiz menção à todas as camadas lógicas, bem como componentes e métodos de classes de modelo de domínio.

[quote=Bruno Laturner]Indo direto ao ponto:

Como começo a fazer testes partindo do ponto zero; e,

Como tornar isso um hábito, um desenvolvimento orientado a testes de fato?

Como vocês começaram com TDD? [/quote]

Também chegando atrasado, mas acho que vai ajudar… Como vcs viram nos links e explicações anteriores que não é tão fácil, mas eu te digo que com a experiência “mão-na-massa” a coisa melhora, e melhora muito !

Aqui na empresa que trabalho começamos fazendo Coding Dojo(http://www.codingdojo.org/), é um exercício muito bacana para TDD, sem contar os demais atributos de um bom programador que esse tipo de exercício explora.

Existem alguns pontos espalhados pelo Brasil, eu pessoalmente conheço o pessoal do Dojo SP(http://www.dojosp.org/) pessoal muito receptivo e gente boa.

Bom, depois de ler todos os ótimos links postados, sugiro realmente você a participar de exemplos práticos e com outras pessoas que podem servir de “coach” para você.

[]´s

Nao entendi o que quis dizer por teste manual, ate onde sei os testes sao automatizados; e se for outro nivel de teste (QA) nao é mais ciclo TDD.

Ainda, a opcao 2 e 3 nao fazem sentido, pq sem TDD de que ciclo vc se refere? A iteracao? Sprint?

Fique claro que uma coisa é usar TDD como tecnica de design, outra é vc ter uma boa cobertura de testes. Pra mim o mais importante é o segundo pq o primeiro nao resolve meu problema imediato.

Ao teste que você, como desenvolvedor, faz para saber se o que escreveu está funcionando.

O ciclo muda código/vê se funcionou/muda código/vê se funcionou…

[quote=cmoscoso]
Fique claro que uma coisa é usar TDD como tecnica de design, outra é vc ter uma boa cobertura de testes. Pra mim o mais importante é o segundo pq o primeiro nao resolve meu problema imediato.[/quote]

Eu acho que isto está bem claro há algum tempo. O ponto que eu estou tentando provar é que qualquer estratégia de desenvolvimento com qualidade mínima vai cair na ‘morosidade’ e ‘baixa agilidade’ que você colocou sobre TDD porque estas não são causadas por TDD e sim pelo fato de que você tem que testar o que faz. TDD só deixa isso mais evidente.

Eu prefiro dizer que nao uso mocks em alguns tipos de teste. Por exemplo, como posso depender de objetos ‘fake’ para testar integracao?!?!

Se seu objeto depende do httpservlet request pra fazer o teste unitario e estranho pq geralmente foco os testes nos objetos que estao relacionados as regras de negocio, onde nao existe esse nivel de acoplamento.

Só uma adendo: depende da integração sendo testada naquele teste. Se você está testando a aderência do seu c’pdogio com, digamos, Servlets framework, você pode fazer mock da parte de persistência naquele teste, e vice-versa.

[quote=pcalcado][quote=cmoscoso]
Nao entendi o que quis dizer por teste manual, ate onde sei os testes sao automatizados; e se for outro nivel de teste (QA) nao é mais ciclo TDD.
[/quote]

Ao teste que você, como desenvolvedor, faz para saber se o que escreveu está funcionando.

O ciclo muda código/vê se funcionou/muda código/vê se funcionou…

[quote=cmoscoso]
Fique claro que uma coisa é usar TDD como tecnica de design, outra é vc ter uma boa cobertura de testes. Pra mim o mais importante é o segundo pq o primeiro nao resolve meu problema imediato.[/quote]

Eu acho que isto está bem claro há algum tempo. O ponto que eu estou tentando provar é que qualquer estratégia de desenvolvimento com qualidade mínima vai cair na ‘morosidade’ e ‘baixa agilidade’ que você colocou sobre TDD porque estas não são causadas por TDD e sim pelo fato de que você tem que testar o que faz. TDD só deixa isso mais evidente.[/quote]

Entao o programador profissional deve procurar boa cobertura de testes unitarios mais do que TDD. TDD é uma forma de alcancar esse objetivo pq considera os testes como parte do processo de projetar o sistema desde o inicio, mas isso implica em uma bagagem maior do que é necessario carregar, considerando que sozinho e vc nao escreve teste antes do codigo sempre, por exemplo: se vc vem de uma suite de testes compreensivel e tem uma adicao de funcionalidade que pode exigir um refactoring um pouco maior, deixar os testes (naquela parte especifica) de lado por um instante permite que vc experimente mais rapidamente outras solucoes. Neste momento eu nao estaria fazendo TDD, e talvez pq fosse menos agil pra ocasiao.

Vc pode dizer que poderia experimentar usando TDD mas acho o processo mais ‘moroso’. Talvez seja a tipagem estatica do java, ou talvez apenas necessidade de enxergar o sistma de outros pontos de vista e nao apenas a visao black-box dos objetos na estrategia TDD.

Exatamente o que eu tentei dizer.

Entendo, mas no final creio que é questão de prática com TDD. Uma pessoa com prática não vai nem cogitar iniciar um refactoring sem ter um teste falhando (supondo que o refactoring em questão afete testes, que nem sempre é o caso) porque vê nesta prática uma especificação do que ela deseja. Refatorar sem um objetivo certo é meio ineficiente, IMHO, e testes te dizem exatamente quando seu objetivo foi cumprido. Como disse, creio que é questão de prática.

[quote=cmoscoso]
Vc pode dizer que poderia experimentar usando TDD mas acho o processo mais ‘moroso’. Talvez seja a tipagem estatica do java, ou talvez apenas necessidade de enxergar o sistma de outros pontos de vista e nao apenas a visao black-box dos objetos na estrategia TDD.[/quote]

Não necessariamente Java mas alguns frameworks de mock (EasyMock, JMock…) podem tornar sua vida bem mais chata. Acho que Ruby (por exemplo) se beneficia do fato de que quando surgiram os RSpecs e shoulda da vida nós já fazíamos TDD há um bom tempo.

[quote=cmoscoso]
Vc pode dizer que poderia experimentar usando TDD mas acho o processo mais ‘moroso’. Talvez seja a tipagem estatica do java, ou talvez apenas necessidade de enxergar o sistma de outros pontos de vista e nao apenas a visao black-box dos objetos na estrategia TDD.[/quote]

TDD é desenvolvimento. Todo o desenvolvimento implica em pensar, experimental, refazer… é por isso que se chamada desenvolvimento.
TDD tem dois artefactos : codigo e testes. Vc tem que aplicar o ciclo de desenvolvimento : pensar, experimental, refazer em ambos os artefactos. É por isso que é moroso. A culpa não é do Java.

Se vc for um desenvolvedor chuck noris que já sabe como o sistema vai ser antes de Deus, então vc não precisa de TDD para ficar experimentando… lol

Agora, cobertura de testes é outra historia. Concordo contigo.
Ai não ha muito que pensar exceto como mocar certa parte do sistema… Isso não é, a bem dizer, trabalho de desenvolvimento, é trabalho da equipe de testes ou de QA.
Claro que na visão minimalista das filosofias ageis o desenvolvedor é um ser super-poderoso auto-gerenciável. capaz de analizar, desenvolveder, codificar, testar, conversar com o cliente , convencê-lo a fazer o seu trabalho e nas horas vagas ainda participa de projetos open sorce, escreve me blogs, dá palestas no google talks e beb muito café…
Na visão realista ninguem sabe fazer tudo. Alguns sãi melhores desenvolvedores, outros analistas outros a lidar com o cliente, outros a fazer frameworks… e claro, tem os que só são bons bebendo café… lol
Na real, cobertura 100% é uma maravilha se vc tiver todo o tempo do mundo. Pois existe sempre mais uma coisinha que vc pode testar/ não testou antes. Em projetos reais privados duvido que algum tenha cobertura 100%. Digo privados porque os open source tem - virtualmente - todo o tempo do mundo (aka, não têm prazo para terminar)

Lá vou eu com minhas perguntas idiotas :stuck_out_tongue:

Quando se sabe que a cobertura foi 100%? - Isso parece “meio” impossível…

Desculpa se a pergunta é boba, mas é uma coisa que eu acredito ser praticamente inviável de fazer.

Depende. Pela métrica (não definitiva, mas isso é outro assunto) de test coverage basta você usar alguma ferramenta como Emma.

O grande ponto é que não faz sentido ter 100% de cobertura de testes e este nunca foi nem será o objetivo de TDD, metodologias ágeis ou o que quer que seja. Cobertura baixa te diz que o sistema está muito ruim mas cobertura alta não diz nada.

Existe muito ruído e pouco sinal por aí, cuidado.

Trocando uns e-mails com o GC (que está de férias e não baixa aqui tão cedo), ele me passou link pro blog dele pra ajudar, o mesmo que o Luca passou antes:

Test infection: por onde começar?

Basicamente fala do que discutimos no começo, sobre o que fazer com sistemas sem testes algum.

[quote=GC]Mas o que você faz quando cai de pára-quedas num projeto que não tem um mísero teste sequer? Você não pode deixar esse problema para outra pessoa? É você o infeliz que tem que resolver o problema e fazer a faxina?

Minha resposta para essa pergunta é bem simples: SIM, você é o infeliz que tem que resolver o problema.[/quote]
Não é muito animador, mas alguém tem que desarmar a bomba algum dia. Melhor que seja você agora antes que caia de para-quedas em outro projeto onde ela já tenha estourado e o inexperiente seja você.

Mais fácil falar que fazer, mas tudo sempre é.

Quanto a livros, se alguém perguntar no futuro, uma resposta do Luca sobre o assunto (tá no meu favoritos desde que fiz a pergunta).

[quote=Luca]Ola

JUnit in Action de 2004 - excelente livro

Test Driven Development: By Example de 2002

Test Driven Development: A J2EE Example de 2005

Test-Driven Development: A Practical Guide de 2003

Pragmatic Unit Testing in Java with JUnit de 2003

TDD and Acceptance TDD for Java Developers de 2007

Java Testing and Design livro grátis disponivel em PDF desde 2004

Além destes livros, há muitos tutoriais que podem ser baixados livremente como este por exemplo: http://hotwork.sourceforge.net/hotwork/manual/junit/junit-user-guide.html

Outra fonte de aprendizado podem ser as centenas de projetos open source que usam testes unitários

E a documentação do JUnit não é “palpérrima” e muito menos paupérrima

Não é por falta de documentação que não se usa.

[]s
Luca[/quote]

Finalmente, respondendo em parte a minha dúvida inicial, [quote]como começar com testes?[/quote]
Apenas comece. Bata a cara na porta até aprender. Faça o que puder.

[quote=cmoscoso][quote=Paulo Silveira]
Em resumo: se você tentar implantar testes unitários em algo que já tem meses de desenolvimento, além de não conseguir realizar a tarefa direito, vai ficar frustrado e culpar o TDD.[/quote]

Nao concordo com essa afirmacao.

Em muitas ocasioes vale a pena criar testes unitarios para projetos em andamento. Se vc esta trabalhando num projeto existente porque nao introduzir testes unitarios durante o refactoring ou para novas funcionalides do sistema?
[/quote]

So pra deixar claro, eu nao afirmei que nao vale a pena. Quero dizer que é dificil e provavelmente vai culpar o TDD se nao conseguir testar.

Lá vou eu com minhas perguntas idiotas :stuck_out_tongue:

Quando se sabe que a cobertura foi 100%? - Isso parece “meio” impossível…
[/quote]

Vc executa todo o codigo de testes e vê se todo o codigo do seu programa foi executado. e TODO é TODO inclusive codigo de tratamento de exceção e aquele que vc colocou só porque na possibilidade de aliens o raptarem amanhã o codigo tem que funcionar…

Existem ferramentas que fazem isso por vc (bendito seja o bytecode). Tem uma com um nome sujectivo: Cobertura.

Cobertura 100% é a única forma de garantir que o seu sistema está testado. Qualquer coisa abaixo disso e zero é a mesma coisa do ponto de vista de uma equipe de QA/Testing.
Do ponto de vista do desenvolvedor colocar testes unitátios em 50% das classes é suficiente para garantir que o sistema funciona. Mas apenas com 100% de cobertura vc realmente garante - com selo de garantia - que o sistema está testado.

O objetivo do TDD não é ter 100% cobertura. Aliás , o objetivo de TDD não é sequer fazer testes de unidade. Os testes de TDD são , digamos, mais conceptuais. Vc quer testar se a sua ideia para o problema X funciona. Repare que a coisa é ao contrario.
Vc sabe o input e o output e não sabe o como a classe faz transforma um no outro. O objetivo do TDD é encontrar esse miolo da classe. O objetivo não é que o teste rode todas as possibilidades em cima da mesma classe.

Em testes “de garantia” vc não sabe o miolo e não quer saber. Vc sabe os inputs e os outputs para várias situações (todas as situações) e vc quer testar exaustivamente a mesma unidade em todas essas situações. O objetivo é diferente. Aqui o objetivo é que todo os codigo da classe seja executado para ter a certeza que não ha erro em nenhuma linha. É este trabalho que é complexo.

Confundir TDD com teste “de garantia” é tiro no pé. TDD não lhe garante nada mais além do que vc pensou.
Testes de garantia provam que a classe funciona mesmo em situações em que o programador da classe não pensou.

O que é preciso entender é que garantia real só existe com cobertura 100%. Não podem ser ser usados processos estatisticos, não é aceitável vc dizer “o sistema tem 99.99% de codigo testado” Ou é tudo ou não é nada.

É por isto que promessa que se vincula na media é meio oca. A mensagem normalmente é "Vc está melhor com testes do que sem "
mas a realidade é que sem cobertura total os testezitos que vc fez garantem tanto como nenhum. Entenda que não é possivel tem 80% de confiança. Ou vc confia, ou vc não confia.

Veja por outro lado. Imagine que a sua empresa dá garantia para o osftware produzido de X anos.
qual é o maximo de anos que pode dar sem dar prejuizo À empresa.
Se o seu software é totalmente não testado o risco de problemas em X anos é tanto maior quando mais anos.
Se o seu software tem 100% de cobertura o risco é zero indepndnete de quantos anos são.

Assim empresas com 1 ano de garantia vs empresas com 10 anos são diferentes.
Em qual vc confiaria ? A primeira cobra barato mas dá 1 ano, a outra cobra caro, mas tem uma garantia maior que a vida util do software ( ou seja, vc sabe que nunca mais vai pagar nada ) Qual vc escolhe ?

Por isso que cobertura 100% é algo inerente a equipes de teste/QA. Equipes de QA não são formadas pelos desenvolvedores que criaram o software ( principio de imparcialidade).

O ponto é que se contam pelos dedos empresas que façam isso. E pior, com essa vaga de agilidade que anda por ai , ha muito desenvolvedor enganando-se com cobertura 10% , 50% , 90% …

Entendido isso , não ha um meio termo ?
Ha. Ha um compromisso. É dizer que 100% cobetura é impossivel e amarrar os anos de garantia à confiança/risco que vc tem. a formula é risco = 1 / cobertura

cobertura 0 (0%) = risco infinito. Os bugs parecem aleatorios e parecem nunca mais acabar
cobertura 1 (100%) = risco 0. Vc poe a ma mão no fogo se for preciso.
cobertura 0.5 (50%) = risco 1/0.5 = 2 (200%) … o que significa isto ? ninguem sabe… ( na realidade não significa nada, esse é o ponto, mas vc pode enganar-se e pensar que sim).

A priori, aprendi o que são os testes de cobertura.
Mas (opz), o que o Phillip falou não entra em um pouco de contradição com que o Sergio falou?

Bom, pelo que eu entendi, testes de cobertura é testar o software de fio a fio, linha por linha. Daí, surge uma vantagem e uma desvantagem: a vantagem é de que a segurança e a confiabilidade são imensas (como o Sergio falou, eu ponho minha mão no fogo pelo software). Só que tem a desvantagem, que (acredito eu) seja muito caro.

O que vocês fazem nos projetos?

Abraço.

Exatamente. Vc matou a charada. É muito caro.

Então o que os agilistas defendem é que se vc começar por fazer o sistema junto com os testes então quando vc acabar o sistema os testes já estão prontos. Melhor ainda, vc faz os testes antes e modela o seu código para se encaixar nos testes.

Mas quais testes são estes que os agilistas defendem ? Aqui é que está o buzilis da questão.
Estes testes não são os testes de cobertura/garantia. São os testes de aceitação.

Ou seja, se o teste passa vc aceita que o programa está pronto. Mas “pronto” é diferente de "garantia que não dá erro"
A ideia é que um requisitos de funcionalidades gera vários testes. Quanto os testes passaram o requisitos está implementado.
Mais que isso, eu aceito sem duvidar que está implementado.

Isto tem vários senãos. Vc começa a confiar demais no teste. Vc vê uma barra verde e fica feliz. Mas como o objetivo não é testar todos os cenários possiveis então vc testa apenas aqueles que estão nos requisitos. Ou seja, vc testa aquilo que o cliente pediu que quer no sistema e vc (quanto a mim ingenuamente) aceita que ele só vai usar isso do sistema , que ele lhe disse tudo o que havia a dizer ou seja, vc supoe que não existem mais casos de uso escondidos que foram esquecidos.
Pior, vc aceita que não precisa de uma equpe de QA e que o seu desenvolvimento é totalmente imparcial.

Fora isso vc não usa testes de aceitação para requisitos não funcionais a menos que eles tenham sido explicitados pelo cliente.

No fim vc fica com a certeza de que os requisitos estão bem implementados, mas como uma aplicação é mais que o conjunto dos requisitos isso significa que tem um monte de código que não foi testado. Vc tem o aceite do cliente, mas vc não tem garantia do funcionamento.

Ai vc soma testes de garantia aos de aceitação. E ai voltamos ao ponto em que ha muitos testes e a coisa fica cara.

Isso eu tb queria saber. O que as pessoas realmente fazem nos projetos? Porque é irrealista acreditar que façam testes de garantia com 100% de cobertura ainda por cima em equipes ageis em que não se faz nada além do que o cliente pediu.

Eu por mim uso testes para guiar o desenvolvimento e em uma ou outra classe critica coloco Junit. Normalmente quando dá problema em uma classe coloco um teste que simula esse problema e depois tento resolver. Isso é bom porque não preciso correr o codigo inteiro para resolver o problema ( ou saber se o problema resurgiu). Ou seja, vc mata o bug e garante que ele continua morto. Testes vão sendo adicionadas à medida que bugs vão sendo encontrados. Mais raramente o teste é criado junto com a classe. Isso normalmente para classes de serviço que pegam algo e retornam algo, tipo calculadora. E mesmo assim só quando é critico ( em sistema financeiros , contas é critico)

Quando o algoritmo é muito complexo ou a interação dos tipos é complexa começo por fazer o teste antes da classe e depois preencho o miolo (TDD)

Enfim, estratégias diferentes para problemas diferentes.

Testes (as in TDD) são justamente para você desenvolver somente o que foi pedido.

Testes (as in TDD) são justamente para você retomar o desenvolvimento a partir do ponto que o deixou, refatorar o sistema para comportar todas a novas alterações e ter certeza que o que fez antes não quebrou.

Testes (as in TDD) são justamente para você desenvolver menos de tudo e mais o que realmente importa. Nem um pingo a mais nem a menos.

Tudo vai depender da definicao de teste de aceitacao (TA). Por exemplo eu considero TA outro de nivel de teste (captura de requisitos+ QA-), mas definitivamente nao relacionado com teste unitario e seu “principio ativo” TDD. Sao testes criados pelo analista! E esse é o principal ponto de divergencia quanto a definicao de TA, que IMO deve ser focada na visao funcional do sistema apenas. Mas o assunto desse topico é testes unitarios e TDD. Podemos falar de BDD, RSpec mas nao disso tem a ver com TA que sao criados pelo papel do analista.

Segundo algumas correntes agilistas esses testes ditados pelo analista ( que é uma figura que não existe em ambiente agil onde todo o mundo é desenvolvedor faz-tudo) são colocados em codigo. Assim simplesmente correndo um suite de testes podemos saber quando do requisitos já foi completado. tudo isso de forma automática.
Coisas como o FIT/Fitness servem exatamente para testes de aceitação em codigo. Esse codigo pode ser corrido em qualquer momento pela equipe de dev, logo em nada é diferente de um teste de unidade.