Nice post… I agree at some points…
and, I don´t have much knowledge in TDD…
But one thing in sure: it´s better to write a code to test another,
than to test on the UI all the time.
I recently work on a Library software (actual, fisical library… books and stuff)…
Had ALOT of “merged” logics… JUnit and Mockito help me in a way that i can´t describle.
Well… keep it up
***Vou traduzir pra não ter problemas, apesar de não precisar (só quem sabe ingles poderia comentar o topico…)
Gostei cara,
mas na verdade é muito melhor escrever um código que testa outro, do que ir, rodar a aplicação e testar na unha…
Estava desenvolvendo um modulo para controle de bibliotecas…tinha mta logica unida com outra… JUnit
e Mockito me pouparam algumas horas de testes …
abraços
esmiralha
Primeiro, ele afirma que o programador tem uma intuição natural para perceber quais partes do código são mais sujeitas a erros e que dessa forma ele codificaria essas partes com mais cuidado, evitando assim os bugs. Isso é um absurdo. Se isso fosse verdade, não existiria bug em software…
Segundo, ele fala que a interface gráfica é a parte mais importante de um software e a mais buguenta. Isso é uma sandice tão grande que dá pena. A interface gráfica é importante pra cacete, mas o que mais importa é o domínio essencial da aplicação. A interface gráfica vai se entupir de bugs se você enfiar as regras de negócio dentro dela, como ele parece sugerir.
Terceiro, ele diz que testes unitários introduzem bugs por aumentarem a complexidade do código. Isso também é bizarro, porque testes unitários desenvolvidos em TDD tendem a diminuir a complexidade da interface pública e reduzir o número de dependências da classe. Isso aumenta a coesão da classe e reduz o acoplamento.
Quarto, ele diz que tornar uma classe testável por testes unitários exige que você use alguns design patterns complicando o design. Ele esquece de mencionar QUAIS design patterns. Será que ele sabe?
saoj
Bug existe com ou teste unitário.
Concordo com vc.
Com certeza ela não estava falando de TDD. Mas esse negócio de acoplamento pode ser um tiro no pé, as famosas milhares de camadas.
Ele tava falando do pattern DECORATOR.
tnaires
Eu até tento, mas não consigo concordar com tudo.
Claro que é impossível testar todas as possibilidades. Mas isso não é razão para não escrever os testes. Além disso, o autor quer evitar empregar esforço escrevendo testes, mas ele não enxerga que no futuro terá que arcar com problemas no código que seus testes poderiam ter captado tranquilamente, se ele os tivesse escrito. A hora de pensar sobre o que pode dar errado com o seu código é o momento em que você o escreve, porque dois dias depois você mal lembra o que aquele código fazia.
Posso ter entendido errado, mas aqui o autor parte do princípio que ele nunca comete erros bobos de digitação de código, como escrever um método pra somar dois números e usar o sinal de multiplicação sem querer.
Aqui concordo com o autor - não se usa teste unitário pra testar interface.
Aqui é uma questão de opinião. Eu definitivamente não acho que escrever testes unitários seja “boring”, e muita gente que usa TDD também não acha. Mas se o autor não acha legal, aí não tem argumento que o convença.
Usar TDD pode nos ajudar a ver o que está errado com nosso código. Ter que criar muitos mocks para testar um código pode ser sinal de bad smell. E o autor generaliza quando ele diz que provavelmente os erros descobertos pelos testes unitários são provocados pelo próprio uso de TDD. Sobre as interfaces, elas são particularmente úteis em linguagens com tipagem estática, como Java, mas não o são por causa do TDD. Programar orientado a interfaces é um princípio de desacoplamento, e as pessoas o seguem mesmo quando não escrevem testes.
saoj
tnaires:
Usar TDD pode nos ajudar a ver o que está errado com nosso código. Ter que criar muitos mocks para testar um código pode ser sinal de bad smell. E o autor generaliza quando ele diz que provavelmente os erros descobertos pelos testes unitários são provocados pelo próprio uso de TDD. Sobre as interfaces, elas são particularmente úteis em linguagens com tipagem estática, como Java, mas não o são por causa do TDD. Programar orientado a interfaces é um princípio de desacoplamento, e as pessoas o seguem mesmo quando não escrevem testes.
Ele não criticou interface, que é fundamental e o que Java tem de melhor. Ele criticou o pattern DECORATOR (delegate) que busca desacoplar e isolar tudo nos sistemas a fim de facilitar os testes transformando o sistema numa zona incompreensível de bonecas russas. Eu já vi sistemas assim… é um pain-in-the-ass…
Y
YvGa
saoj:
tnaires:
Usar TDD pode nos ajudar a ver o que está errado com nosso código. Ter que criar muitos mocks para testar um código pode ser sinal de bad smell. E o autor generaliza quando ele diz que provavelmente os erros descobertos pelos testes unitários são provocados pelo próprio uso de TDD. Sobre as interfaces, elas são particularmente úteis em linguagens com tipagem estática, como Java, mas não o são por causa do TDD. Programar orientado a interfaces é um princípio de desacoplamento, e as pessoas o seguem mesmo quando não escrevem testes.
Ele não criticou interface, que é fundamental e o que Java tem de melhor. Ele criticou o pattern DECORATOR (delegate) que busca desacoplar e isolar tudo nos sistemas a fim de facilitar os testes transformando o sistema numa zona incompreensível de bonecas russas. Eu já vi sistemas assim… é um pain-in-the-ass…
Pois eh, Sergio, eu concordo plenamente com voce sobre a simplicidade de código e a complexidade que os design patterns trazem quando sao usados em lugares onde nao se precisa deles.
Eu ja vivi, na verdade ainda vivo (faltam muitos para remover), na pele o problema das bonecas russas, mas isso nao eh culpa da existencia dos patterns, mas do mau uso deles. O decorator, o template method, são exemplos classico do inferno que eles podem provocar, com camadas em cima de camadas, quando sao mal utilizados.
E os testes unitarios tem menos ainda a ver com essa desgraça toda. A unica coisa que eles exigem é codigo desacoplado. Mas qual eh o primeiro entendimento que os programadores tem quando se fala em código acoplado. Ah, vou desacoplar tudo, vou por mock e remover minhas dependencias.
Usar mock pra todo lado não eh desacoplar, eh sim uma confissao de que voce vai precisar viver com aquele acoplamento. Isso pode ou não ser verdade, principalmente em etapas transitorias de um refactoring em codigo legado. Por enquanto voce vai ter que viver com aquele acoplamento, entao o mock te ajuda. Mas voce não desacoplou porcaria nenhuma.
TDD nao precisa de design pattern “sofisticado”, eles não levam as bonecas russas de jeito nenhum e precisa de mock em pontos bem especificos o que não te torna dependente deles. TDD não é chato na minha opinião, bem pelo contrário e, uma vez que você tem os principios basicos OO bem definidos na sua cabeça é algo muito simples.
Mas se voce for fazer uma convergencia para ver para onde os problemas do testes que voce ja viu levam você vai identificar um mesmo ponto comum, a absoluta falta de conhecimento dos principios OO, só que aí o problema está em quem fez os testes, não nos testes em si.
Dont throw the baby with the bath water. Você está querendo culpar a chuteira porque o atacante do seu time não consegue fazer gol.
Eu acho muito justo e acho que voce tem todo o direito de não querer escrever testes, mas não é isso que vai fazer com que os testes sejam ruins.
Rubem_Azenha
Mais um cara que quer aumentar número de acessos e o pagerank do blog dele por fazer um crítica (bem fraquinha, na minha opinião) num conceito bem estabelecido.
Luizao
Eu não entendo porque o pessoal gosta tanto de falar mal de testes automatizados… testes fazem parte do desenvolvimento, e se dá pra automatizar, por quê não? Vc vai ter que testar o código de qualquer jeito, se vc não escreve testes vai ter que testar na mão…
J
JoseIgnacio
Você sabe que o erro existe e a solução, você pode consertar o erro e voltar a ser produtivo ou criar outro código com o único intuito de testar a solução que acabou de criar.
Acho que isso responde porque muitos preferem não automatizar.
Luizao
Vc vai ter que testar o código de qualquer jeito. A vantagem de automatizar é que quando precisar testar novamente vc já tem tudo pronto :).
S
Skim
Na minha opinião testes a mão tem q ser feitos com ou sem testes automatizados. Eu acho q um da uma mão p o outro.
Y
YvGa
Na minha opinião testes a mão tem q ser feitos com ou sem testes automatizados. Eu acho q um da uma mão p o outro.
Com certeza, teste com o sistema sendo executado tem que ter independente de haver ou nao teste unitario. A diferenca é o quanto voce consegue testar com um e outro.
Luizao
Na minha opinião testes a mão tem q ser feitos com ou sem testes automatizados. Eu acho q um da uma mão p o outro.
Com certeza, não dá pra dispensar teste manual. O meu ponto é: se dá pra automatizar algumas coisas, porque não?
javaflex
Acho teste unitário importante pra manter regras de validação dentro do esperado. Já pra automatizar testes à vera contra bugs, só mesmo teste funcional, com Selenium por exemplo, pois a interface gráfica é mesmo mais sensível a bugs, considerando tecnologia web, linguagem com tipagem dinâmica como javascript é muito mais propensa a erros inesperados se a complexidade da página for alta, com várias interações gráficas, etc.
saoj
Acho legal teste FUNCIONAL automatizado via JUnit. Obviamente não é porque usa o JUnit que é teste unitário né?
Já testes unitários acho que não se pagam. Entrava o projeto inteiro, cria uma burocracia absurda, qualquer alteração no código implica alteração no teste unitário, não pega nenhum bug importante só e não garante nada, etc. Minha opinião pessoal apenas.
Já testes funcionais são mais big-picture, documentam a sua API e te dão uma tranquilidade para saber que pelo menos as funcionalidades core do seu sistema não foram quebradas.
Selenium como vc falou é uma ótima mesmo!
javaflex
Acho legal teste FUNCIONAL automatizado via JUnit. Obviamente não é porque usa o JUnit que é teste unitário né?
Já testes unitários acho que não se pagam. Entrava o projeto inteiro, cria uma burocracia absurda, qualquer alteração no código implica alteração no teste unitário, não pega nenhum bug importante só e não garante nada, etc. Minha opinião pessoal apenas.
Já testes funcionais são mais big-picture, documentam a sua API e te dão uma tranquilidade para saber que pelo menos as funcionalidades core do seu sistema não foram quebradas.
Selenium como vc falou é uma ótima mesmo!
Manutenção de testes unitários é um inferno mesmo, é bom ter um gerador de cenário. O retorno disso depende da criticidade da aplicação, tendo proveito em regras muito críticas que não podem falhar, onde traria grandes prejuízos pra empresa, como grandes multas, perda de vida etc, mas não acho proveitoso mesmo fazer teste unitário de tudo só pra dizer que fez, claro que teria algum retorno, mas muito pequeno diante do grande esforço. E com Selenium realmente temos o “teste do sistema” automatizado pra valer, não adianta ter teste unitário se o jquery falhar por algum motivo. Exagero nunca é bem vindo, assim como usar e abusar de Hibernate pra tudo no sistema, ao invés de usar só onde ele traz bom retorno.
marioareias
Posso estar enganado, mas o autor do artigo não sabe fazer testes unitário. Por exemplo nesse trecho:
Rapaz, nenhum tipo de teste vai testar todas as permutações do seu código. Esquece. O teste unitário servem para testar métodos e se ele não consegue testar todas as permutações dos métodos dele, bom, o método dele tá fazendo coisa demais.
Bom, os teste unitários pegam alguns bugs sim, com um feedback bem rápido. Mas não é nem de longe todos os bugs possíveis, por isso temos outros tipos de teste como o saoj falou teste funcionais e talz. A grande sacada do TDD é que te ajuda com o design do teu sistema. Por exemplo, no caso do autor, os testes unitários estão mostrando pra ele que os método deles estão fazendo muita coisa e ele ao invés de entender e arrumar, ele prefere meter pau no TDD. Basicamente se tá muito difícil de manter ou criar um teste unitário no teu sistema, o teu design deve estar bem errado. Design errado não quer dizer que o sistema não funciona, design errado quer dizer que muitas para vezes para dar manutenção no sistema você vai sofrer pra entender o que tá acontecendo.
Isso aqui é parte da verdade. Se for um sistema Web, tu pode fazer testes unitários de javascript. Mas com certeza, tem outras ferramentas também, como o Selenium.
De novo, acho que isso é baseado na má experiência dele com testes unitários. O objetivo do TDD é deixar o teu código simples e de fácil manutenção e quando você precisa refatorar, você tem vários testes que garantem que você não quebrou nada (ao menos garante que o resultado que um determinado método esperava continua sendo o mesmo). Se ele acha perda de tempo, boring e complicado ele não está fazendo direito.
Para concluir deixar o Selenium testar tudo na sua aplicação é a pior coisa que você pode fazer. Os testes de Selenium não são muito confiáveis e explico o porque. Como o teste vai rodar na tua aplicação como um todo, ele vai acessar todos os pontos de integração do teu sistema. Banco de dados, Web Services e etc. Se algum desses serviços não funcionar direito, pode quebrar teus testes e confundir os desenvolvedores achando que foi o código deles que quebrou. Outra coisa, testes de Selenium demoram para rodar, afinal é como se fosse um usuário acessando o teu sistema. É muito fácil você ter teste de Selenium que demoram HORAS para rodar. Num projeto onde você tenha CI em que rodam os teus testes, o feedback para o desenvolvedor saber se o código dele tá certo ou não seria imenso. Somando isso a demora com teste não tão confiáveis é muito fácil pra equipe não ligar mais para esse tipo de teste. Já visso acontecer algumas vezes
Selenium é uma ferramenta boa, mas para ser usada com cuidado. Tem que ser a última saída. Existem outros tipos de testes como teste unitários e de serviço. Aliás tem um artigo interessante do Martin Fowler falado sobre a pirâmide de testes. Pode dar uma olhada aqui
javaflex
Sim tudo tem ser usado com cuidado conforme a real necessidade. Rodar testes no Selenium é naturalmente lento, mas não é algo pra ser rodado toda hora em checkins, mas sim no final de uma sprint, antes do deploy pra homologação, afim de pegar erros onde “não foi mexido”, já o que foi mexido e previsto de impacto teve seu teste feito e rodado individualmente após sua implementação finalizada por cada um da equipe, embora por garantia também serão rodados no final de tudo. Sobre algum serviço não funcionar, aí já é problema da infraestrutura manter a coisa funcionando com a mesma importância de um ambiente de produção. Se algo de ambiente falhar faz parte mesmo, mas o teste em si é confiável se houver tempo investido pra mantê-lo certo. Enfim, é tudo questão de usar ao nosso favor e não usar tudo por etiqueta.
marioareias
javaflex:
Sim tudo tem ser usado com cuidado conforme a real necessidade. Rodar testes no Selenium é naturalmente lento, mas não é algo pra ser rodado toda hora em checkins, mas sim no final de uma sprint, antes do deploy pra homologação, afim de pegar erros onde “não foi mexido”, já o que foi mexido e previsto de impacto teve seu teste feito e rodado individualmente após sua implementação finalizada. Sobre algum serviço não funcionar, aí já é problema da infraestrutura manter a coisa funcionando com a mesma importância de um ambiente de produção, se algo não rodar faz parte mesmo… É tudo questão de usar ao nosso favor e não usar tudo por etiqueta.
Você diz para executar só no final do sprint? Então o feedback tu só vai ter de duas em duas semanas? Acho um feedback looongo de mais. Tu só vai achar o bug no final do sprint e no outro sprint provavelmente vai ficar arrumando os bugs do sprint anterior.
E em relação a infra, tu não consegue controlar a infra de Web Service de terceiros, por exemplo. Outra coisa é que dependendo do porte do teu software não tem como tu manter um ambiente igual ao de produção no teu de testes. É simplesmente muito caro e complicado demais para fazer. Em software pequenos isso é plenamente acessível, mas em softwares muto grandes, muitas vezes, não é não.
javaflex
Não, bugs que aparecem no final são geralmente coisas pequenas, pois envolve pouco do que mexemos durante a sprint, tudo que é mexido e impactado durante a sprint são feitos ou alterados testes durante a própria implementação de cada história, então já existe uma boa parcela de garantia a cada término de uma história. E no final de tudo só aparecem erros inesperados, tipo algo que o designer mexeu no CSS e quebrou algum jquery ou algo genérico que impactou outra coisa que esqueceram de prever, etc. Geralmente bugs pequenos em telas jamais mexidas diretamente e que normalmente só pegaríamos quando estivesse em produção. E o deploy também é uma “história” (entra na gordura), tem postits rotineiros, ou algo de atenção, e entre eles “rodar os testes” e dependendo do resultado distribuir pra equipe resolver os imprevistos. E tudo é repeitado dessa forma por ter dado mais certo até então, não que seja o melhor pra todo caso, cada equipe trabalha da melhor forma que as pessoas se sintam produzindo melhor no momento e daí vai evoluindo, sem ditadura.
marioareias:
E em relação a infra, tu não consegue controlar a infra de Web Service de terceiros, por exemplo. Outra coisa é que dependendo do porte do teu software não tem como tu manter um ambiente igual ao de produção no teu de testes. É simplesmente muito caro e complicado demais para fazer. Em software pequenos isso é plenamente acessível, mas em softwares muto grandes, muitas vezes, não é não.
Sim vai depender do caso, falei de um caso particular, nesse caso a infra é na própria empresa que tem o setor de desenvolvimento, mas os sistemas são grandes e a empresa também. Já em sistemas menores que as vezes pego por fora não faço testes automatizados nenhum, por não ter investimento mesmo para isso.
Ah, e outra coisa, Selenium não exclui os testes unitários, não sei se interpretou assim, pois são dois níveis de teste.
Y
YvGa
Concordo com você. Esse cara tem muito pouca experiencia com TDD, desde o conceito até a prática. Ok, tudo que você sabe que precisa ser testado, você saberá fazer certo. Correto?
Não, não é correto, pois como disse alguem lá nos próprios comentários do post dele, se fosse assim não haveria bugs em software. E eles existem aos montes. Então sim, os pontos que sabemos ser problemáticos precisam obrigatoriamente ser testados. O ponto é como.
Nós podemos largar tudo nas costas de testadores, com testes funcionais manuais pra encontrar bugs em um sistema já pronto. Que ainda é a prática comum hoje. Mas nós podemos também prevenir a entrada de bugs através de testes automatizados. Acho que até aqui ninguem discorda, certo?
Nós podemos automatizar testes funcionais nos caminhos principais com ferramentas como o Selenium. Isso ajuda bastante, vamos descobrir o bug antes do que se esperarmos a turma da qualidade chegar, mas dificilmente saberemos onde exatamente está o problema sem que tenhamos que apelar para grandes sessoes de debug. Os erros podem não se repetir em todas as circunstancias, pode não acontecer em todas as configuracoes, para todos os clientes, para todas as versoes. E em cada cenario desse, se quisermos cobertura para eles, precisamos ter testes.
Manter testes nessas ferramentas é muito mais custoso do que simples testes unitarios, em todos os aspectos. Só que já trabalhou com eles sabe. Alterar um teste de uma funcionalidade no selenium pode ser bem complicado, além de que um mesmo problema pode fazer com que inumeros testes se quebrem. Testes unitarios são mais simples e específicos, quando algo quebra, quebra poucos testes. Os cenarios sao mais faceis de montar e de manter. Ou seja, exigem menos esforço.
Bugs existem e TDD não te livra deles, mas te livra sim de bugs recorrentes. Além de ajudar muito a não introduzir novos. Lógico algo pode acabar escapando, mas nunca pela segunda vez.
Nós não temos o direito de usar a física tradicional nas nossas aplicações, como podem os engenheiros, então nós deviamos criar a física da nossa aplicação. Validar regras de negócio automaticamente é uma forma de colocar constraints “físicas” aos nossos processos e ter certeza que continuam de acordo com o que queremos. Eu ainda não conheço nenhum forma melhor de fazer isso do que através de testes unitários. Se alguem tiver que a traga, pelo menos a proposta, que eu a recebo de braços abertos, ao menos para avaliá-la.
Só não tentem me convencer de que não existir leis regendo nossas aplicações é uma coisa boa e que tê-las em nada me ajuda.
No mundo da física uma pessoa ao cair não passa do chão, não deve passar e assim deve ser. No mundo do software eu preciso garantir que ele não passará e verificar sempre se ela continua garantindo para não ter inconsistencia. Então eu preciso sim de um teste automatico que me dê a segurança de que ao fazer uma alteração na lei da gravidade e não esteja, sem querer, permitindo que alguem caia e vá alem do chão.
As vezes meus comentarios se tornam repetitivos através de vários posts diferentes, mas não consigo não reagir aos ataques a uma tecnica que mudou da agua pro vinho a qualidade das aplicacoes que eu faço. Então quem anda tentando e está desanimado, insista por que o problema pode estar em sua pouca experiência e não no TDD. Não que eu seja um expert, mas já consigo tirar bastante proveito.
Podemos chegar a conclusão então de que TDD não é feito com a intenção de detectar todos os tipos de bugs no código mas sim de criar um código legível e que siga o principío do SOC (Separation of concerns)?
Ou seja, quem escreve bons código não precisa do TDD para se prevenir de bugs, mas quem ainda não tem experiência pode se valer do TDD para ajudar a escrever bons códigos?
Abs
marioareias
André Fonseca:
oi,
Podemos chegar a conclusão então de que TDD não é feito com a intenção de detectar todos os tipos de bugs no código mas sim de criar um código legível e que siga o principío do SOC (Separation of concerns)?
Ou seja, quem escreve bons código não precisa do TDD para se prevenir de bugs, mas quem ainda não tem experiência pode se valer do TDD para ajudar a escrever bons códigos?
Abs
TDD pega alguns bugs sim, mas não pega todos. Aliás, nenhum tipo de teste pega todos os bugs. O único método infalível de pegar todos os bugs é chamado de Usuário. Ele com certeza vai achar todos
Me apresentar o programador que escreve código sem bugs que eu preciso aprender com ele. E não é só quem não tem experiência que usa TDD, muito desenvolvedor bom que eu conheço usa TDD. E carinhas bem fraquinhos como Kent Beck, Uncle Bob, Michael Feathers usam TDD também rs
maior_abandonado
André Fonseca:
oi,
Podemos chegar a conclusão então de que TDD não é feito com a intenção de detectar todos os tipos de bugs no código mas sim de criar um código legível e que siga o principío do SOC (Separation of concerns)?
Ou seja, quem escreve bons código não precisa do TDD para se prevenir de bugs, mas quem ainda não tem experiência pode se valer do TDD para ajudar a escrever bons códigos?
Abs
eu considero que a filosofia de testes unitários vai além disso, uma das coisas que eu acho bem legal é que você também tem nos seus testes automatizados a garantia de que o bug não voltará, por que teoricamente você terá um teste que dará o erro e evidenciará caso o bug aconteça, sendo assim caso alguém acabe por inserir novamente algum bug no código em manutenção (não vou questionar os motivos, seriam muitos), ao executar os testes você terá a evidencia disso, o que aumenta a confiabilidade do software.
considero que tem seus pontos negativos também, aumenta uma camada de complexidade mas, por outro lado melhora no sentido da garantia da qualidade e da organização… como todo o resto use com moderação, saiba o que está usando e não terá problemas.
maior_abandonado
marioareias:
André Fonseca:
oi,
Podemos chegar a conclusão então de que TDD não é feito com a intenção de detectar todos os tipos de bugs no código mas sim de criar um código legível e que siga o principío do SOC (Separation of concerns)?
Ou seja, quem escreve bons código não precisa do TDD para se prevenir de bugs, mas quem ainda não tem experiência pode se valer do TDD para ajudar a escrever bons códigos?
Abs
TDD pega alguns bugs sim, mas não pega todos. Aliás, nenhum tipo de teste pega todos os bugs. O único método infalível de pegar todos os bugs é chamado de Usuário. Ele com certeza vai achar todos
Me apresentar o programador que escreve código sem bugs que eu preciso aprender com ele. E não é só quem não tem experiência que usa TDD, muito desenvolvedor bom que eu conheço usa TDD. E carinhas bem fraquinhos como Kent Beck, Uncle Bob, Michael Feathers usam TDD também rs
pior que nem chamando o usuário…
de repente ele pega a maioria dos de negócio… mas mesmo isso ainda é bem relativo…
marioareias
maior_abandonado:
pior que nem chamando o usuário…
de repente ele pega a maioria dos de negócio… mas mesmo isso ainda é bem relativo…
Se ele não achar o bug, é porque ele não tá usando. Se ele não tá usando, o código nem deveria ter sido feito. Se o código não deveria ser feito, não deixa de ser um problema
Andre_Fonseca
marioareias:
André Fonseca:
oi,
Podemos chegar a conclusão então de que TDD não é feito com a intenção de detectar todos os tipos de bugs no código mas sim de criar um código legível e que siga o principío do SOC (Separation of concerns)?
Ou seja, quem escreve bons código não precisa do TDD para se prevenir de bugs, mas quem ainda não tem experiência pode se valer do TDD para ajudar a escrever bons códigos?
Abs
TDD pega alguns bugs sim, mas não pega todos. Aliás, nenhum tipo de teste pega todos os bugs. O único método infalível de pegar todos os bugs é chamado de Usuário. Ele com certeza vai achar todos
Me apresentar o programador que escreve código sem bugs que eu preciso aprender com ele. E não é só quem não tem experiência que usa TDD, muito desenvolvedor bom que eu conheço usa TDD. E carinhas bem fraquinhos como Kent Beck, Uncle Bob, Michael Feathers usam TDD também rs
Eu não quis dizer que só quem não tem experiência usa TDD, eu acho que quem não tem experiência pode se valer do TDD para escrever bons códigos
maior_abandonado
marioareias:
maior_abandonado:
pior que nem chamando o usuário…
de repente ele pega a maioria dos de negócio… mas mesmo isso ainda é bem relativo…
Se ele não achar o bug, é porque ele não tá usando. Se ele não tá usando, o código nem deveria ter sido feito. Se o código não deveria ser feito, não deixa de ser um problema :)
muito pelo contrário, ele pode estar usando e dependendo do bug ele não encontrar (na verdade não somente dependendo do bug… dependendo do usuário também…rs)
isso é plenamente… normal…
inclusive se fosse assim não existiriam mais bugs no windows (clássico exemplo), usuário desse istema operacional é o que não falta, tem gente usando, por que que ainda se encontra bug então, ainda nos dias de hoje? editando para explicar melhor… por que que ja não foram todos encontrados? muitas vezes muitos bugs passam batido, isso é a coisa mais normal do mundo…
marioareias
maior_abandonado:
muito pelo contrário, ele pode estar usando e dependendo do bug ele não encontrar (na verdade não somente dependendo do bug… dependendo do usuário também…rs)
isso é plenamente… normal…
inclusive se fosse assim não existiriam mais bugs no windows (clássico exemplo), usuário desse istema operacional é o que não falta, tem gente usando, por que que ainda se encontra bug então, ainda nos dias de hoje? editando para explicar melhor… por que que ja não foram todos encontrados? muitas vezes muitos bugs passam batido, isso é a coisa mais normal do mundo…
Cara, tu não entendeu o que eu falei. Meu ponto é se teu usuário não acha bug em determinado lugar de um software, ele é porque ele não está usando esse determinado lugar do software. Exemplo é o Word com toneladas de funcionalidades, com certeza devem ter alguns pequenos bugs que ninguém nunca viu, porque ninguém precisou usar. Se não tem usuário usando aquele funcionalidade, ela nem deveria ter sido feita. Foi dinheiro e tempo desperdiçado, o que por si só já um problema.
Não concordo com isso de ser plenamente normal. Aliás, acho isso muito fora do normal. Se um usuário usa uma determinada funcionalidade e a funcionalidade tá bugada, ele VAI achar o bug. Ponto.
Y
YvGa
Nao creio que seja o caso porque para extrair o melhor do TDD é preciso bases sólidas dos conceitos OO. Se não nascem as macarronadas que acabam causando péssima impressão em quem herda uma bateria de testes mal feita. Se você se refere a alguem sem experiência, mas sendo assistido eu concordo.
Concordo também com o Mário, quanto a bugs não encontrados. Se algo não é usado é porque não é necessário e foi gasto tempo/dinheiro em algo desnecessário.
Bom se todo o problema fosse esse. Mas há algo ainda mais sério e eu vivo isso na pele atualmente.
Existe um calculo de correção de valor na aplicação na qual trabalho que em determinadas circunstancias pode ser obtida através de um índice, cujo cálculo é beeeem mais complexo do que o normal. Há pouco tempo eu descobri que ele não é usado, nunca foi usado por essa versão, foi criado porque havia a necessidade nos tempos de inflação altissima (que já se foi há mais de vinte anos). Mas ele está lá, para o caso de alguem precisar um dia.
E eu não consigo convencer o pessoal de negócios a tirar o maldito cálculo. “Frescura”, eles dizem, “se já está pronto, deixa ele lá”. Quem lê pode pensar que eles têm razão, mas sou eu que tenho que ficar desviando aquele trem o tempo todo, testando a funcionalidade quando preciso alterar, cuidando para que os testes dela não quebrem. E pior ainda, arrumar quando eles pegam algo errado.
Seria muito mais simples jogar aquilo fora e reimplementar quando for o caso, mas não o fazem por preciosismo.
Esse tipo de coisa encarece o produto.
marioareias
Caso clássico de otimização prematura. Até fiz um blog post sobre isso. Muitos clientes tem esse tipo de pensamento vai que alguém um dia talvez precise. Realmente é um problema.
saoj
Como mencionei no post de abertura desse tópico, testes unitários exigem uma arquitetura muito desacoplada onde tudo precisa ser testável isoladamente. Qualquer herança que não seja de classe abstrata se torna um crime e o cara precisa abusar do pattern decorator (composição com delegate) criando 10 níveis de boneca russa e implementações “do nothing” das interfaces para quando ele quiser desativar uma funcionalidade. Minha experiência prática: é um LIXO. Nem o “open call hierarchy” funciona direito porque a implementação pode ser uma das 1000 existente e vc não tem como saber no compile time.
Esse é apenas um dos efeitos colaterais do extremismo com testes unitários e patterns: too many moving parts, complexity, dificuldade para fazer qualquer alteração no código, a coisa fica engessada, uma pentelhação para evoluir, etc.
Foi o que o cara falou:
Eu concordo com cada carácter dessa afirmação.
marioareias
A minha experiência com TDD é beeeeem diferente da sua. Pelo contrário, o TDD faz o meu código ficar mais simples, legível e sem essas camadas todas aí que você citou. Na minha experiência o TDD ajuda muito para contribuir com o Emergent Design. Ele aponta falhas muito facilmente. Se o design fica como você falou com tantas camadas e complexidade é porque quem fez, não soube reconhecer isso e alterar na hora certa.
Na minha opinião, quem faz design ruim com TDD, faz design ruim sem TDD. Quem faz design bom sem TDD, faz ainda melhor com TDD. E quando se está trabalhando em equipe, é sempre bom encontrar uns testes que te mostram como determinada classe funciona e que te ofereçam uma certa proteção na hora de alterar.
Concordo plenamente que testes bagunçados, difíceis de dar manutenção são horríveis e mais atrapalham do que ajudam. Mas quem fez esses testes também cria classes ruins, com design ruim.
TDD não faz milagre, é uma técnica que te ajuda em alguns pontos. Mas no final das contas, quem faz o código ser bom ou não é o desenvolvedor. Tem muito desenvolvedor bom que não gosta de TDD (como o saoj) e muito desenvolvedor que coloca a culpa no TDD pelos erros que comete todo dia. E nem tentam melhorar.
TDD (assim como qualquer outra coisa) não é unanimidade, tem quem defenda, tem quem ataque. Mas com certeza facilita o meu trabalho
saoj
Existe teste unitário com TDD e teste unitário sem TDD. Acho que o cara estava falando do último. Eu nunca experimentei fazer um sistema usando TDD, então não tenho como opinar. O ponto é que algumas pessoas usam os testes unitários para justificar a zona da arquitetura: “é uma zona mas eu consigo testar tudo de forma independente”. O pior é que muitas vezes eles nem sabem que está uma zona, pois nunca viram a coisa limpa. Acham que complexidade é um “efeito colateral inevitável” e que programação é coisa pra gente inteligente mesmo, logo se o cara não entende ou tem dificuldade é porque ele é burro. Faz o cara que fez a coisa se sentir “cool”. Taí a separação republicano x democrata na área de programação: simplicidade x complexidade.
Não estou falando que é o seu caso, Mario. Mas é o que eu já vi por aí.
Y
YvGa
saoj:
Como mencionei no post de abertura desse tópico, testes unitários exigem uma arquitetura muito desacoplada onde tudo precisa ser testável isoladamente. Qualquer herança que não seja de classe abstrata se torna um crime e o cara precisa abusar do pattern decorator (composição com delegate) criando 10 níveis de boneca russa e implementações “do nothing” das interfaces para quando ele quiser desativar uma funcionalidade. Minha experiência prática: é um LIXO. Nem o “open call hierarchy” funciona direito porque a implementação pode ser uma das 1000 existente e vc não tem como saber no compile time.
Esse é apenas um dos efeitos colaterais do extremismo com testes unitários e patterns: too many moving parts, complexity, dificuldade para fazer qualquer alteração no código, a coisa fica engessada, uma pentelhação para evoluir, etc.
Foi o que o cara falou:
Eu concordo com cada carácter dessa afirmação.
Sergio, voce conseguiria detalhar um exemplo disso? Eu confesso que não consigo entender o porque de voce ter essa impressão. Você tem algo mais concreto pra exemplificar?
Y
YvGa
saoj:
Existe teste unitário com TDD e teste unitário sem TDD. Acho que o cara estava falando do último. Eu nunca experimentei fazer um sistema usando TDD, então não tenho como opinar. O ponto é que algumas pessoas usam os testes unitários para justificar a zona da arquitetura: “é uma zona mas eu consigo testar tudo de forma independente”. O pior é que muitas vezes eles nem sabem que está uma zona, pois nunca viram a coisa limpa. Acham que complexidade é um “efeito colateral inevitável” e que programação é coisa pra gente inteligente mesmo, logo se o cara não entende ou tem dificuldade é porque ele é burro. Faz o cara que fez a coisa se sentir “cool”. Taí a separação republicano x democrata na área de programação: simplicidade x complexidade.
Não estou falando que é o seu caso, Mario. Mas é o que eu já vi por aí.
Penso a mesma coisa, e existe sim esse negócio de ser cool porque fez uma coisa extremamente complexa.
Me dá arrepios quando ouço um programador dizendo: “Cara, eu sou foda.” Pode saber que ele fez uma gambiarra monstruosa.
saoj
YvGa:
Sergio, voce conseguiria detalhar um exemplo disso? Eu confesso que não consigo entender o porque de voce ter essa impressão. Você tem algo mais concreto pra exemplificar?
Eu trabalhei em dois lugares diferentes que faziam a mesma coisa e um era totalmente zoneado e o outro era a coisa mais bela e limpa que eu já vi. Não por coincidência o zoneado adorava teste unitário e o limpo ignorava os mesmos.
Agora eu realmente queria encontrar um exemplo open-source de arquitetura boneca russa. O cara só percebe a zona quando ele trabalha a fundo com o código fonte e começa a ver quão difícil é fazer as coisas ou entender o flow. Se um dia eu encontrar algo assim open-source eu te aviso. Com certeza deve ter…
javaflex
saoj:
YvGa:
Sergio, voce conseguiria detalhar um exemplo disso? Eu confesso que não consigo entender o porque de voce ter essa impressão. Você tem algo mais concreto pra exemplificar?
Eu trabalhei em dois lugares diferentes que faziam a mesma coisa e um era totalmente zoneado e o outro era a coisa mais bela e limpa que eu já vi. Não por coincidência o zoneado adorava teste unitário e o limpo ignorava os mesmos.
Agora eu realmente queria encontrar um exemplo open-source de arquitetura boneca russa. O cara só percebe a zona quando ele trabalha a fundo com o código fonte e começa a ver quão difícil é fazer as coisas ou entender o flow. Se um dia eu encontrar algo assim open-source eu te aviso. Com certeza deve ter…
Pois é, existem casos que não é necessário usar, senão vira burocrático, vai atrapalhar mais do que ajudar. O simples é genial.
gomesrod
Veeeelho… esse negócio de Síndrome de Diógenes em projetos de software merece um tópico próprio!
J
JoseIgnacio
O fato de começarem a falar de TDD quando o assunto é testes unitários mostra como o assunto é pouco entendido, até mesmo entre os entusiastas.
Y
YvGa
JoseIgnacio:
O fato de começarem a falar de TDD quando o assunto é testes unitários mostra como o assunto é pouco entendido, até mesmo entre os entusiastas.
Talvez voce esteja certo. Ou talvez nós entusiastas simplesmente não acreditemos na viabilidade de testes unitários depois do código já escrito. No outro tópico que eu indiquei ali há uma trecho de debate sobre isso. TDD vs testes unitários.
javaflex
TDD eu também não tenho muito o que opinar, só assisti palestras, achei interessante pelo menos na teoria, pela maior garantia das coisas, só não sei se na prática é divertido fazer, pois não gosto de nada chato. No momento só trabalho mesmo com teste após funcionalidade pronta, gerando automaticamente o cenário de testes/repositório fake com objetos instanciados a partir do banco de dados real, isso já elimina bastante trabalho burocrático no teste e só fica a parte de quebra da regra. Teste automatizado automático para preguiçosos igual eu. Se está errado ou fere etiquetas não sei, mas funciona pro caso.
bsl.lacerda
Pra mim quem não testa uma parte crítica do software seja com TDD ou não é por que não conhece a técnica.
Testes unitários são fundamentais para garantir que o seu código (de sua responsabilidade) funciona em determinado ponto do sistema, e vai continuar funcionando enquanto o teste EXISTIR e estiver passando.
É amigos, digo EXISTIR por que infelizmente já vi muita gente comentar teste que parou de passar depois que alguma alteração foi efetuada no código testado.
Sad but true…
ViniGodoy
bsl.lacerda:
Pra mim quem não testa uma parte crítica do software seja com TDD ou não é por que não conhece a técnica.
Testes unitários são fundamentais para garantir que o seu código (de sua responsabilidade) funciona em determinado ponto do sistema, e vai continuar funcionando enquanto o teste EXISTIR e estiver passando.
É amigos, digo EXISTIR por que infelizmente já vi muita gente comentar teste que parou de passar depois que alguma alteração foi efetuada no código testado.
Sad but true…
Por favor, evite ressuscitar tópicos sem um EXCELENTE motivo para isso. Por exemplo, dar a solução de um problema. Tópicos de opinião, como esse, raramente merecem ser ressuscitados - até porque, sua conclusão está próxima de muitas já emitidas aqui.