Como introduzir TDD à minha vida?  XML
Índice dos Fóruns » Metodologias de Desenvolvimento e Testes de Software
Autor Mensagem
Bruno Laturner
GUJ Expert
[Avatar]

Membro desde: 18/02/2008 16:17:53
Mensagens: 3002
Offline

Indo direto ao ponto:

Sou um Programador de Schrödinger e gostaria de introduzir testes e TDD à minha vida, à empresa que trabalho e nas que trabalharei. Infelizmente tenho aquelas eternas dúvidas:

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

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

Gostaria que a discussão tivesse um tema "Como introduzi TDD à minha vida", queria que falassem do passado e do presente, desafios encontrados, uma opinião muito pessoal de como fizeram e como fazem isso. Eu aprendo muito por exemplo/tutorial de vida de outras pessoas.

Como vocês começaram com TDD? Agradeço desde já a ajuda.

This message was edited 1 time. Last update was at 05/11/2008 18:43:25


A resposta acima foi achada em menos de 5 minutos no google.
The prisoner falls in love with his chains. --E.W. Dijkstra
[WWW]
Paulo Silveira
Administrador
[Avatar]

Membro desde: 07/08/2002 18:38:50
Mensagens: 4204
Localização: São Paulo
Offline

Oi Bruno!

Sua pergunta é excelente e muito relevante. Eu nao vou argumentar em como começar, mas vou argumentar em relação aos meus próprios erros:

A pior maneira de tentar começar TDD é criando testes unitários em um projeto que já nasceu sem testes. Escrever testes unitários para código muito acoplado é praticamente impossível: eles viram pequenos testes de integração, já que você precisaria criar um número gigante de mocks para transformar o teste em unitário. E isso é um fato: código que nasceu sem testes é mais acoplado que o que nasce com testes! Quando você testa desde o começo, seu código é forçado a ser desacoplado, caso contrário você não conseguiria testa-lo!

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.

Sim, isso é uma confissao de 4 anos atras

http://blog.caelum.com.br twitter: @paulo_caelum


[Email] [WWW]
victorwss
JWizard
[Avatar]

Membro desde: 18/12/2007 14:46:00
Mensagens: 2409
Localização: São Paulo - SP
Offline

Pois é, estou nessa também porque já faz muito tempo que não pego alguma coisa do zero. Sempre caio de para-quedas em projetos que tem coisas que me dão vontade de chorar.

Sou outro programador de Schrödinger.

Victor Williams Stafusa da Silva

Bacharel em Ciência da Computação - UFMT // Especialista em Desenvolvimento Java - CEFET/MT // Doutorando em Ciência da Computação - IME-USP
SCJP 6.0 - 19/12/2007 - PASS - 88% // SCWCD 5 - 17/05/2008 - PASS - 79% // SCJA - 09/09/2008 - PASS - 96% // SCSNI - 30/06/2009 - PASS - 68% // SCBCD 5 - 31/05/2010 - PASS - 95%
Próximos: SCJD (encalhado com o projeto), SCEA parte I (estudando). Algum dia desses: SCMAD, OCA, SCEA e SCDJWS.

Computação: uma ciência holística e esotérica!
E então veio Deus a terra e disse aos homens: Não dividireis por zero.
XML is a giant step in no direction at all. (Erik Naggum)
Arquitetura de sistemas: Eu prefiro ser essa metamorfose ambulante do que ter aquela velha opinião formada sobre tudo.
Diga não as drogas: Não use java.util.Vector.
Cuidado: Este usuário pode ter temperamento agressivo.

Always code as if the person who will maintain your code is a maniac serial killer that knows where you live.
I am the maniac serial killer that knows where you live who will maintain your code.


É impossível falar de CMMI (Capability Maturity Model Integration) sem saber o que é CIMM (Capability Im-Maturity Model).


Se você escreve "concerteza", "concerteza" você andou matando aulas de português.
[MSN]
Emerson Macedo
Virtual Machine Man
[Avatar]

Membro desde: 01/08/2006 16:55:28
Mensagens: 689
Localização: Rio de Janeiro - RJ
Offline

Só um adendo...

Existem situações em que você precisa adicionar testes a um projeto existente, caso contrário você vai se dar mau. Para esses casos, é necessário uma pessoa com mais experiência em testes automatizados de um modo geral. E estou com o Paulo no que ele falou: Iniciante em TDD tentando aplicar em um projeto sem testes, vai se irritar e culpar o TDD.

This message was edited 1 time. Last update was at 05/11/2008 17:18:21


Emerson Macedo Leite
PMP - Ping-pong Master Player
CSM - Counter-Strile Manager
http://codificando.com

"Porque, assim como o relâmpago sai do oriente e se mostra até o ocidente, assim será também a vinda do filho do homem." - Mateus 24:27
[Email] [WWW] [Yahoo!] [MSN] [ICQ]
Bruno Laturner
GUJ Expert
[Avatar]

Membro desde: 18/02/2008 16:17:53
Mensagens: 3002
Offline

Falando em testes unitários, como vocês definem uma "unidade"? Uma classe, um método?

This message was edited 1 time. Last update was at 05/11/2008 17:50:57


A resposta acima foi achada em menos de 5 minutos no google.
The prisoner falls in love with his chains. --E.W. Dijkstra
[WWW]
cmoscoso
Virtual Machine Man

Membro desde: 23/10/2007 10:08:29
Mensagens: 687
Offline

Paulo Silveira wrote:
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.


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?

Mas acho que vc quis se referir a introduzir testes unitarios para ser adotado por uma equipe de desenvolvimento e nao por um 'desenvolvedor solo'. Isso e realmente mais complicado, pq se as pessoas estivessem dispostas a comprar a ideia ja teriam feito desde o inicio do projeto.
[Email]
Andre Brito
JWizard

Membro desde: 21/07/2007 17:44:31
Mensagens: 2485
Localização: Paraná
Offline

Excelente tópico.
Sempre tive a mesma dúvida, mas nunca tive coragem de perguntar (na verdade, nunca tive tempo pra estudar direito isso. Agora nas férias não tem como escapar).

Tópico favoritado.

Abraços.

Como organizar o GUJ.
Meu Twitter.
Meu blog.
Future proofing means making code easy to change, not trying to anticipate every possible way your code might need to change.
[WWW]
Luca
Moderador
[Avatar]

Membro desde: 06/09/2002 14:30:10
Mensagens: 5810
Localização: São Paulo/SP ou Paraty/RJ
Offline

Olá

A pergunta é muito pertinente e ainda tem o mérito de desencavar este excelente post do nosso amigo Chapiewski

Acho que ninguém aqui aprendeu a programar fazendo testes. A gente sabe que é bom e tudo o mais mas começar a programar pelos testes exige um certo esforço mental.

Eu que sou macaco velho e põe velho nisto, sinto dificuldades nas raras vezes em que escrevo código de pensar primeiro nos testes. Já andei me forçando mas como escrever código não faz parte do meu dia a dia ainda não peguei o hábito. É isto que cada um precisa: pegar o hábito. Para isto precisa investir um certo tempo sofrendo um pouco.

Sabem do que sinto falta? De um tutorial explicando como fazer isto usando o eclipse (ou o Netbeans) desde a criação e organização das classes de teste e das classes testadas. Alguns dos melhores links que conheço são também do Chapiewski:

http://gc.blog.br/2007/06/20/slides-da-palestra-sobre-tdd-no-riojug/

http://gc.blog.br/2008/03/30/test-infection-por-onde-comecar/

[]s
Luca



Dare Obasanjo (Program Manager at Microsoft)
"The folks I know from across the industry who have to build large scale Web services on the Web today at Google, Yahoo!, Facebook, Windows Live, Amazon, etc are using RESTful Web services. The only times I encounter someone with good things to say about WS-* is if it is their job to pimp these technologies or they have already "invested" in WS-* and want to defend that investment."


CEP, JMS, JMX e coisas afins (ou não)
http://lucabastos.blogspot.com/
[Email] [WWW]
Bruno Laturner
GUJ Expert
[Avatar]

Membro desde: 18/02/2008 16:17:53
Mensagens: 3002
Offline

É, caio no mesmo caso do Victor, o código que pego é quase sempre de manutenção. Apesar disso não acho que esse é o maior problema.

Por aqui a arquitetura é o famoso BOLOVO, orientado ao banco de dados. O problema é que não sei testar algo onde o endpoint é sempre o BD, onde as operações são sempre "... do/no banco", verificar se tal dado existe no banco, trazer várias coisas do banco, associá-las, e mostrar na tela, inserir, alterar... Os dados sempre vem e vão para algum lugar.

E não ajuda o fato que o mecanismo de persistência é fixo, SQL/JDBC na mão, mudar ele para um mock e de volta p/ o mecanismo real daria trabalho e é falível.

Ouvi falar que o melhor modo de tratar isso é instalar um SGBD localmente e zerar os registros antes de começar os testes.

TDD precisa de uma ambiente mínimo para funcionar?

This message was edited 1 time. Last update was at 06/11/2008 08:49:52


A resposta acima foi achada em menos de 5 minutos no google.
The prisoner falls in love with his chains. --E.W. Dijkstra
[WWW]
sergiotaborda
GUJ Expert
[Avatar]

Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline

Bruno Laturner wrote:Indo direto ao ponto:

Sou um Programador de Schrödinger e gostaria de introduzir testes e TDD à minha vida, à empresa que trabalho e nas que trabalharei. Infelizmente tenho aquelas eternas dúvidas:

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

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

Gostaria que a discussão tivesse um tema "Como introduzi TDD à minha vida", queria que falassem do passado e do presente, desafios encontrados, uma opinião muito pessoal de como fizeram e como fazem isso. Eu aprendo muito por exemplo/tutorial de vida de outras pessoas.

Como vocês começaram com TDD? Agradeço desde já a ajuda.


Existe uma diferença entre usar testes unitários e usar TDD. TDD significa Test Driven Development : Desenvolvimento Guiado por Testes. Isso é radicalmente diferente do que simplesmente usar um Junit da vida e ter algumas ou todas as classes sobre o controle de testes ( cobertura 100%).

Então o ponto inicial é começar a usar testes unitários. O JUnit e o Eclipse são uma boa dobradinha, mas existem outras por ai (TestNG + Maven ou Ant por exemplo). O ponto aqui é simples. Vc faz uma classe que executa alguma logica. Vc sabe que passados os parametros x e y o resultado tem que ser z. Vc cria uma classe de test (do junit por exemplo) e executa o codigo como se estivesses dentro de um programa real. A diferença é que o seu método de teste só executa uma classe. testes corriqueiros que vemos em exemplos em revistas e afins não são realistas. ninguém escreve um teste para testar de 1+1 = 2.
Em aplicações normais as suas classes vão produzir objetos e alterar estados em outros objetos de outras classes e não simplesmente retorná-los como uma calculadora. Vão tentar enviar email, mensagens via Jms , acessar o banco, processar um arquivo. É isso que tem que ser simulado no teste. vários niveis de complexidade geram vários tipos de teste (unidade, integração, etc... ) comece pelos de unidade.

Rápidamente vc vai entender que aplicar testes de unidade em ambientes complexos demanda uma muito boa separação de responsabilidade dos seus objetos. Para fazer testes bem feitos o seu modelo tem que ter OO bem feita. O seu modelo vai tender naturalmente a ser desacoplado porque vc vai precisar substituir objetos reais por objetos simulados. Por exemplo, substituir um repositório que comunica com o banco por um que simplesmente guardas as coisas em memoria e disponibiliza métodos públicos para podermos consultar se os objetos estão lá e montar os asserts. Estes objetos ficticios, simulados - chamados mocks - podem levá-lo na grande estrada do teste orientado a mocks. Que nada tem a haver com TDD em uma primeira aproximação.

O habito vem do seu esforço em não desistir de incluir suas classes sobre o controle de testes. A maior parte das vezes isso não é simples e requer um esforço tanto de codificação como de refactoring para que possam ser injetados objetos simulados.

TDD tem um propósito diferente do simples teste. Você não modela a aplicação e depois a testa. Vc primeiro escreve código que usa o modelo na forma de testes. A classe do modelo não tem código, apenas interface. O teste invoca essa interface. O teste é executado e dá erro porque nada foi implementado ainda. Ai vc implementa a lógica da classe. Testa. refactora, Testa. E continua nisto até que o teste passe.
Ai vc parte para outra funcionalidades. Sempre começando por definir como o codigo se deve comportar e só depois implementando o miolo. O teste vem primeiro. É ele que guia o desenvolvimento da classe como um cliente dos serviços da classe e não a classe que dita o teste. É por isso que se chama Desenvolvimento guiado por teste (TDD). Em TDD raramente ha a necessidade de mocks porque vc não está simulando o funcionamento do sistema, vc está escrevendo como ele vai se comportar. Claro que mocks são uteis em situações complexas que acabarão aparecendo, mas não são o foco nem a ferramenta principal. TDD é muito ligado a design by contract. A preocupação é como o que a classe deve fazer e não como ela deve fazê-lo. Ela tem que respeitar o contrato.
O TDD incrementa isso definindo o contrato à priori via código executável ( o código do teste).

TDD é um processo moroso e pouco ágil para sistemas complexos.Para classes unitárias pode ser mais eficaz.
Embora isso, ele é altamente compensador uma vez completado já que vc acaba como a classe e o teste prontos ao mesmo tempo. Eu utilizo esta técnica apenas quando não domino aquilo que a classe irá fazer ou não tenho o modelo claro na minha cabeça, ou quero experimentar com várias interfaces para a API para encontrar a que é mais fluente e coerente. Assim , ao escrever o código cliente primeiro, as funcionalidades da classe (ou de uma pequena biblioteca de classes) aparecem mais naturalmente.

--
Como nota tenho que comentar a desconfiança encontrada nas palavras do Donald Knuth. Ele tem toda a razão no que diz. O problema é que, como sempre, ha uma confusão de conceitos básicos e os hypes levam a melhor. Orientação a Objetos não tem mistérios sobrenaturais.

Como o próprio Knuth diz nessa mesma entrevista "software methodology has always been akin to religion." é preciso ter muito cuidado quando se fala de TDD , DDD , XP, etc ... sem raciocinar a diferença entre a metodologia e a filosofia e as técnicas e ferramentas. As técnicas e ferramentas são as da OO. Não existem outras. Não serão criadas outras.

Aqui fica a ideia dele - expressa na mesma entrevista - sobre XP.
With the caveat that there?s no reason anybody should care about the opinions of a computer scientist/mathematician like me regarding software development, let me just say that almost everything I?ve ever heard associated with the term "extreme programming" sounds like exactly the wrong way to go...with one exception. The exception is the idea of working in teams and reading each other?s code. That idea is crucial, and it might even mask out all the terrible aspects of extreme programming that alarm me.


É tudo uma questão de bom senso. Metodologia não poderão nunca suplantar a boa e velha teoria de computação que lhes dá base.
Seja OO ou outra qualquer.

Quanto ao problema do gato do Schrodinger o nome não é muito bom. A MQ é um dos mais exatos ramos da física e não aleatória como é popular. O gato do Schrodinger é só um, não dois. O gato está morto ou vivo. Não morto e vivo. É por isso que quando vc abra a caixa nunca sai um gato zombie de lá. Ou sai vivo, ou está morto. (é como lançar uma moeda , ou sai cara ou coroa, nunca sai cara e coroa)
O problema mais grave com a analogia é que passa a idéia de que vc pode escrever qq código absurdo e por meio de escrever testes vc consegue que ele funcione corretamente (mascarando a incompetência do programador) e sem saber como isso veio a acontecer. Ou seja, faça-se um sistema caótico, inclua-se testes e vira um sistema estável. (!)
É verdade que os testes levam a essa conclusão, mas não sozinhos. É o refactoring e reimplementação durante os testes que leva o sistema a funcionar. Um programador mentecapto nunca irá colocar o programa a funcionar por muitos testes que existam.

Acho que é isso que fica das palavras do Knuth: parem de procurar nas metodologias o que falta em conhecimento fundamental.

Criando sua própria API de Validação



Blog do MiddleHeaven
[WWW]
cmoscoso
Virtual Machine Man

Membro desde: 23/10/2007 10:08:29
Mensagens: 687
Offline

Bruno Laturner wrote:
Ouvi falar que o melhor modo de tratar isso é instalar um SGBD localmente e zerar os registros antes de começar os testes.

TDD precisa de uma ambiente mínimo para funcionar?


A principio nao importa se vai ser em memoria, banco de dados local ou remoto desde que seja um espaco onde nao exista interferencias externas. Lembrando que testes unitarios, cada desenvolvedor tem seu processo de build isolado dos demais desenvolvedores no projeto.

Em se tratando do ambiente, eu concordo quando o sergiotaborda diz "TDD é um processo moroso e pouco ágil.." mas ao mesmo tempo é a estrategia mais eficaz que conheco pra desenvolvimento que envolva mais de 1 programador. Isso inclui code ownership, CI e tudo aquilo que TDD compreende alem de testes do desenvolvedor. Este ultimo principalmente acho util no modo solo mas TDD como todo nao oferece tantos beneficios evidentes.
[Email]
Edufa
JavaEvangelist
[Avatar]

Membro desde: 18/04/2006 10:20:03
Mensagens: 315
Localização: Curitiba, PR
Offline

Luca wrote:
Acho que ninguém aqui aprendeu a programar fazendo testes. A gente sabe que é bom e tudo o mais mas começar a programar pelos testes exige um certo esforço mental.
(...)
Sabem do que sinto falta? De um tutorial explicando como fazer isto usando o eclipse (ou o Netbeans) desde a criação e organização das classes de teste e das classes testadas. Alguns dos melhores links que conheço são também do Chapiewski:


Assino embaixo Luca, na minha opinião é uma falha. Se vários tutoriais viessem com testes unitários, bem como exemplos, ficaria muito mais fácil incorporar estes hábitos sem contar que seria vantajoso verificar como outros usam os testes e ainda ver como certas funcionalidades são testadas.

Seria uma grande mudança da forma de se programar, por mais que falem muito de TDD, sem exemplos a maioria acaba não se acostumando e desiste, sem contar que o esforço de usar algo pouco demonstrado aumenta consideravelmente.

E quando digo pouco demonstrado, não me referi a tuoriais de como usar TDD, isso existe e muitos os conceitos estão bem explicados, é relativamente fácil de entender o q se propões, mas o uso prático, ver os testes, ver como estão usando e resolvendo situações parecidas, comparar, e por isso para aprender através deles ainda falta muito.

Sempre que pego um sistema ou projeto para estudar, a primeira coisa que verifico são os testes unitários, e uma infima minoria se preocupa com eles, e muitos ainda são primários, testando coisas óbvias e deixando de lado testar a lógica de negócio.

Edufa
Curitiba, PR
--
"O estado sou eu". - Luís XIV
"O estado somos nós."- Lênin
"O estado somos eu." - Lula
--
O mundo é deles mas a amazônia é nossa
O petróleo é nosso, mas o gás é deles.
Luiz Aguiar
Moderador
[Avatar]

Membro desde: 23/01/2005 00:05:55
Mensagens: 3840
Localização: São Paulo
Offline

Aqui tem ótima referências:
http://dojofloripa.wordpress.com/2007/09/10/tudo-sobre-tdd/



-
Blog de Tecnologia
GitHub
@AguiarLuiz
Recicla SP na App Store!




[WWW] [MSN] [ICQ]
dreamspeaker
GUJ Ranger
[Avatar]

Membro desde: 22/04/2003 10:09:58
Mensagens: 752
Localização: SP - Capitar
Offline

sergiotaborda wrote:... É por isso que se chama Desenvolvimento guiado por teste (TDD). Em TDD raramente ha a necessidade de mocks porque vc não está simulando o funcionamento do sistema, vc está escrevendo como ele vai se comportar. Claro que mocks são uteis em situações complexas que acabarão aparecendo, mas não são o foco nem a ferramenta principal...


Ando estudando TDD esses ultimos dias, muito bom seu post. Mas fiquei meio confuso no "raramente". Escrever como o sistema vai se comportar não indica o uso de recursos externos? Claro que a super utilização de mocks mostra que o que você esta escrevendo provavelmente está com um acoplamento muito alto, mas via de regra sempre há algum acoplamento. Esse "raramente" é tão "raramente" assim?




André Barbosa
Para de encher o saco e vai doar sangue!
twitter
[Email] [WWW]
Bruno Laturner
GUJ Expert
[Avatar]

Membro desde: 18/02/2008 16:17:53
Mensagens: 3002
Offline

Ótima resposta Sérgio!

Eu já faço a distinção entre fazer testes e fazer TDD, meio que coloquei isso na frases grifadas. "Como começo a fazer testes" é o meu objetivo inicial, o começo de tudo, "Como tornar isso um hábito, um TDD de fato" é o meu objetivo final.

Concordo demais com que fala de exemplos de revistas, elas se focam demais em "testar que instrumentos musicais estão afiados", pouco falam de testar se os músicos sabem tocá-los e ler as partituras, e nunca falam sobre como garantir que a orquestra ser um sucesso.

Outra, por acaso testar as partes garante que o todo funcione?

No caso que descreveste, não é demais ter ver se o email foi enviado certo, se a mensagem Jms chegou, verificar o que no banco mudou, de o resultado do processamento do arquivo está certo? Testar cada um em separado já não garantiria tudo?

Um programador mentecapto nunca irá colocar o programa a funcionar por muitos testes que existam.

Conseguirá se o que ele fizer passar em todos os testes; All green. Como você disse "A preocupação é como o que a classe deve fazer e não como ela deve fazê-lo."

Se bem que se ele consegui essa "façanha", ele não será mentecapto.

A resposta acima foi achada em menos de 5 minutos no google.
The prisoner falls in love with his chains. --E.W. Dijkstra
[WWW]
 
Índice dos Fóruns » Metodologias de Desenvolvimento e Testes de Software
Ir para:   
Powered by JForum 2.1.8 © JForum Team