Cadê os testes?

90 respostas
H

Alguém poderia me informar onde ficam os testes unitários da classe java.util.ArrayList ?
Ou qualquer outra classe standard do java ?

Não sou contra testes unitários nem metodologias etc… mas pensei nisso agora e fiquei curioso.

O kernel do linux pelo visto não tem teste unitário como a maioria conhece, engraçado que está para nascer alguém que escreva um kernel do zero concordam ?

http://forums.pragprog.com/forums/123/topics/9588

Escrevo código com e sem teste. Entendo absolutamente as questões sobre refactor, bom design, manutenibilidade etc… quando usamos testes unitários, tdd etc? mas a questão religiosa estou fora.

Tem alguém que não usa projeto opensource/free sem testes unitários ? Caso sim, já parou para pensar sobre o editor de textos, a IDE, o framework, a linguagem, o compilador, o SO ?

Ou quem cria editor de texto, IDE, SO etc… é semi-deus e não precisa escrever teste unitário ?

Modo religião ON:
O comando “ls” para listar diretórios e arquivos é antigo pra caramba alguém sabe alguma notócia sobre o teste unitário dele ? Pode ser que liste um arquivo a mais ou a menos do que deveria !

Cadê o teste unitário do counter strike ? Se enviar um comando para lançar uma granada mas na verdade o sprite lança uma carteira de marlboro ? CS nunca mais ?

http://www.heliofrota.com/?p=109

90 Respostas

B

Que eu saiba eles usam um framework só pra isso, o jtreg (e não JUnit) para fazer os testes.

Para rodar os testes no OpenJDK siga esse roteiro:

http://hg.openjdk.java.net/jdk7/test/file/a4ecebcb77d9/README

H

Bacana o JDK (OpenJDK) tem, seguirei o passo a passo descrito no readme.

Não está claro sobre o teste da classe ArrayList mas tudo bem já ajudou bastante obrigado.

PS: Não tem nada haver com o assunto do JDK mas se você voltar um dígito na url olha o que acontece:

http://hg.openjdk.java.net/jdk7/test/file/a4ecebcb77d9/README

http://hg.openjdk.java.net/jdk6/test/file/a4ecebcb77d9/README

A problem occurred in a Python script. Here is the sequence of function calls leading up to the error, in the order they occurred.

/oj/hg/web/hgwebdir.cgi in ()

48

49 def make_web_app():

50     return hgwebdir(“hgweb.config”)

51

52 wsgicgi.launch(wsgiapplication(make_web_app))

wsgicgi = <proxied module ‘wsgicgi’>, wsgicgi.launch = <function launch at 0x8477b1c>, wsgiapplication = <class ‘hgweb.request.wsgiapplication’>, make_web_app = <function make_web_app at 0x8477c6c>

/oj/lib/hghost/hgweb/wsgicgi.py in launch(application=<hgweb.request.wsgiapplication object at 0x8476c2c>)

62         return write

Só para descontrair um pouco

H

Atitude simples:

Vou enviar um email hoje ou amanhã pro Richard Stallman, outro pro Linus Torvalds outro pro Patrick Volkerding perguntando se escrevem testes unitários.

Se algum deles responder eu vou pedir permissão para publicar aqui.

[editado]

Emails enviados, agora é esperar e torcer para que um mero mortal possa ser respondido.

[/editado]

H

Sr. Patrick Volkerding (O cara que criou e mantém o Slackware) respondeu meu email:

heliofrota :
I do not want to take your time, just ask if you usually write unit tests.

Patrick Volkerding:

heliofrota :
I’m not religious about TDD and i believe that free software can and should have credits without unit tests.

Patrick Volkerding:

Tem alguém que não usa framework porque não tem teste unitário, e está usando Slackware no momento ? (acredito que não, provavelmente usa windows 7 ou MacOX, no máximo rodou o live-cd do kurumim ou ubuntu)

Se alguem escrever uma distribuição brasileira derivada do Slackware com ou sem testes unitários, gostaria de participar do projeto para aprender mais.

S

Teste unitário é chato demais, pega poucos bugs e não garante qualidade/simplicidade do código. Teste funcional automatizado ainda vai. O melhor é o teste manual e a programação defensiva. Quando for alterar, use técnicas seguras e lógicamente corretas, ao invés de sair metendo a mão em tudo como um louco. Depois rode os seus programinhas e sistemas para ver se eles continuam funcionando. Os testes automatizados que faco geralmente vão dentro do main das minhas classes. Então eu posso re-executá-los quando quiser. Mas não fazem parte do meu sistema em si, ou seja, não precisam ser mantidos, refatorados, etc.

Na minha opinião, o mais importante de uma biblioteca / framework é se ele possui uma API simples de usar. Isso é qualidade. Caso contrário ninguém entende nada, nem mesmo o cara que fez.

O melhor teste automatizado para o seu sistema é o seu sistema. Pra isso que existe ambiente de testes. Se testes unitários fossem tão bons não precisaria de ambiente de testes. Altera, roda os testes e joga para produção.

D

saoj:
Teste unitário é chato demais, pega poucos bugs e não garante qualidade/simplicidade do código. Teste funcional automatizado ainda vai. O melhor é o teste manual e a programação defensiva. Quando for alterar, use técnicas seguras e lógicamente corretas, ao invés de sair metendo a mão em tudo como um louco. Depois rode os seus programinhas e sistemas para ver se eles continuam funcionando. Os testes automatizados que faco geralmente vão dentro do main das minhas classes. Então eu posso re-executá-los quando quiser. Mas não fazem parte do meu sistema em si, ou seja, não precisam ser mantidos, refatorados, etc.

Na minha opinião, o mais importante de uma biblioteca / framework é se ele possui uma API simples de usar. Isso é qualidade. Caso contrário ninguém entende nada, nem mesmo o cara que fez.


++
Concordo plenamente.
E há uma leva de “evangélicos” dos testes, que creem que qualquer coisa fora do mundo dos evangelhos dos testes é coisa do demônio.

G

Isso traduz bem o que penso: testes unitários onde eles são necessários.
Geralmente uso em rotinas que executam lógicas complexas ou razoavelmente complexas, mas sem essa obrigação de 100% de cobertura. Por exemplo, um determinado parâmetro não informado lança uma exceção. Não crio um teste para isso pois está bastante óbvio o comportamento do código.

Outros pontos que o pessoal às vezes faz malabarismos com mock apenas para conseguir cobertura de 100%: Actions/Controllers, Serviços que só delegam ao DAO.

H

Também penso dessa forma.

A

Nos meus últimos projetos, utilizamos TDD, e para mim a mudança foi excelente.

No meu caso, o que sinto após usarmos TDD é que aumenta e muito a confiança no seu sistema, por exemplo, ocorreu um bug, você identifica e cria um teste reproduzindo-o.

Assim, você pode ter certeza que esse bug não existirá mais em futuras modificações do código, pois cada vez que você modificar o código, poderá rodar o testee verificar que os bugs descobertos não voltam mais.

Então a equipe consegue evoluir o software, fazer grandes refactors, mudar implementações de módulos mantendo as mesmas interfaces e garantir que continue tudo ok.

Falo isso porque éramos uma equipe ágil, que mesmo quando o cliente não sabia exatamente o que queria, sempre implementávamos uma versão básica da funcionalidade, e conforme íamos discutindo a solução completa com o cliente, conseguíamos mudar o que já tínhamos feito sem muito esforço.

E testes unitários ajuda principalmente quando você vai dar manutenção em código que não escreveu.

Olhando o teste você consegue ter uma noção maior de como o pedaço de código interage com outros componentes.

S

Isso é legal, mas pensa comigo: Se vc corrigiu um bug e ele voltou isso muito provavelmente significa uma das opções abaixo:

  1. Código spagetti, sem divisão de responsabilidades, onde tudo depende de tudo.

  2. O cara que tá programando não sabe o que tá fazendo.

  3. Ambos

Minha opinião: se o código tá zoneado e spagetti não será o teste unitário que vai te salvar na hora de dar manutenção. Se o código tá direito e vc sabe o que tá fazendo então não precisa de testes unitários.

A

quando eu digo bug pode ser também requisitos que mudaram, e então você vai ter que modificar o que estava funcionando antes para funcionar da nova maneira. Isso é muito comum. Como você sabe que vai continuar tudo igual, sem efeitos colaterais no código que depende disso sem testes?

O Eclipse não vai indicar nenhum erro de compilação, mas como saber se a lógica dos componentes que dependem do que você mudou continua correta?

H

andreiribas o que você escreveu eu entendo, tanto que escrevi a frase acima.

O foco do pensamento é Não usar software que não tem teste unitário. “Você” usa software que não tem teste unitário ? Caso sim, não “você” não teria argumentos para degradar qualquer framework que não possui testes unitários estou certo ?

PS: Quando falo “Você” me refiro aos fanáticos por testes unitários e não você andreribas :slight_smile:

Se o cara reclamar que o neoframework (por exemplo) não tem teste unitário e está usando slackware linux, então esse cara está dando um “TIRO no pé” bem feio.

H

Resposta de Richard Stallman ao email que enviei:

Quem não sabe de quem estou me referindo procura isso no google : “The last true hacker”

T

Foi uma grande iniciativa mandar e-mail pra esses caras pra saber o que eles pensam :slight_smile: Mais legal ainda foi ver que eles responderam com suas opinioes.

Nao sou fanatico, mas passsei a trabalhar com TDD e BDD nos ultimos seis meses e tenho gostado muito. Antes nao tinha trabalhado nao porque nao gostava, mas sim porque nao tinha oportunidade.

Alguns pontos interessantes a observar, em minha opiniao:

  • TDD e testes unitarios nao sao a mesma coisa. TDD e mais uma tecnica de design, e a cobertura de testes adquirida com o seu uso e uma consequencia, e nao a motivacao.
  • Usando TDD voce tem menos chances de escrever codigo espagueti por dois motivos: 1) voce tende a separar as responsabilidades em diferentes classes e 2) o refactoring faz parte da metodologia. Ou seja, voce tende a escrever codigo menos acoplado e nao fica satisfeito com o primeiro resultado, voce o melhora.
  • Testes unitarios nao sao, e nem devem ser, a unica forma de garantir a qualidade do software. O teste unitario, quando existe, e bom para o desenvolvedor, mas ele por si so nao garante que todas as features serao entregues sem erros.

EDIT - nao, eu nao deixo de usar software so porque ele nao tem testes unitarios.

G

Eu falei aquilo lá em cima (sobre não usar tão rigidamente) mas confesso que gostaria de experimentar o TDD de verdade, já vi muito por aí gente dizendo que depois de experimentar não quer saber de outra coisa na vida

Li o livro (Kent Beck) mas quando tentei praticar tive uma dificuldade imensa com os “passos pequeninos”, ciclos curtíssimos onde cada etapa de codificação não pode levar mais de um minuto. Para mim essa é uma das mudanças de paradigma mais difíceis. E para vocês que usam TDD, foi tranquilo passar a pensar dessa forma?

S

Programação é uma arte. Um programa é como um livro: há infinitas maneiras de contar a mesma história.

Refatoração é fundamental para melhorar a coisa. Um sistema está sempre under construction e pode ser sempre melhorado, simplificado e arrumado.

Minha opinIão é que teste unitário funciona mais como atrito do que como incentivo. O fato de Java ser uma linguagem fortemente tipada com IDEs maduras que vão te ajudar e muito no refactory faz uma grande diferença para a necessidade ou não de testes unitários.

Se eu quiser fazer uma mudança mais radical, vou ter que mudar também todos os testes. Já paras as mudanças mais simples os testes vão testar as coisas óbvias que provavelmente vc não quebrou tendo em vista que vc entende bem lógica if-then-else-or-and-etc. Se você ainda não treinou o seu cérebro para ser bom com if-then-else-or-and-etc. então os testes serão sua muleta. Cada passo que vc der vc vai executá-los para saber se vc não quebrou aquele IF. Quanto mais vc programar, menos erros de IF você irá cometer, até chegar num ponto que vc vai estar seguro o bastante para modificar um IF sem testar. Nesse ponto os testes unitários serão apenas um pé-no-saco.

Minha opinião é que os testes unitários são um limitador da liberdade e da criatividade. É uma muleta que não ajuda muito e causa atrito desnecessário.

Agora TDD é outra coisa como o mestre Tarso falou. Cada um tem sua preferência para modelar. Pra mim a melhor maneira de planejar é executar. Sair programando, analisando e aperfeiçoando ao mesmo tempo. O teste se torna uma burocracia que reduz a dinâmica da coisa. Mas cada um com suas preferências. Apenas estou expondo minha preferencia e opinião sobre o assunto.

Agora com certeza: Teste unitário é a última coisa que vai determinar se um sistema está bom ou não. Ele é no máximo uma ajuda para o programador.

E ter que especificar todos os contratos, todos os IF-then-ELSE do meu sistema via testes unitários é coisa de maluco. Eu preciso de liberdade para programar sem ter que bater continência pros testes unitários a cada passo que dou.

Y

Ha algumas questoes a serem consideradas quanto a isso.

A resposta óbvia a sua pergunta implicita é: Sim, é possível fazer software sem TDD, muita gente já fez e muita gente continua fazendo software de qualidade sem essa tecnica.

Eu nao gosto de nada que seja imposto, nem de nada que não tenha sua eficacia comprovada, por isso eu entendo perfeitamente a irritação de voces contra os pregadores incondicionais da tecnica. Esses caras estao em toda parte, atacando todo mundo que nao pensa como eles. Seja la por que motivo for, qual tecnica, qual ferramenta, qual SO, qualquer coisa tem esses caras.

Se voce nao usa Mac voce nao eh feliz, se nao usa Linux voce eh burro, se nao usa Scrum esta fora do mercado, se nao usa TDD nao sabe desenvolver software.

Esses caras sao umas pragas que se espalham por todo o lado e na maioria das vezes nao sabem nem porque defendem as coisas que defendem.

Mas nao eh por isso que a tecnica é ruim, que nao te ajuda e que deve ser evitada.

Eu posso desenvolver software sem TDD? Logico que posso, mesmo hoje a maioria é desenvolvida assim. Mas por que? Sera que eu nao posso fazer uso de novas tecnicas pra me ajudar a desenvolver?
Sera que so por que tem um mala o tempo todo me enchendo o saco dizendo que TDD eh isso, isso e aquilo, que eu tenho que desconsiderar?

Eu uso TDD, e gosto bastante, ele me ajuda a entender código legado (quando eu jogo testes em pontos que vou ter que alterar) e me ajuda a definir a estrutura de novos
codigos. Ele, para mim, eh muito mais uma ferramenta de analise e desenvolvimento do que de teste. Mas nao eh uma tecnica facil, voce precisa de muita pratica pra que ele
seja produtivo. Depois ele eh absurdamente produtivo, mas nao sem estudo árduo. E esse é o ponto, o estudo árduo é em conceitos basicos OO, que muita gente acha que nao precisa e não necessariamente em TDD que todo mundo procura aprender.

Nao adianta nada voce mergulhar em toda a literatura de TDD sem antes entender os conceitos basico de programacao e de orientacao a objetos. Depois que voce tiver aprendido, pelo menos um pouco, a base da programacao, os principios de atribuicao de responsabilidades, alta coesao, baixo acoplamento, divisao em camadas logicas e etc e etc e etc, aí sim TDD pode te ajudar, mas se o cara nao sabe o basico nao adianta chorar, com testes ou sem testes o resultado eh o mesmo: codigo ruim.

O grande problema que eu tenho visto ultimamente, salvo excecoes, é que muita gente quer “se livrar” de TDD, não porque acha que nao precisa, porque é capaz de escrever
um código simples sem TDD. Mas por que TDD simplesmente é reflexo do seu código, se o teu codigo for simples, será facilmente testavel, se for complexo os testes ser
tornarao um inferno.

É como o saoj disse, voce nao tem que ficar esbarrando em burocracia de testes a cada vez que quiser fazer uma alteracao simples. Nesse passo voce pode optar por jogar
os testes fora, ou estudar TDD e aprender a escrever testes de uma forma que a “dor” da alteração no teste será tão pequena quanto a alteração da regra.

Essa eh uma coisa que eu sempre repito, se criar ou alterar um teste leva mais tempo do que criar ou alterar aquilo que ele esta testando, tem algo errado com a forma
que voce testa. Eu ja vi gente se enrolando no meio de mocks e stubs e coisas do genero, tentando fazer TDD e “fingindo” gostar dele, quando deveria rever
a forma de programar. O seu codigo tem que ser simples, os seus testes tambem. O uso excessivo de mocks eh um bom indicativo de que há algo errado com eles, ao menos
nos casos que tenho visto.

Eu concordo com saoj tambem quando ele diz que testes unitarios não são determinantes para a qualidade do sistema. Nao sao, nem de longe.

Mas para quem critica os testes, eu aconselho a se perguntar, se esta lutando contra TDD porque produz codigo ruim que dificulta o uso da tecnica, ou porque realmente
não precisa da tecnica?

E

Tenho uma observacao em relacao a testes unitários

Muitas vezes, por ser obrigado a fazer o teste, o programador cria um método qualquer joga uma anotation @Test e chama o método no qual deseja testar e se dá como satisfeito.
Em grande parte deles, nao testa nem 10% dos casos de testes possíveis e termina a tarefa com a sensacao de teste concluído e de sofware bom.

Acontece um caso muito parecido qd alguem coloca um comentário no código, q nao diz nada com nda, simplesmente para ter o gosto de falar q fez o javadoc ou o resolveu as críticas do checkstyle.

O q me preocupa em relacao ao TESTES é q muitas vezes se impõe a obrigacao de se criar 100% dos testes unitários, e isso algumas vezes acaba forcando a barra para a criacao de testes que nao fazem nada com nada. Tem empresa q obriga o programador a testar POJO, enfim, coisas do tipo…

Acredito q Testes Unitários são bons qd são usados verdadeiramente onde é necessário e nao simplesmente por leis, religioes ou caprichos…

Sobre o q o pessoal tava debatendo, nao deixaria de usar um software ou framework q nao tem teste. O q me diz se o software ou framework é bom ou nao, é a confianca q ele adquiriu. Na minha opnião confianca se conquista por diversos outros fatores, como por exemplo opnião dos usuários e resultado final em cima do problema q ele se propôs a resolver e diversos outros fatores.

H

Esse foi o segundo motivo real da discussão que iniciei, o primeiro foi realmente o questionamento a respeito de testes sobre a classe ArrayList e que propaguei em outras questões.

Eu penso que proibir publicação e divulgação de software livre em um fórum democrático e que apoia o opensource signifca postura ditatorial e apoio à software proprietário (não free software). Criticar iniciativas, mesmo sabendo que existem pessoas/profissionais neste mundo, que , muitas vezes fizeram-nos o favor de criar software para que possamos programar em linguagens de mais alto nível, e que tais pessoas/profissionais nem sequer se estressam com TDD, ou testes unitários.

A questão toda é que se “você” quer ser 100% radical e verdadeiro seja realmente 100%. Começe escrevendo o seu próprio sistema operacional com 100% de cobertura de testes ou mude sua postura e passe a aceitar que existem inúmeras pessoas/profissionais melhores do que você e softwares melhores do que o que você escreve/cria mesmo sem testes unitários.

É bem mais simples ser humilde do que ser “o foda”. Afinal, escrever código mais simples demonstra mais inteligência do que escrever código complexo, para atingir o mesmo objetivo.

Y

Confesso que não entendi muito bem o que você quis dizer com proibir a publicação e divulgação de software livre e nem como isso vem à discussão.

Quanto ao resto, vamos lá:

Eu acho que você tem todo o direito de escrever o seu software da forma como bem entende e não tenho o menor motivo para duvidar da sua capacidade técnica de construir um software sem testes, muito menos tenho a menor intenção de comprar uma briga homérica para mudar a sua opinião.

No entanto, há outras pessoas que leem esse fórum, que muitas vezes vêm até aqui em busca de esclarecimento às suas dúvidas ou de pessoas que passam ou passaram pelo mesmo problema que elas. E é direcionado a essas pessoas que farei esse post.

Pode ser que estes caras estejam lutando para aprender a escrever software melhor, e nessa luta estão esbarrando na dificuldade dos testes. Aí eles vem aqui e se deparam com um tópico desses e pronto. Logo percebem que eles estão certos e os testes errado. Mas pode não ser bem assim.

Vamos supor o seguinte trecho de código:

public void execute(int codigoDaBase, int codigoDaAltura){
  double base = dao.buscarBaseDoTrinagulo(codigoDaBase);
  double altura = dao.buscarAlturaDoTriangulo(codigoDaAltura);
  double area = (base * altura)/2;
  dao.salvarAreaDoTriangulo(area);
}

Claro que esse é um exemplo simples, onde a solução de refatoração é óbvia. Mas na realidade você vai se deparar com códigos muito piores que esse, com logicas bem mais complexas e bem mais difíceis de refatorar.

Mas num caso real, o desenvolvedor menos experiente, que leu aqui e ali sobre testes vai tentar testar o seu código. Vai ter que mockar a chamada da busca da base do triangulo, vai ter que mockar a busca da altura do triangulo, testar o cálculo da área, e mockar o método salvar.

Os testes nesse caso serão um inferno, e desnecessariamente, porque a intenção seria só testar o cálculo da área. Bastaria eu extraí-lo e testá-lo isoladamente. É um caso típico, entre muitos e muitos outros, de problema de design de código que dificulta a aplicação de testes unitários.

Aí o sujeito desavisado vem pro GUJ e dá de cara com um tópico como esses e pronto. Lá se foram os testes da vida dele e junto com eles uma boa oportunidade de aprender a escrever um código melhor.

Como eu disse, eu não quero convencer ninguém a mudar de idéia, nem dizer que quem não escreve software com testes não sabe o que está fazendo. Mas eu posso dividir facilmente minha carreira em antes e depois de aprender TDD. O índice de defeitos do que eu escrevia diminuiu absurdamente depois que eu passei a usar testes unitários e a facilidade de manutenção no que eu escrevo é muito maior hoje do que era antes.

Lógico que eu não sou perfeito e ainda tenho muito que melhorar, mas TDD pra mim foi a mais revolucionária ferramenta que eu experimentei. Foi o maior salto de qualidade que eu obtive. Então para mim ela teve a sua eficiência mais do que comprovada.

Se você não gosta, ou não quer usar a técnica é um direito seu, mas respeite-a porque ela será útil para muita gente.

E para quem lê e que concorda com o autor do tópico e deixo o conselho: antes de maldizer algo que vem crescendo bastante certifique-se de que o problema não está no seu código antes de simplesmente abandona-la.

Y

Só para complementar, eu não busco cobertura de 100%, não escrevo testes com mocks, só pra simular um if-else ou try-catch de falha de conexao.

Eu uso mocks, bastante, em códigos legado, onde mormalmente é bem mais fácil extrair interfaces e simular as diversas possibilidades que o código está tentando fazer do que tentar entendê-lo só olhando, ou, pior ainda, tentar executar em situação real.

Mocks pra mim são ferramentas de refactoring de código legado.

Eu uso TDD como um duto por onde a informação vai passar, nao importa de onde vem, nem pra onde vai, se de um xml ou de um banco de dados, o que me importa é que ao passar por meus objetos de negócio ela irá respeitar as regras que eu estipulei através dos testes.

Para isso eu preciso isolar a minha regra de qualquer forma de acesso a dados, arquivos externos, requests e responses e afins. Fazendo isso eu praticamente não preciso de mocks.

Essa é a minha realidade, dentro do tipo de software que eu desenvolvo, não sei se seria possivel abrir mão de mocks em outros tipos de produtos.

H

Se você tiver um tempo neste fim de semana dá uma lida neste tópico aqui de 2007, alguns exemplos, não irei citar os autores não estou preocupado com a vida de ninguém, apenas com as opiniões :

01:

Qual o problema de vários frameworks no planeta ? Se isso for problema deveria haver apenas um sistema operacional também, afinal é software.

02:

As coisas só funcionam se tiver javadoc e teste unitário ? Porque baixar o código do spring e olhar o javadoc deles ? Porque não olhar o javadoc da API do java ?

03:

Essa frase não necessita de comentários…

04:

Essa frase não necessita de comentários…ninguém é obrigado a usar JSF ou EJB 2.1 bem como usar o GUJ para divulgar alguma coisa, basta mudar de emprego ou se cadastrar em outro fórum.

05

Essa frase não necessita de comentários…

06, 07, 08 …vários outros comentários…

Se essa coisa toda é “opensource” porque ao invés de criticar não escrevem os benditos testes unitários para o projeto ?

Ou os que criticam nunca leram a respeito das 4 liberdades do opensource criadas pela FSF ?

Deixo claro que não faço parte do time do neoframework, mas algumas pessoas/profissionais divulgam algo para ajudar a comunidade de alguma forma e recebem críticas em vez de ajuda com codificação ou criação de testes ou incentivos.

Me responda se isso não é ridículo ?

H

Sei o que é um mock , mas hoje não consigo abrir mão do cigarro, já tentei parar de fumar mas ainda não consegui.

Y

Li o tópico, principalmente os mais “contundentes” e tive a seguinte impressão:

Embora muitos dos posts tenham de fato sido desnecessariamente desrespeitosos e mal-educados, outros com opiniões favoráveis a TDD e testes unitários em geral, são bem menos agressivos. A estes você escolheu simplesmente ignorar ou fingir que não existiram e concentrar-se naqueles mais “tensos” e respondê-los, como se respondendo a eles poderia provar a tese de que TDD é desnecessário.

Este seria muito mais útil para uma discussão se você respondesse do que os quais você quotou no seu post.

Um simples post do tópico que você indicou que sintetiza minha opinião:

Para quem não leu, considere ler o tópico que o helio indicou, é excelente, apesar de realmente haver algum excesso por parte de um ou outro defensor do TDD, principalmente no começo do tópico.

H

Teste unitário, TDD, Usar ou não IDE …

Isso não é BOM ou RUIM.

É disso que estou falando, concordo com o Sérgio programar para mim também é uma arte e deve ser feito com prazer e vontade e motivação, não com imposições do mercado.
Não sou um robô nem um número como diz o trecho da música do Iron Maiden “im not a number i’m a free man !”

T

heliofrota:
Teste unitário, TDD, Usar ou não IDE …

Isso não é BOM ou RUIM.

É disso que estou falando, concordo com o Sérgio programar para mim também é uma arte e deve ser feito com prazer e vontade e motivação, não com imposições do mercado.


E como foi que você conheceu Java? Por que você trabalha com Java?
Tudo o que conhecemos e/ou estudamos são, direta ou indiretamente, influenciados pelo mercado. Já trabalhei com Delphi, Java e Ruby, e aprendi essas três tecnologias por causa do mercado.

Só que aí entra o ponto onde concordo contigo: é uma decisão pessoal querer aprender ou não o que o mercado nos direciona a aprender.

Você, o Sérgio e outros demonstram um certo incômodo com o “estresse” que TDD traz, porque vocês se sentem um pouco obrigados a testar todos os aspectos do seu código. Mas aí que tá: quando usamos TDD, não precisamos testar um if-then-else, não precisamos nos preocupar com os detalhes da estrutura do código. Precisamos apenas testar o que ele faz.

Falando por mim, eu sinto o maior prazer em usar TDD. Programar os testes pra mim é tão viciante quanto programar o código em si. Particularmente, sou meio viciado em fazer o vermelho ficar verde hehehe. Mas para mim, o maior benefício que TDD traz não é sentido na hora que você cria o código, mas sim na hora que você precisa mantê-lo. Quando digo manter, me refiro a adicionar uma nova funcionalidade ou modificar uma que já existe. E se a gente for analisar o ciclo de vida de um software, a gente passa muuuuuito mais tempo modificando esse software do que o criando. Então TDD caiu muito bem pra mim nesse sentido.

Quando vejo alguém que não gosta de TDD, fico me perguntando que tipo de experiência traumática a pessoa teve para não gostar de TDD. No caso do Sérgio, eu sei o que houve porque já estava no fórum quando as pessoas jogaram pedra nele porque o Mentawai não tinha testes - e não concordo nem um pouco com esse apedrejamento. O Mentawai não deixou de ser um excelente framework só porque não tinha testes, e nem o Sérgio passou a ser um programador irresponsável só porque não usa TDD.

Mas se você tem essa resistência a TDD, convido você a insistir mais um pouco. Você não vai conhecer os benefícios do TDD se ficar com essa resistência, e nunca vai entender porque quem usa fala tão bem. Acredite, como profissional você só tem a ganhar.

H

Em 2000 estudando em casa.
Porque não nasci rico, e java não é apenas mercado. Quem me conhece falo que se ganhar na mega-sena vou tentar escrever jogos em java por diversão.

Isso faz parte do pensamento.

Como citei anteriormente: a questão aqui são as críticas destrutivas à softwares sem testes unitários, não à metodologia de TDD.

Você é livre para escolher o que gosta parabéns, ruim é querer que todos gostem a todo custo do que “você declara” concorda ? (não estou me referindo a você diretamente, nem à metodologia)

Sinto prazer em estar aqui no fluxbox customizado da maneira que eu quero, com a ultima versão do slackware linux 32bits da maneira que eu quero, e lendo a especificação da jvm, claro, apenas os capítulos que quero, enquanto paro por alguns minutos para lhe responder da maneira, que, obviamente quero.

T

heliofrota:
Em 2000 estudando em casa.
Porque não nasci rico, e java não é apenas mercado. Quem me conhece falo que se ganhar na mega-sena vou tentar escrever jogos em java por diversão.

Aí é que tá… Provavelmente não teríamos estudado Java se não fosse a influência de algo, e esse algo é o mercado em 99% das vezes. Por mais que tenhamos estudado em casa, sozinhos, devorando livros, por que fomos estudar Java e não outra coisa? Não dá pra negar a influência, direta ou indireta, do mercado em nossas decisões profissionais.

Isso realmente é um saco, e é lamentável que as pessoas julguem o profissionalismo dos outros pelo que o que ela deixa ou não de usar em seu trabalho.

P

unit test, tdd, bdd, caixa preta, branca, azul, rosa, etc. é tudo um conceito, gente. Quem aplica a técnica com autoridade sabe que a grande utilidade disso não é em apenas diminuir bugs ou melhorar o design, mas sim encorajar o programador a alterar/refatorar o código lá na frente, visto que o mesmo possui o “escudo” dos testes para evidenciar qualquer erro causado por determinada alteração. Testes = facilitar alterações. Como tu vai fazer isso? Não importa, desde que seja possível executar a bateria de testes de forma prática e evidente. Testar no main das classes e/ou testes de interface é muito instável. Então eu considero que pessoas que não escrevem testes para partes críticas do sistema ou não sabem ou são preguiçosos.

Minha opinião.

H

A sua opinião é completamente válida, porque é sua.

A minha opinião é que eu iria ficar puto se você escrevesse aqui informando que não usa software que não tem teste unitário vi que você usa o wordpress

Acessei o código fonte e não vi testes unitários do wordpress isso seria contradição sua, entendeu onde quero chegar ?

http://core.svn.wordpress.org/

Eu acho o wordpress uma excelente ferramenta, se não tiver nenhum teste unitário, continuo achando uma excelente ferramenta.

Este tópico é sobre abrir as mentes e formar opinião, não sobre denegrir testes unitários ou metodologias.

Ler a terceira frase que escrevi no post inicial :

S

gomesrod:
heliofrota:

Patrick Volkerding:


Isso traduz bem o que penso: testes unitários onde eles são necessários.
Geralmente uso em rotinas que executam lógicas complexas ou razoavelmente complexas, mas sem essa obrigação de 100% de cobertura. Por exemplo, um determinado parâmetro não informado lança uma exceção. Não crio um teste para isso pois está bastante óbvio o comportamento do código.

Outros pontos que o pessoal às vezes faz malabarismos com mock apenas para conseguir cobertura de 100%: Actions/Controllers, Serviços que só delegam ao DAO.

Gostaria de comentar algumas coisas aqui. Não realmente responder ao autor do trecho acima, mas tocar os pontos texto.

Primeiro ha que distinguir “teste” de "test-drive-developement’ (aka TDD) e “test-first”. Também destinguir “teste” de “experiencia”.
É muito comum ouvir a frase “teste de mesa”. Isto não existe. O que se quer dizer é “experiencia de mesa”. O programador após criar o código experimenta se ele funciona. E fica experimentando até que o código faz o que ele espera.
É certo que os programadores só fazem experiencia quando têm dúvidas se o código funciona. Ninguém experimenta 2+ 2 , mas provavelmente vão experimental BigDecimal.divide() porque tem 2 argumentos em vez de um, que seria o de esperar. E mesmo tem gente que usar o junit para criar experiencias mais complexas e avançadas. Mas são experiencias.

Teste é algo mais técnico. Primeiro ha que saber onde podem estar as falhas, criar cenários (passo-a-passo) para exercitar essas falhas. Os chamados “corner cases” são importantes. Incluir regras de qualidade (por exemplo, o método nunca deve retornar os parametros que recebeu, ou o método não deve aceitar nulo, o objeto é realmente imutável). Depois código é escrito para realizar estas verificações. A diferença é que um teste é criado sem saber nada sobre o código a ser testado e sim sobre a unidade sob test ( classe, sistema, etc). Apenas quem escreve o código do teste tem que se preocupar com isto.

Estes testes são raros a menos que haja investimento da instituição e das equipes.

Test-Fisrt é simplesmente a prática de criar o teste antes de programar a unidade (classe, sistema, etc…) a ser testada. Desta forma, apenas quando criarmos o código de teste iremos nos preocupar com a real interface da unidade, mas não para fazer a lista de coisas a testar.

TDD é abusar do conceito de Test-First para ajudar no desenvolvimento. Ou seja, o código do teste é utilizado para guiar como será a interface da unidade sob teste, quantos e quais outras unidades serão necessárias, como elas interagem etc… ou seja, é simplesmente modelar o código melhor usando o cheklist de testes para prover um melhor desing. Por exemplo, Testar um singleton é um parto, então, usando TDD irá criar um outro design mais simples de testar e que obtém os mesmos resultados.

Isto nada mais é que a velha prática de criar mais do que um cliente para o seu código. O código de teste que chama o seu business é tao importante quanto o código do action que chama o business. São ambos dois clientes válidos para o business.

Não confundir TDD com Test-First. O primeiro é um receiturário de processo de desenvolvimento (não de teste), o segundo é uma Diretiva de Desenvolvimento ( usada, por exemplo, no XP)

Só um ponto de ordem, todos os testes são unitários , o que muda é a unidade que pode ser um classe, uma instancia de uma classe, um conjunto de classes, um conjunto de instancias, um sistema completo, um conjunto de sistema. Nome variados são usados para agrupar as coias como teste de integração e coisas assim, mas quando se fala em “Unit Test” não se está falando em teste onde a unidade é o mais baixo possivel, e sim na metodologia geral de testes. “Unit test” significa teste no sentido que expliquei antes, para não confundir com “experiencia”.

Dado isto, a resposta do Pratick não é “Não quero saber de testes unitários” é “Eu escrevo testes, e ocasionalmente usando o principio do Test-First, mas não desenvolvo meu código usando os testes” ou seja, ele desenvolve o código como qualquer um faria, usando a experiencia, imaginação e um plano mental do que ha fazer e como, e depois escreve os testes do que realizou. E às vezes, ele escreve primeiro o teste - provavelmente para deixar bem claro para ele mesmo o que ha a ser feito e quais os riscos.

Em nenhum ponto ele escreveu “eu não escrevo testes” ou “só escrevo quando me apetece” ou “só escrevo quando acho que é necessário”.

É fácil mal-intepretar as respostas, mas o ponto é simples : Testes Unitários (os que não são experiencias) sim são importantes e vitais.

Ninguém disse que é fácil. Ninguém disse que é rápido. Mas todos concordam que é importante e vital.
Ok, não preciso criar o teste antes. É muito útil se fizer isso, mas isso não é tão importante. O importante é que o teste exista.

Por outro lado, quando se programa é muito simples criar estruturas que não são fáceis de testar. É para evitar isso que existe o TDD e o Test-First. Mas se você sá sabe criar bom código, que é simples de testar, vc simplesmente vai lá e escreve o código.
Se o código é bom, não importa realmente a ordem. Agora, se o código é ruim, ou o programador não sabe o que está fazendo, então sim, estes princípios são importantes até que o gramador ganhe uma maestria do design.

Por outro lado, os testes não são criados para ver se o código funciona. Isto é um pensamento errado. Não estamos querendo saber se sódio com cloro dá sal. Não é uma investigação. Não é um experimento. O que queremos com isto é ter um mecanismo automatizado que nos diga que o sistema ainda está funcionando. É esta segurança que procuramos e não se o sistema funciona. Porque é esta segurança que nos permitirá realizar modificações sem medo pois existe outra diretiva que diz “Não tenha medo de refactorar”. Vc pode ter medo que o seu codigo seja impossível, caro, ou lento de refactorar, ou que refactorando ele deixe de funcionar. Esses são medos válidos e são eliminados usando, por exemplo, testes automáticos. Ter medo que deixe de funcionar é normal, ficar paralizado por isso não é.

Cobertura de 100% é impossível. O normal é 30-50% e 70% é absurdamente bom. Mas claro, testar todos os get/set não conta nesta cobertura. Além disso testes são incrementais. Começa por testar o que você espera que possa dar errado. Depois, vc vai receber tikets com erros que mostra que alguns cenários vc não previu e vc adiciona mais testes e assim vai… ninguém testa tudo da primeira vez. Seria insano.

Criar testes é dificil, caro , demorado e muitas vezes mais dificil que criar o próprio sistema. Eu vivo isto todos os dias, não apenas no trabalho, mas no meu projeto pessoal que tem mais de 60 mil linhas de código e 1900 classes. Para tudo isto tenho 127 testes com 16% de cobertura - muito pouco. Mas não vale me enganar achando que o mais importantes é o código e que não preciso dos testes. É claro que preciso. Muitos refactorings são feitos na fé e isso não é bom. Não vale me enganar dizendo que se o Spring ou o JDK não têm testes eu também não preciso. Não vale tentar arranjar desculpas para não fazer os testes.

Então vamos parar com essa ideia que existe a mínima chance de não ter que escrever testes. Não ha!. Pode ser preguiçoso, pode ter falta de tempo, recursos e até de conhecimento de como fazer os testes, mas dizer que eles não são necessários é simplesmente burrice. É como dizer que o cinto de segurança não é necessário.

Eu já convivi com vários projetos que não têm testes automáticos. Ok, funciona. Até que descobrimos que não funciona. E quando descobrimos isso e precisamos refatorar - valha-nos Deus. E se queremos melhorar o sistema em algum ponto , logo alguém grita “Não! pode quebrar”. É claro que pode quebrar. A questão é se vamos saber. Se ha um mecanismo automático que testa o pontos vitais mais preocupantes e se esses continuam funcionando podemos dizer que o refactoring foi um sucesso. Mas e quando não temos os testes ? E pior, quando temos um código que é impossível testar ? Ai é pior ainda, porque para criar os testes teríamos que refatorar o sistema primeiro (!). O risco envolvido nisto é insano. E como disse Einstein, insanidade é repetir a mesma coisa e esperar resultados diferentes. Portanto, deixar o sistema sem testes e esperar que ele não vai dar problema é tão insano quanto criar um sistema impossível de testar.

Quanto a só usar sistemas com testes, o argumento é uma falácia logo no inicio. Os testes não são para proteger o cliente e o usuário, são proteger o investimento e a equipe de desenvolvimento. O cliente simplesmente mudar de sistema se ele dá problema ou processa a empresa por danos. Ou seja, é risco. Os testes servem para mitigar risco no desenvolvimento, não para salvar o usuário.

N

peerless:
unit test, tdd, bdd, caixa preta, branca, azul, rosa, etc. é tudo um conceito, gente. Quem aplica a técnica com autoridade sabe que a grande utilidade disso não é em apenas diminuir bugs ou melhorar o design, mas sim encorajar o programador a alterar/refatorar o código lá na frente, visto que o mesmo possui o “escudo” dos testes para evidenciar qualquer erro causado por determinada alteração. Testes = facilitar alterações. Como tu vai fazer isso? Não importa, desde que seja possível executar a bateria de testes de forma prática e evidente. Testar no main das classes e/ou testes de interface é muito instável. Então eu considero que pessoas que não escrevem testes para partes críticas do sistema ou não sabem ou são preguiçosos.

Minha opinião.

TDD é pouco eficaz para reduzir bugs e melhorar design, não é a toa que a proposição mudou para “facilitar a vida de quem precisa alterar o sistema no futuro e não é o autor original do software”.

Pelo menos agora é útil para empresas que não conseguem reter seus profissionais por muito tempo.

H

sergiotaborda

Acredito que sobre o tema de testes, unitários ou não, e TDD você foi o que trouxe mais enriquecimento à esta thread.

A discussão que iniciei aqui não é técnica, é social. Uma ironia a respeito de uso de software sem testes unitários. Mas que obviamente foram testados pelo programador por várias situações que você conseguiu traduzir em alguns parágrafos, quando citou sobre experimentos.

Acredito que ninguém tenha interpretado mal a resposta do Patrick, mas o fato de você traduzir para pt_BR foi uma iniciativa boa.

Eu não evangelizo ninguém, cada um tem o céu e o inferno que merece.

Sem escrever muito:

Você acha correto um programador criticar um projeto livre que não possui testes persistidos em meios magnéticos e/ou não possuem o formato mercadológico atual ?

É disso que estou falando quando criei essa thread.

H

tnaires

Não estudei por causa do mercado, um amigo que estava fazendo mestrado em IA estava tentando me ensinar complexidade algorítmica, digo tentando por 2 motivos: o primeiro que eu até então não havia colocado os pés na faculdade e o segundo que ele estava estudando para uma prova e aquilo , segundo ele, o ajudaria a passar na prova.

Depois em 2001 foi que comecei a entender o mercado e o que a plataforma java representava neste meio.

Mas acredito que você tenha uma % boa de razão, o capitão crunch só estudou telefonia a fundo depois que viu o mercado de telefonia aflorar e imaginou N possibilidades…

S

heliofrota:

Sem escrever muito:

Você acha correto um programador criticar um projeto livre que não possui testes persistidos em meios magnéticos e/ou não possuem o formato mercadológico atual ?

É disso que estou falando quando criei essa thread.

Sim. Acho correto que o projeto seja criticado por falta de testes codificados que possam ser executados e adicionados. E entenda que tenho um projeto destes que, como disse tem poucos testes.
O mesmo vale para projetos não-livres.

O ponto é que em projetos livres você perde o direito de criticar a partir do momento a que se recusa a ajudar.
Se estava ruim não é culpa sua. Se continua ruim, a culpa é sua.( regra do bom escuteiro) Porque não participou e ajudou. Se a culpa é sua não adianta criticar. Tem que ajudar. Não quer ajudar ? Então não reclame.

Eu nunca criticaria os projetos linux, ou o jdk ou qq projeto livre por falta de testes porque eu não faço a mínima ideia de como ajudar.

È diferente para projetos fechados. Que como falei antes o problema está no risco. Tem também a ver com a vida util. Se vcvai jogar o software fora em um ano, não adianta muito criar um super esquema de teste, mas se vc comanda um produto que irá viver 10 anos ou mais ( como o linux ou o jdk , etc…) é bom para si que tenha os testes. O Cliente simplesmente pode usar outro produto.

Y

Ah, as maximas!!! As maximas!!!

TDD é muito eficaz para reduzir bugs e melhorar design. Ele, bem aplicado, reduz a quantidade de bugs de um sistema porque cria uma bateria de testes automaticos que validam se todo o seu sistema continua funcionando da forma como voce espera. E TDD, melhora muito o design, porque voce nao consegue testar um design ruim.

Acho que esse nem eh o ponto da discussao. O que o Helio reclama, e eu tenho que dar razao a ele, é do fato de quererem tornar TDD obrigatório e dizerem que quem não faz não sabe programar.

E, para concluir, gostaria de saber qual autor assumiu pra si a responsabilidade de alterar a proposição da forma como você sugeriu. Para mim ela nunca foi alterada.

Quando for emitir a sua opinião, procure sempre deixar claro que ela é a sua opinião, pois muita gente que está começando costuma ler este fórum e tais afirmações podem confundi-las.

Ao invés de dizer “TDD é pouco eficaz para reduzir bugs e melhorar design”, diga "eu acho TDD pouco eficaz… " e de preferência explique porque.

Acho que até pode criticar, mesmo projetos livres, desde que faça com respeito.

O grande problema está em ridicularizar o trabalho dos outros, principalmente trabalho que é feito de forma voluntária e que não espera compensação financeira.

P

heliofrota:
A sua opinião é completamente válida, porque é sua.

A minha opinião é que eu iria ficar puto se você escrevesse aqui informando que não usa software que não tem teste unitário vi que você usa o wordpress

Acessei o código fonte e não vi testes unitários do wordpress isso seria contradição sua, entendeu onde quero chegar ?

http://core.svn.wordpress.org/

Eu acho o wordpress uma excelente ferramenta, se não tiver nenhum teste unitário, continuo achando uma excelente ferramenta.

Este tópico é sobre abrir as mentes e formar opinião, não sobre denegrir testes unitários ou metodologias.

Ler a terceira frase que escrevi no post inicial :

Sim, eu entendi seu ponto. Uma coisa é o software que eu uso, a outra é o software que eu construo para os outros usarem. Uma coisa é um erro no wordpress a outra é no sistema de folha de pagamentos da empresa que eu trabalho, e por ai vai. Certamente não seria um lunático para verificar se o que eu uso possui testes (salvo algumas excecoes, como frameworks e outras ferramentas de trabalho open-source que precisam ser alteradas), no mais… são contextos completamente diferentes.

Outra questão… em nenhum momento eu disse que teste é requisito primário para se construir software - pessoas que preferem assim, o fazem - sem problemas. Acho que em nenhum lugar está escrito isso. A questão é: com suites de testes o desenvolvimento torna-se mais confiavel, visto que tu tem evidencias para capturar rapidamente erros incluidos devido a alteracoes - eu prefiro não arriscar - não confiar - e ter certeza que um problema incluido por qualquer um do time possa quebrar o build o quanto antes, ponto. Posso estar viajando, mas isso aqui parece com um projeto de testes do wordpress, isso aqui uma iniciativa de testes automatizados para o kernel do linux, e por ai vai.

Conclusão: cada um faz software como acha melhor, o resultado (o software) é uma coisa, pode ser entregue sem testes (que é o caso dos softwares proprietários, onde tu nao tem nem acesso a fontes). Eu uso testes para me proteger, é uma técnica. Testes lhe fornecem uma metodologia mais séria e barata para desenvolvimento comunitário (caso dos projetos open-source).

P

NickGaspar:
peerless:
unit test, tdd, bdd, caixa preta, branca, azul, rosa, etc. é tudo um conceito, gente. Quem aplica a técnica com autoridade sabe que a grande utilidade disso não é em apenas diminuir bugs ou melhorar o design, mas sim encorajar o programador a alterar/refatorar o código lá na frente, visto que o mesmo possui o “escudo” dos testes para evidenciar qualquer erro causado por determinada alteração. Testes = facilitar alterações. Como tu vai fazer isso? Não importa, desde que seja possível executar a bateria de testes de forma prática e evidente. Testar no main das classes e/ou testes de interface é muito instável. Então eu considero que pessoas que não escrevem testes para partes críticas do sistema ou não sabem ou são preguiçosos.

Minha opinião.

TDD é pouco eficaz para reduzir bugs e melhorar design, não é a toa que a proposição mudou para “facilitar a vida de quem precisa alterar o sistema no futuro e não é o autor original do software”.

Pelo menos agora é útil para empresas que não conseguem reter seus profissionais por muito tempo.

Fonte disso?

Pessoas chamam o que quiserem de TDD. É necessário uma boa experiencia para aplicar TDD na medida exata a qual ele lhe dará o seu melhor benefício: design. Analogicamente a construcao com TDD seria assim:

Problema: colocar um tijolo dentro de um copo

com TDD: existe o tijolo, constrói-se o copo já com o tijolo dentro.
sem TDD: existe o copo, adapta-se o tijolo para caber dentro.

H

YvGa

Só um alinhamento: Eu não reclamo do mercado exigir TDD, já usei essa metodologia. No atual emprego não uso, não preciso mentir, se a situação ou a liberação dos releases se modificar
de alguma forma, pode ser que use TDD ou simplesmente adicione uma cobertura ou não faça nada disso.

Em casa codificando algumas coisas , hora uso TDD hora não uso.

Usei mais TDD no emprego anterior do que no atual (a mais ou menos 2 anos atrás)

Agora a parte que você falou sobre “Quem não utiliza esta metodologia não sabe programar” sou realmente contra, assim como vários são.

Tem profissionais excelentes aqui no GUJ que provavelmente aprenderam essa metodologia uns 3 anos pra cá, e começaram a trabalhar a uns 15 anos atrás por exemplo, logo esses caras só aprenderam a programar os 3 últimos anos ? Os 12 foram para o lixo ? Isso seria ridículo, é um rótulo apenas.

H

Chegamos ao núcleo da discussão:

Quem critica negativamente vai escrever assim agora ?

Ou

No minimo ridiculo não ?

É bom saber que tem testes de alguma forma, agora o cara criticar de forma negativa quando o projeto não tem pega mal pra ele mesmo (na minha opinião).

S

Tenho andado afastado do guj por muito bom tempo e não sei se você se está referindo a outra thread, mas na real alguém criticar um projeto porque não usa TDD ? Ou você quer dizer “Criticar porque não usar Test-first” ?
Ou criticar porque “não usa teste” ? É que não é tudo a mesma coisa. Ha uma escala aqui. Teste é obrigatório, TDD é mais do que opcional. Test-First está no meio.

De onde vem este sentimento que se criticam projetos por falta de testes ?

H

Entendi sua filosofia, e sei que você é um bom “entendedor”, para deixar mais claro ou mais confuso vamos falar sobre arquivos de testes salvos em meio magnético de preferência utilizando um framework conhecido de mercado/comunidade.

Porque do contrário do óbvio, não existe código sem teste (experimento), no mínimo testou-se na mente na menor unidade possível. Por exemplo, alguém pede para fazer uma consulta em um banco
de dados, a consulta sql é construida e, no momento da execução em um cliente qualquer, foi efetuado um experimento ou teste, nota-se que faltam campos , melhora-se a consulta e o software
"o comando SQL" está pronto. (SQL é uma linguagem)

Não existe verdade absoluta o que existe é a verdade de cada um.

Agora respondendo a sua pergunta, não estou com sentimento de nada sobre ninguém, apenas iniciei uma discussão para ver o que os demais membros pensam a respeito de crítica negativa em projetos
que não possuem testes no formato supracitado.

E se por acaso lhe interessar, não foi algo proposital posso falar abertamente aqui o que aconteceu, sexta-feira busquei no gogole por “combo Reload Group” cai em uma thread sobre o neoframework
e comecei a filosofar se o linux que eu estava utilizando naquele momento possuia ou não testes unitários, se o JDK possuia, se a classe ArrayList possuia testes etc etc

Acredito que o resultado foi bom , nunca havia enviado email para Richard Stallman, para Patrick do slackware, ou o criador do kernel que no caso não respondeu mas tudo bem. Foi uma discussão bacana não houve baixaria.

Pergunta respondida ?

[editado]
Procure pelo mentawai ou menta beans, irá encontrar muita coisa sobre criticas negativas pelo fato do projeto naquele momento não possuir testes no formato citado anteriormente.
[/editado]

T

Isso aí eu acho também que foi um dos grandes lances dessa thread :smiley:

T

Uma pena, porque você sempre tem muito a adicionar com suas contribuições. Bem vindo de volta.

H

tnaires

Já que você achou legal esse feedback, vou te repassar o outro email que ele me mandou, para você ver o que é atitude humilde

  1. Perguntei sobre os testes

  2. Ele respondeu “Não tenho opinião sobre isso , desculpe”

  3. Mandei outro email (no outro dia) dizendo: “Você não precisa se desculpar, você é o Dr. Richard Stallman, o mestre”

4) Ele respondeu: “Por favor não me chame de mestre, mestre significa alguém que comanda um escravo. Você merece a liberdade e liberdade significa não possuir mestre”

Sou fã do cara, não nego. Tirei screenshot desse e do outro email, tem gente que é fã de banda de pagode, de time de futebol enfim…

Y

Dois parágrafos em particular do que você escreveu que eu gostaria de comentar.

Cobertura de 100% eu acho impossível tambem, mas o fato de estar 70% por si só não é necessariamente bom. Nesse ponto eu tenho que concordar com o saoj, se eu tenho testes apenas pela obrigação de tê-los, e ainda que eu os tenha cobrindo os pontos mais importantes da aplicação, ainda assim pode não ser bom.

Para exemplificar vamos ao segundo parágrafo, supondo que voce esteja falando de testes automatizados quando diz que criá-los é difícil e caro.

Difícil? Não sei se são, difícil sim é aprender as técnicas a tal ponto que escrevê-los seja fácil.

Caro é que é a questão: Segundo os princípios Lean, qualquer coisa que não adicione valor a um produto é desperdício. Sob este ponto de vista, testes, como um todo, são desperdício. O usuário não se importa com testes, como foi testado, ou sequer se foi testado, o que ele importa pra ele é que as funcionalidades que ele precisa estejam lá e funcionando.
Se você tem um programador que consegue, o que acho pouco provável, escrever código sem falhas já na primeira vez que codifica então você está num cenário ideal. Você pode simplesmente desenvolver o que o cliente precisa e pôr em produção, sem testes, sem perda de tempo, sem desperdício. E ainda assim o cliente estará satisfeito.

O problema é que isso beira ao impossível e antes de por algo em produção você precisa garantir que funciona para evitar o desgaste de ser avisado pelo usuário que algum ponto crucial parou de funcionar. E nesse ponto entram os testes com todos os custos que vêm com eles.

Aqui você vai precisar pesar o que é mais barato quando comparado ao resultado. Se você não tem uma equipe experiente em testes automatizados e tem um sistema que não é crítico a ponto de alguns simples testes funcionais nos caminhos principais do aplicativo serem suficientes para evitar problemas com o usuário. Ótimo, faça isso.

Mas esse também é um cenário excepcional. Embora, a grande maioria dos sistemas de médio e grande porte que eu vi, ou ouvi falar, não tenham rotinas de testes automatizados eles deveriam ter. E o fato de não os terem os torna mais caro do que se tivessem. Logo, nesses casos, testes automatizados são mais baratos.

Eu trabalho num sistema que se utiliza de diversas fórmulas de cálculo de valores, fórmulas que no geral são parecidas entre si, mas que possuem particularidades para cada cliente que as utiliza. Eu tenho que constantemente combinar as partes comuns com as particulares. Considerando que são mais de 80 clientes você pode imaginar o custo de garantir que tudo está funcionando apenas “executando o sistema”. É impossível.

Nesse caso, e em muitos outros, testes automáticos são mais baratos, inclusive do ponto de vista do programador. Se eu alterei uma linha de código eu posso rodar uma bateria de até milhares de testes em menos tempo do que eu vou levar para subir o servidor de aplicação. Lógico que cedo ou tarde eu vou subir o servidor e rodar a aplicação, mas não para cada linha que eu alterei, luxo a que posso me dar com testes automáticos.

Ainda falando em custo, mas voltando ao ponto dos “ideais” 70%. Mesmo que eu os tenha, e ainda que eles cubram as partes mais importantes da minha aplicação, mesmo assim o desperdício e o transtorno que eles me causam podem ser bem maiores do que simplesmente alterar e depois testar manualmente a aplicação. Códigos de testes mal feitos são infernais, ter que gastar mais tempos alterando código de teste do que alterando código real é de deixar qualquer um louco. Se a cada a vez que você altera um if dezenas ou centenas de testes se quebram você, com certeza, está investindo em algo que não se paga. Ainda que uma ferramenta de cobertura te diga que 70% de código estácoberto.

E o mais grave com testes mal feitos é que cedo ou tarde, e normalmente cedo, eles vão ser abandonados. Aí sim o desperdício se completa, porque TUDO o que você gastou com eles foi pro lixo.

Isso aí eu acho também que foi um dos grandes lances dessa thread :D

Achei muito legal também esse negócio de mandar email pros caras.

Mas voltando (ou insistindo ainda nela) à obrigatoriedade do uso de TDD, veja que os exemplos que o Helio citou são exceções. A regra histórica de desenvolvimento de software é a falha. Desde um número absurdo, inaceitável até, de cancelamento de projetos, até atrasos, entrega de funcionalidades meia boca, mal implementadas, aplicações bugadas e coisas do gênero. Essa é a regra da qualidade do software hoje.

Eu dei uma procurada básica sem perder muito tempo e achei num post sobre gerenciamento de projetos alguns números. Segundo o Standish Group em 2003 o número de projetos de software concluído com sucesso foi de 28% (impressionante!!!), enquanto projetos na área de engenharia, segundo Why Software Projects Fail, os projetos concluídos com sucesso estão na casa dos 94%. Sendo que concluído com sucesso quer dizer, entregue no custo e prazo determinados. http://www.fernandoamaral.com.br/Default.aspx?Artigo=52

Não investiguei a veracidade desses números, nem em que contexto se aplicam, por tanto podem estar distorcidos. Embora eu tenha estranhado os 94%, achando alto demais, todos nós sabemos que o número de falhas em projetos de software é extremamente alto.

Por isso eu acho “perigoso” tentar provar uma tese de que algumas técnicas recentes, que se propõem a preencher lacunas há muito abertas na codificação de software são desnecessárias e fazer isso se utilizando de exceções à regra de que projetos de software tradicionais costumam falhar.

Eu não tenho números, nem sei se alguém os tem (embora muitos clamem ter achado o santo graal do desenvolvimento de software), sobre como TDD e testes automáticos como um todo melhoraram o desenvolvimento de software. Eu posso responder por mim e para mim ele é um divisor de águas.

E não estou sozinho nessa opinião, há algum tempo assisti a uma palestra do Robert C. Martin em que ele diz acreditar que TDD se tornará parte integrante do processo de desenvolvimento de software no futuro. Ele compara TDD ao fim do goto, pensado impossível a princípio escrever código sem goto, hoje ele é praticamente ignorado.

Michael C. Feathers, autor de um dos mais extraordinários livros sobre desenvolvimento de software que li (Working Effectively with Legacy Code), considera código legado todo código que não possui testes unitários automatizados.

Só para citar alguns dos grandes autores que defendem a prática de escrever testes antes do código, de ter um sistema cuja consistência possa ser verificada sempre que necessário.

S

YvGa:
sergiotaborda:

Cobertura de 100% é impossível. O normal é 30-50% e 70% é absurdamente bom. Mas claro, testar todos os get/set não conta nesta cobertura. Além disso testes são incrementais. Começa por testar o que você espera que possa dar errado. Depois, vc vai receber tikets com erros que mostra que alguns cenários vc não previu e vc adiciona mais testes e assim vai… ninguém testa tudo da primeira vez. Seria insano.

Criar testes é dificil, caro , demorado e muitas vezes mais dificil que criar o próprio sistema. Eu vivo isto todos os dias, não apenas no trabalho, mas no meu projeto pessoal que tem mais de 60 mil linhas de código e 1900 classes. Para tudo isto tenho 127 testes com 16% de cobertura - muito pouco. Mas não vale me enganar achando que o mais importantes é o código e que não preciso dos testes. É claro que preciso. Muitos refactorings são feitos na fé e isso não é bom. Não vale me enganar dizendo que se o Spring ou o JDK não têm testes eu também não preciso. Não vale tentar arranjar desculpas para não fazer os testes.

Dois parágrafos em particular do que você escreveu que eu gostaria de comentar.

Cobertura de 100% eu acho impossível tambem, mas o fato de estar 70% por si só não é necessariamente bom. Nesse ponto eu tenho que concordar com o saoj, se eu tenho testes apenas pela obrigação de tê-los, e ainda que eu os tenha cobrindo os pontos mais importantes da aplicação, ainda assim pode não ser bom.

Para exemplificar vamos ao segundo parágrafo, supondo que voce esteja falando de testes automatizados quando diz que criá-los é difícil e caro.

Difícil? Não sei se são, difícil sim é aprender as técnicas a tal ponto que escrevê-los seja fácil.

Quando eu disse 70% de cobertura, me refiro a caso de teste automáticos que cubram 70% da funcionalidade e não a 70% do código ser executado.
Ha essa ideia - errada quanto a mim - de ferramentas como o Cobertura que medem as linhas que são executadas durante um junit da vida. Isso não é cobertura de verdade, é enganação. Como vc disse, e bem, ha muitas coisas a considerar mais importantes que isso.

Este é um outro pré-conceito errado (missconception). Valor do produto existe para os stakeholders, o cliente é apenas um desses stakeholders. A empresa é outro. Aceitando que os testes não elevam o valor para o cliente ( o que poderíamos argumentar que não é verdade) eles elevam para a empresa. Diminui risco, diminui impacto, diminui surpresas , melhora o design, melhora o entendimento , melhora a documentação que código é por si mesmo.

Testes nunca são um desperdício. Mas claro, estou falando de testes como deve ser, não experiencias ou junits aqui e ali sem nexo nenhum. Como vc falou, criar um arcabouço de testes (test harness) não é trivial. Poderemos criar um junit que testa todos os get/set da vida e tem cobertura de execução de código de 100% mesmo assim é um lixo e não serve para nada. A discussão parte do principio que estamos falando de testes verdadeiros, em feitos e bem pensados.

Sim. Esse é o ponto.
Ha o custo de montagem do teste. Ou seja, pessoas trabalhando para criar e manter código que testa outro código. Isto como vc falou exige pessoas especializadas e como tal é caro. Mas caro aqui em termos de muito dinheiro não em termos de custo/beneficio. Este dinheiro é um investimento. Quando vc paga a alguém para testar manualmente o custo é o mesmo (pode ser o mesmo) mas é uma despesa, não um investimento.

O importante, como vc e mais alguém já disseram ai, é entender que o test harness é um colchão que protege o projeto, o produto , o investimento. E é por isso que ele é importante e é por isso que todos os desenvolvedores deveriam pressionar para ter um. Não ter um é como aceitar deixar viajar seus filhos sem cinto de segurança ou não passar alcool antes e depois da vacina. Vc pode viver sem isso, mas o risco é maior.

O TDD em si é uma moda, mas o Test-First e o Test Harness não são. Isto deve ser claro na mente de todos.

N

Se Donald Knuth, Joe Armstrong e Ken Thopnsom, pra citar alguns, encontraram o santo graal eu não sei, mas o que eles falam, eu seria um trouxa se não escutasse.

Por outro lado, pra cada um que diz ter achado o santo graal do desenvolvimento de software, existe 10 blogueiros e autores de livros que só sabem falar sobre como programar OO usando TDD, mas não fazer.

Bom, pelo menos eles não ficaram conhecidos pelo software que criaram.

Agora, não me leve a mal, até gosto do trabalho do Bob Martin, mas não vamos confundir evangelizadores de testes com os verdadeiros mestres da arte!

Y

NickGaspar:
YvGa:

embora muitos clamem ter achado o santo graal do desenvolvimento de software

Se Donald Knuth, Joe Armstrong e Ken Thopnsom, pra citar alguns, encontraram o santo graal eu não sei, mas o que eles falam, eu seria um trouxa se não escutasse.

Por outro lado, pra cada um que diz ter achado o santo graal do desenvolvimento de software, existe 10 blogueiros e autores de livros que só sabem falar sobre como programar OO usando TDD, mas não fazer.

Bom, pelo menos eles não ficaram conhecidos pelo software que criaram.

Agora, não me leve a mal, até gosto do trabalho do Bob Martin, mas não vamos confundir evangelizadores de testes com os verdadeiros mestres da arte!

Como eu disse no meu post anterior, não devemos usar da exceção para tentar provar a regra.

Eu não sou um grande mestre, eu não tenho toda a bagagem e nem todas as qualificações que eles têm para simplesmente ignorar o que aqueles como eu dizem.

Repetindo Keith Braithwaite:

Se dez blogueiros e alguns autores me dizem que teste unitário é bom (e eu comprovei por conta própria que para mim é), mas alguns dos mestres dizem que para eles é perda de tempo em quem eu devo acreditar?

Lógico que nos blogueiros e autores, pois eles estão bem mais próximos da minha realidade do que esses caras. Eu não sou um gênio, nem nunca vou me tornar, eu sou apenas alguem que recebe um pouco de dinheiro para entregar bom software para o meu cliente. Mais ou menos como os blogueiros que dizem que testes unitários são importantes, com mais ou menos os mesmos problemas e as mesmas dificuldades. Se funcionou para eles, é bem possível que funcione para mim. O que funcionou para Donald Knuth, pouco provavelmente funcionará para mim.

Se você está entre os gênios que pode simplesmente ignorar o benefício que esta técnica tem trazido, ótimo para você. Mas esse não é o meu caso, não é o nosso caso, o da maioria dos programadores.

E só para garantir que ninguém se esqueceu. Ainda hoje, a falha é a regra em projetos de software.

S

Uma curiosidade, YvGa.

Quando vc está programando vc introduz muitos bugs que os testes unitários vão pegar pra vc?

Ou quando o Junit fica vermelhinho não é um bug mas sim os contratos que mudaram e agora vc tem que atualizar os seus testes unitários?

Se os testes unitários estão pegando vários bugs que vc está introduzindo no seu código, então eles realmente são essenciais.

No meu emprego atual tem teste unistário pra kacete. Mas nas raras vezes que ele fica vermelho não é bug não. É contrato que foi modificado, apenas isso.

PS: Eu não sou gênio e não uso teste unitário. Estou mais para compulsivo. Genealidade está mais para matemática e física, do que para lógica. :slight_smile: Para esses vc realmente precisa de um pode de processamento cerebral elevado.

H

Hail ! Isso é que é discussão !

Mais um objetivo atingido sobre abrir mentes nesta thread ! Alguém precisa pegar pontos relevantes e postar em algum lugar.

sergiotaborda:

Comentários sensatos.

YvGa:

Não há nada melhor do que a realidade e eu à admiro na maioria dos meus devaneios.

A vida real é assim mesmo, tem um diretor querendo um software pra agora e nem quer saber se você é júnior, sênior, se agrega valor ou não à empresa dele, mas se você não entrega a parada “Rodando”, você perde o emprego que você gosta. Isso é bem real, gostei da exposição do seu comentário, vários passam por isso. Ainda digo mais, tem um monte de gênio do passado ou atuais, que lidam apenas com uma linguagem, é sério, não sabem desenrolar html, nem se preocupam com o xmlhttprequest 2, com desenvolvimento mobile nativo, híbrido ou usando html5 + css3 +js, nem relatórios chatos, etc etc etc, performance, segurança etc…

Embora não sejam obrigados a saberem para serem chamados ou não de gênios.

saoj :

O saoj é um caso a parte. Só quem já teve oportunidade de trocar umas ideias real-time, gtalk ou seja lá o que for, para presenciar resultados de coisas complexas resolvidas em pouco tempo. Meu pensamento no geral é parecido com o dele, não sou foda como o cara mas sou compulsivo.
Essa semana irão entrar 2 em produção um java swing puro feito todo na mão por que não sei usar o netbeans ainda e não gosto do código gerado por ele e outro que não vou citar detalhes, nenhum desses tem teste unitário, foi testado claro, mas bateria de teste com junit. Se tivesse seria bom mesmo é verdade, mas não tem e vai gerar lucro para a empresa. No geral eu acho que é importante saber fazer testes, com ou sem junit não precisa ser com o junit também, contanto que a funcionalidade atenda as espectativas, se não tiver teste no formato fomentado ou mercadológico ou seja lá o que for eu programo também do mesmo jeito.

Y

saoj:
Uma curiosidade, YvGa.

Quando vc está programando vc introduz muitos bugs que os testes unitários vão pegar pra vc?

Ou quando o Junit fica vermelhinho não é um bug mas sim os contratos que mudaram e agora vc tem que atualizar os seus testes unitários?

Se os testes unitários estão pegando vários bugs que vc está introduzindo no seu código, então eles realmente são essenciais.

No meu emprego atual tem teste unistário pra kacete. Mas nas raras vezes que ele fica vermelho não é bug não. É contrato que foi modificado, apenas isso.

PS: Eu não sou gênio e não uso teste unitário. Estou mais para compulsivo. Genealidade está mais para matemática e física, do que para lógica. :slight_smile: Para esses vc realmente precisa de um pode de processamento cerebral elevado.

Certo, saoj, vamos lá.

Eu não ignoro o fato de que para se ter testes é preciso cuidar deles, e cuidar deles tem um custo. Se eu passei uma impressão diferente, o que não acho, me desculpem, mas nem de longe foi a minha intenção. A tecla que eu continuo batendo é a de diminuir ao máximo o custo deles para que eles se paguem, para que tê-los valha a pena. Como eu já disse, várias vezes, eu acho que não se deve (não se pode, talvez fosse melhor) gastar mais tempo trabalhando com testes do que trabalhando com o código testado.

Não, normalmente não, embora eventualmente aconteça.

Sim, geralmente as alterações são por conta dos contratos que mudaram e eu tenho que atualizar meus testes unitários. E é a partir deste ponto exato que nossas opiniões começam a divergir. E a partir deste ponto que nós, nos nossos estudos, carreira, teorias e seja lá mais o que for, seguimos caminhos diferentes. Neste ponto tanto eu como você achamos que ter testes unitários “protegendo” a aplicação estava ficando custoso demais. Você optou por abandonar a técnica, eu optei por buscar formas de simplificar os testes para diminuir esse custo. Eu descobri que eu preciso nos meus códigos de teste, tanto ou mais código limpo do que preciso no meu código testado.

Não vou te dizer que sou um mestre do teste unitário, que se você vir meu código de testes vai ficar tão maravilhado pela simplicidade que vai começar a escrever testes no mesmo instante. Mas eu já percorri um trajeto considerável nesse caminho e sempre que esbarro em problemas nos meus testes eu procuro formas de simplificá-los ainda mais. E isto tem me dado resultado.

Quando eu altero algo meus testes ficam vermelhos normalmente por causa de quebra de contrato, mas alinhar esse contrato e fazer os testes refletí-los tem se tornado tarefa cada vez mais simples. Quando eu digo simples, eu quero dizer rápida. Altero dois ou três testes, as vezes só a montagem comum deles e pronto, eles estão verdes novamente. E adequados às novas regras do sistema.

O que eu tenho sempre em mente é: não se pode perder mais tempo mantendo testes do que mantendo o código testado.

Mas ainda assim o fato de eu ter que alterar testes por causa de alteração de contrato não significa necessariamente que eles só me dão trabalho. Muitas vezes essas quebras de contrato me mostram a inviabilidade de uma solução que eu havia pensado e que talvez não fosse tão óbvia somente olhando o código a ser alterado.

Eu não tenho como manter na minha cabeça todas as possibilidades de efeito colateral de uma alteração, então a quebra de contrato não serve somente pra me encher o saco com tarefa mecânica de alterar o que eu não precisaria se eu não tivesse testes. As vezes eu corro lá no teste que quebrou pra alterar rapidinho e ficar tudo verdinho de novo e epa!!! Não era tão simples assim. Alterar para que atenda ao contrato é simples, acrescento ou removo um parâmetro, mudo a entrada, a saída ou sei lá mais o quê e pronto, tudo compila. Compila, mas não fica verde. E aí eu vejo que vou ter que alterar o contrato bem mais do que havia previsto, ou não da forma como havia previsto, ou que não vou poder alterar de jeito nenhum.

Isso é bem mais comum do que ver os testes encontrando bugs. Mas ainda assim eles encontram. De vez em quando acontece de você se encostar na cadeira esticar bem as pernas, se espreguiçar, mandar rodar os testes e já ir levantando pegar um cafézinho antes de anunciar que terminou, e os testes ficam vermelhos.

Mas o ponto principal, saoj, é que com testes unitários ou sem, os contratos foram modificados e cada ponto em que eles foram modificados e as continuações desses pontos, mesmo aquele daquele cliente menor que quase não pede alteração, mas usa o sistema, todos eles terão de ser executados. Cada caminho desse, cada combinação dessas vai ter que ser validada. Se você não tem testes automáticos alguém vai ter que executar pra você cada uma das funcionalidades que dependia daquele contrato para ver se continua funcionando de acordo com o novo. E esse alguém vai ter que se lembrar de cabeça onde estão e como devem se comportar essas funcionalidades.

Se você tem uma capacidade de design de código tão bom a ponto de desdenhar disso tudo, e eu não tenho porque duvidar disso, não mesmo, até porque os frameworks nos quais você trabalha são elogiados por muita gente, ótimo para você. E se isso é realmente possível eu espero um dia chegar lá. Mas não é o meu caso hoje, e sem hipocrisia, nem falsa modéstia. Eu sou um designer de código no máximo meia-boca, mas a maioria é como eu e a maioria precisa de mecanismos que os ajudem a escrever código melhor e mais confiável.

S

Tens razão, Paulo. Aqui:

Concordo que nesse caso os testes ajudam mesmo.

Eu sou a favor de alterações conservadoras e seguras. De bom entendimento de lógica para que se for alterar não vai fazer merda. Mas tem alterações mais complexas (porra, realmente vc precisa fazer essa alteração complexa) que vai ser foda de garantir que algo não quebrou. Daí vc dá uma testada manual mesmo. Roda o seu sisteminha e testa aquela parte do seu sistema. Não precisa necessariamente testar tudo, mas só aquela parte.

Chegamos num ponto de que não há certo ou errado mais. Vai de gosto mesmo.

Bom ponto, Paulo.

Edit: Outra coisa que sou a favor é de experimentar e mudar que nem um louco no começo. Mas daí chegar num ponto mínimo onde vc tem uma FUNDAÇÃO boa. E partir dali seguir de forma mais conservadora. Sou totalmente contra, por questões de sanidade, responsabilidade e foco em resultado, no meio do projeto fazer uma alteração radical nas coisas. A não ser que ninguém use e que vc esteja cagando para bugs, etc.

Resumindo. No início muda que nem um louco. Estabiliza uma fundação. Depois liga o conservative mode. E som na caixa!

H

YvGa bem lembrado.

Será que um cara que escreve API passaria por algo assim ? Ou a % de chance disso acontecer em relação a um que escreve software corporativo de workflow de aprovação por exemplo, seria maior ou menor ?

De qualquer forma essa colocação foi super válida para apontar esse pensamento.

S

Este pequena frase esconde várias coisas. Primeiro podem ingenuamente pensar que esse sistema irão dar lucro agora. O cara recebe em troca do software e tanto faz se funciona ou não. o usuário nunca irá saber a menos que use.
Ora o problema é que o usuário não compra o software para ter no armário. Ele vai usar. E vai encontrar problemas. E os problemas sempre voltam à origem. E ai começa o ciclo de correções e a erosão da confiança do cliente e do dinheiro antes recebido.
O que parece ia lucro , deixa de ser.
Se estamos falando de produto é ainda pior. qualquer alteração aumenta o risco sobremaneira e é mais caro alterar o legado do que fazer do zero. E ai se criam os famosos modulos ( = não vamos mexer no que temos vamos fazer um puxadinho)
e agora os problemas se multiplicam pelo numero de módulos e este fractal de problemas não tem fim.

Sim, claro, façamos o sistema sem testes automáticos. Afinal isso é muito caro. Porque gastar dinheiro com isso. “gastar” dinheiro com isso. Quando alguém fala que fazer testes é despesa, pronto, ai sabemos que o cara não sabe do que fala. Pior, ainda vive em 1950.

Segundo, quem realmente comanda a parada é o desenvolvedor. O que é que realmente vai acontecer se chegar o prazo e o software não estiver pronto ? Vamos extender o prazo, trabalhar horas extra. E isso que vai acontecer. Nenhum cataclismo irá acontecer.O mundo não acada quando o programador diz que não está pronto. Aliás a gerencia espera ouvir isso. Eles só não acreditam ou não querem acreditar. Todos sabemos que a gerencia já tinha cortado o tempo ao meio para começo de conversa, portanto, não é surpresa para ninguém. Ora ,mas esse atrazo não pode ser grátis. O desenvolvedor tem que dar algo em troca. Será que é aceitável atrazar o sistema porque o programador não sabe o que faz. Não. Mas e se ele sim sabe o que faz e está tentando diminuir o risco ? Alguém o pode culpa por isso ? Não. Alguém já foi despedido por fazer testes unitários a mais ? Não. Então o outro lado da medalha não é apenas a empresa e a gerencia que perdem e acham que fazer testes é “gastar” tempo. O pecado original aqui é a preguiça do programador e a falta de comprometimento com a ética do desenvolvimento. Então o que sobra ? Sobra força a que o gerente lhe diga “não faça testes, é gastar tempo”. Quando a ordem vem de cima é outra música.

E tudo isto nos leva ao terceiro ponto. O atraso civilizacional em que vivemos onde os nossos superiores não reconhecem o óbvio e nossos pares são preguiçosos.
Alguém duvida da eficácia do método ? Alguém duvida que realmente aumenta a segurança, diminuir o risco e o tempo de refactoring ? Então porque discutir se é custosos manter ?
Além se preocupa se é custoso manter os sistemas de testes de uma central nuclear ? Não. Até que eles falham e todos morrem de medo da radiação.

Podemos ver pessoas dizendo que assumem o risco. “Ah! eu não faço testes porque sou o Chuck Noris e os bugs fogem de mim”. Claro. Todos podemos fazer isso. Mas aceitar o risco é uma coisa. Ignorá-lo é outra. E outra pior é não saber que ele existe.
Talvez o investimento não valha a pena. Não é todo o risco que pode ser mitigado. às vezes é simplesmente muito caro e não compensa. Ok. Mas esta decisão é lógica e baseada em fatos. Não é uma questão de gosto. Não é uma questão de preguiça.
Não é uma questão de que tenho que efetivamente manter dois sistemas funcionando ( o test harness e o sistema). Podriamos perguntar, mas se o teste harness é código que o testa a ele ? Ora, existem planos de contigencia do plano principal, mas em software isso é insanamente caro. Portanto, por agora, temos que assumir o risco do código de testes estar errado. Transferimos os risco. Mas transferimos o risco do sistema principal que nos dá lucro para o sistema de apoio que não nos dá prejuizo. É bem diferente.

Outro ponto que está sendo esquecido é que ninguém trabalha sozinho. É fácil vc trabalhar sozinho num framework que pode até ser grande e complexo, mas vc tem tudo na cabeça e sabe onde as coisas irão falhar e assume o risco e não faz testes. Outro cenário bem diferente é ter 10 ou 20 pessoas trabalhando com estilos diferentes em pedaços diferentes do código que ninguém realmente conhece todo. Quem vai assumir o risco ? Você vai assumir o risco do código que o seu colega criou ? Por muito que ele seja um gênio ou cuidadoso , vc poria a mão no fogo por ele ?

Ninguém vai me dizer que sim, né ? Então vamos nos deixar de bla bla bla sobe o quão dificil é manter um test harness. Simplesmente é. E simplesmente é necessário. Pronto. É como manter a segurança de um central nuclear ou ter que educar os filhos. Não é fácil, mas é necessário. É claro que queremos que seja o mais rápido, barato e simples possível, mas isso é completamente diferente de simplesmente não fazer nada.

A razão de porque as empresas e os gerentes não levam o test harness a sério é porque os desenvolvedores não o levam a sério e não o sabem vender. Eu me incluo aqui.Eu sei o quão sério é, mas não consigo vender porque logo alguém vem e fala que é “gastar” dinheiro. E tudo bem se fosse o gerente a falar isso. O pior é quando é outro colega. Ai passa a ideia que existe um caminho mais fácil. Claro. Mais fácil. Mas não mais seguro.

Depois que todos são conscientes do que é, e como funciona, e como irá influenciar o futuro e ai, baseado em dados e fatos se chega à conclusão que não é necessário, isso é legítimo. Mas descartar à partida baseado em uma filosofia de vida dos estilo “Chuck noris” ai não dá. É simplesmente idiota.

SE vc tem um classe matriz que vc vai usar em programa que c vai usar 2 vezes, não ha porque mitigar o risco. Seria mais caro que fazer o programa. Agora se vc vai usar essa classe num sistema de calculo que trabalha com milhões e pode ganhar ou perder milhares, vc vai encarar o risco ? E se for um sistema de apoio à vida ? Tamanho e proporção. É isso que temos que ter antes. Por isso que eu não acho que TDD é ensinada corretamente. O Beck tem tendencia a exagerar. Para ele eu tria que testar que 2+ # não é 4 para depois decobrir que 2+2 que é 4 , quando eu já sei à prioria isso. Eu teria que criar um teste para a matriz, antes de criar a matriz mesmo que eu só vá usar 2 vezes. Ou o exagero do tio Bob que o TDD é equivalente e matar o goto. Por amor de Deus, não é nada disso. Tamanho e proporção. Tamanho e proporção.

S

Discordo de vc aqui. Posso falar pela minha experiência. Cada um tem a sua e é ela que vai determinar seu modo de ver as coisas. Ninguém nasce com convicções. É o ambiente e o caminho que o cara percorre que as cria.

Trabalhei em banco de investimento onde um bug significava prejuízo certo e instantâneo. Entre 50k e 200k. Claro que a empresa fazia bastante dinheiro para aguentar um erro desse por mês, mas eu vi uns 4 ou 5 em dois anos. A pergunta é: Se houvesse testes unitários haveria esses erros? Provavelmente, porque nunca era erro simples. Eu fiz um erro desse uma vez que custou uns 100k. Claro que me lembro até hoje. Assumi que a conexão nunca iria me enviar uma coisa, que essa coisa era impossível. Na verdade se eu soubesse disso teria codificado um IF conservador para pegar esse caso, mesmo ele sendo 99.9% impossível. Mas nem sabia da existência dessa possibilidade. Daí a coisa mapeou um produto A como se fosse um produto B. Descobriu-se a cagada em 5 minutos com posições inconsistentes mas o estrago já tinha sido feito. Dava para pegar esse erro com teste unitário? Claro que não.

Se eu altero código dos outros, que eu não domino, basta ser conservador. Se vc for querer ser chuck norris de entender tudo, codificar usando padrões GoF, fazer cobertura 100% o que vai acontecer é que vc vai demorar 10 vezes mais para fazer a coisa e a chance de ter um erro ali será praticamente a mesma. Existe pessoas e empresas práticas que querem resultado e dinheiro. E outras que querem engenharia de software e padrões GoF. Essas últimas geralmente são empresas grandes onde dinheiro não é problema e a burocracia é grande de qualquer jeito então pode-se gastar o tempo que for refatorando e é até melhor pois não vão te pedir para fazer outras coisas. 8)

Tudo que é necessário é boa lógica, bom OO e pouco puritanismo. Fiz essa alteração de acordo como os deuses da engenharia de software gostariam de vê-la? Não! Mas te garanto que é 100% segura! E fiz em 5 segundos. Pode colocar em produção.

Já trabalhei em outra banco de investimento que era o oposto disso. Daí tirei minha preferência, vendo os dois mundos operar.

Teste unitário é bom. Sim, com certeza. Teste unitário é fundamental. Não, na minha opinião.

Um sistema que tem mais teste unitário que outro é mais seguro do que outro. Pela minha experiência acho que não.

Mudança radical num sistema que já esteja em produção e funcionando por um bom tempo é permitida? DE JEITO NENHUM. Gasta um tempo inicial para fazer a coisa direitinho e bonita. Depois entube a sua decisão e se preocupe em gerar resultados para o negócio e não em ficar brincando de engenharia de software. (Nota: Se tivesse teste unitário a mudança radical TAMBÉM não seria permitida em fase avançada)

A regra dos práticos é clara: não se faz mudança radical em sistema que já está funcionando em produção há muito tempo. O cara que fez, fez tudo cagado? Sorry, então refaz do zero a parte cagada, mas não vai brincar de meter a mão para colocar padrões GoF e arranjar um bug em produção que antes não existia. :wink: A merda principal foi ter feito a coisa cagada in the first place. Por isso que é importantíssimo gastar um tempo inicial numa boa fundação. Começar com uma fundação cagada aí não há deus de engenharia de software (quanto menos teste unitário) que vai te salvar.

H

sergiotaborda

Na boa, não posso divulgar o cenário desses 2 projetos.

Logo você está livre para conclusões boas ou ruins.

Agora sobre chuck noris, cowboy esses rótulos, não achei muito legal, porque no geral não desenvolvemos apenas lá, tem infra e mais uma série de coisas para cuidarmos. mas tranquilo.

Me lembrei de quando trabalhava home-office , tive que derrubar 2 coqueiros (com um facão vagabundo) para ter acesso à internet, lembro que no segundo coqueiro eu estava pensando na infra-estrutura do projeto e uma pendência com o maven que eu tinha que resolver. Quando terminei pensei “Porra, isso faz parte ?”

Meu gerente na época falou que foi a primeira vez que ele teve problema desse na carreira dele. Falei sobre a pendência do Maven o cara falou que eu havia perdido 2 dias sem internet e mais uma manhã de um sábado derrubando coqueiro, deixa a pendência pra lá.

Incrivel porque um monte de teste unitário foi pro lixo também… o detalhe é que o cliente é um hotel residencial grande pra caralho em NY. Cuidava desde o servidor CentOS pra aguentar as pancadas de usuários em 4 de julho e natal. Mas isso ai qualquer zé-cueca faz hoje em dia “joga no cloud”.

Eu até quiz terminar os testes, mas fiquei com uma preguiça da porra, confesso. Sem falar que tive um problema temporário de coluna e os calos nas mãos porque os coqueiros que derrubei tinham mais de 20 anos, sei disso porque eram da casa do sogro. Mas tudo em prol do software !

H

Acabei de encontrar isso aqui:

http://www.uispec4j.org/example

Nesse blog aqui:

http://cantinhodoagile.blogspot.com.br/2010/07/uispec4j-para-teste-de-aceitacao.html

Hoje senti vontade de aplicar no sistema java swing que citei anteriormente. Fica a dica para quem não conhecia assim como eu.

O cenário desse projeto foi assim com o stakeholder in house:

Sr. “A” ------------------------------ Eu

“Cliquei aqui deu problema…” > “Corrigido”
“Não está aparecendo a aba…” > “Corrigido”
“A tabela não está carregando dependendo de xpto” > “Corrigido”

E assim por diante

Nesse caso uma ferramenta como o uispec4j ajudaria em não desperdiçar o tempo do “Sr. A” ou pelo menos reduzir correto ? Quando houve uma pré-implantação, tivemos que modificar
o sistema de tabulação inteiro do TAB para o Enter. Isso só com bola de cristal mesmo, para descobrir que o cara da ponta usa apenas o teclado numérico porque segura documentos com a outra mão.

Set set = new HashSet(KeyboardFocusManager.getCurrentKeyboardFocusManager().getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
set.clear();
set.add(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
KeyboardFocusManager.getCurrentKeyboardFocusManager().setDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, set);

Sobre agregar valor, nesse caso agregaria mais valor usar o uispec4j do que uma bateria de testes no modo TDD ou seja lá como for ?

Eu acredito que sim, mas se alguém puder complementar.

Putz parece que existem problemas do uispec4j no linux

java.lang.UnsatisfiedLinkError: sun.awt.motif.MToolkit.init(Ljava/lang/String;)V

at sun.awt.motif.MToolkit.init(Native Method)

at sun.awt.motif.MToolkit.(MToolkit.java:146)

at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)

at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

at java.lang.reflect.Constructor.newInstance(Constructor.java:525)

at java.lang.Class.newInstance0(Class.java:372)

at java.lang.Class.newInstance(Class.java:325)

at org.uispec4j.interception.toolkit.UISpecToolkit.buildUnderlyingToolkit(UISpecToolkit.java:128)

at org.uispec4j.interception.toolkit.UISpecToolkit.setUp(UISpecToolkit.java:39)

at org.uispec4j.interception.toolkit.UISpecToolkit.(UISpecToolkit.java:24)

at org.uispec4j.UISpec4J.initToolkit(UISpec4J.java:39)

at org.uispec4j.UISpec4J.init(UISpec4J.java:31)

at org.uispec4j.UISpecTestCase.(UISpecTestCase.java:31)

at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)

at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

at java.lang.reflect.Constructor.newInstance(Constructor.java:525)

at junit.framework.TestSuite.createTest(TestSuite.java:61)

at junit.framework.TestSuite.addTestMethod(TestSuite.java:294)

at junit.framework.TestSuite.addTestsFromTestCase(TestSuite.java:150)

at junit.framework.TestSuite.(TestSuite.java:129)

at org.junit.internal.runners.JUnit38ClassRunner.(JUnit38ClassRunner.java:71)

at org.junit.internal.builders.JUnit3Builder.runnerForClass(JUnit3Builder.java:14)

at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)

at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)

at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)

at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)

at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.(JUnit4TestReference.java:33)

at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.(JUnit4TestClassReference.java:25)

at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)

at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

[editado]
Consegui colocar para funcionar…mas tive que criar uma versão uispec4j-2.4-LOBOMETAL.jar :slight_smile:

Dou uma dica pra quem quizer brincar de fazer funcionar no linux :

// Black magic - do not touch this (system.setProperty seem to load dynamic libraries)
    if ("Linux".equalsIgnoreCase(System.getProperty("os.name"))) {
      System.setProperty("awt.toolkit", "sun.awt.motif.MToolkit");
}

Pois é… tem “black magic” no código da ferramenta de testes, mas enfim…

[/editado]

A

Quem tem utilizado automação de testes funcionais? Em caso positivo, qual ferramenta?

S

Se for aplicação web: watir e selenium.

Se não for aí vc pode usar Junit para fazer teste funcional.

A

Se for aplicação web: watir e selenium.

Se não for aí vc pode usar Junit para fazer teste funcional.

Já usou Watir em páginas Applet? Será que funciona? Conhece algum que funcione? Pois o Selenium não funciona.

N

YvGa:
NickGaspar:
YvGa:

embora muitos clamem ter achado o santo graal do desenvolvimento de software

Se Donald Knuth, Joe Armstrong e Ken Thopnsom, pra citar alguns, encontraram o santo graal eu não sei, mas o que eles falam, eu seria um trouxa se não escutasse.

Por outro lado, pra cada um que diz ter achado o santo graal do desenvolvimento de software, existe 10 blogueiros e autores de livros que só sabem falar sobre como programar OO usando TDD, mas não fazer.

Bom, pelo menos eles não ficaram conhecidos pelo software que criaram.

Agora, não me leve a mal, até gosto do trabalho do Bob Martin, mas não vamos confundir evangelizadores de testes com os verdadeiros mestres da arte!

Como eu disse no meu post anterior, não devemos usar da exceção para tentar provar a regra.

Eu não sou um grande mestre, eu não tenho toda a bagagem e nem todas as qualificações que eles têm para simplesmente ignorar o que aqueles como eu dizem.

Repetindo Keith Braithwaite:

Se dez blogueiros e alguns autores me dizem que teste unitário é bom (e eu comprovei por conta própria que para mim é), mas alguns dos mestres dizem que para eles é perda de tempo em quem eu devo acreditar?

Lógico que nos blogueiros e autores, pois eles estão bem mais próximos da minha realidade do que esses caras. Eu não sou um gênio, nem nunca vou me tornar, eu sou apenas alguem que recebe um pouco de dinheiro para entregar bom software para o meu cliente. Mais ou menos como os blogueiros que dizem que testes unitários são importantes, com mais ou menos os mesmos problemas e as mesmas dificuldades. Se funcionou para eles, é bem possível que funcione para mim. O que funcionou para Donald Knuth, pouco provavelmente funcionará para mim.

Se você está entre os gênios que pode simplesmente ignorar o benefício que esta técnica tem trazido, ótimo para você. Mas esse não é o meu caso, não é o nosso caso, o da maioria dos programadores.

E só para garantir que ninguém se esqueceu. Ainda hoje, a falha é a regra em projetos de software.

Então você acredita na maioria que não desenvolve software que se preze, ao invés dos programadores produtivos (não necessariamente gênios) que prezam pela sua arte?

Interessante…

H

Encontrei essa outra aqui para testes funcionais java swing:

http://code.google.com/p/fest/

Tive que corrigir bugs na uispec4j para funcionar no linux e mesmo assim ela quebrou em outros pontos. (Ver página anterior)

H

andredecotia

No site desse projeto aqui informa que funciona, tem que faer o experimento pra ver.
http://code.google.com/p/fest/
http://fest.easytesting.org/

Y

Não, você é quem acredita neles, embora goste de pensar que acredita naqueles que “prezam pela sua arte”. A maioria faz software ruim e a maioria não usa testes e é essa maioria que você está defendendo.

Ok, os grandes mestres não usam testes unitários, logo é possível criar grandes softwares sem testes unitários. Mas a regra geral é que a indústria de software é uma merda e a indústria de software no geral não usa testes unitários. Logo se conclui que o fato de não usar testes unitários não é o que faz com que os mestres construam grandes softwares. Então há outras coisas no que eles fazem que permitem que eles construam grandes softwares.

Se você sabe do que se tratam essas outras coisas, parabéns, você não precisa de testes unitários. Se você não sabe, mas quer continuar procurando, direito seu. Só cuidado ao dizer que testes unitários são ineficazes e não ajudam a escrever código de qualidade porque o único argumento que você trouxe para defender a sua teoria foi o Donald Knuth dizendo que não gosta de escrever testes unitários.

Repare que a opinião do Sérgio e do Hélio é: Teste unitários não garantem qualidade de código. Enquanto a sua é: Testes unitários são ineficazes e não auxiliam a construir um código bom.

Ligeiramente diferentes.

Y

heliofrota:

Mas o ponto principal, saoj, é que com testes unitários ou sem, os contratos foram modificados e cada ponto em que eles foram modificados e as continuações desses pontos, mesmo aquele daquele cliente menor que quase não pede alteração, mas usa o sistema, todos eles terão de ser executados. Cada caminho desse, cada combinação dessas vai ter que ser validada. Se você não tem testes automáticos alguém vai ter que executar pra você cada uma das funcionalidades que dependia daquele contrato para ver se continua funcionando de acordo com o novo. E esse alguém vai ter que se lembrar de cabeça onde estão e como devem se comportar essas funcionalidades.

YvGa bem lembrado.

Será que um cara que escreve API passaria por algo assim ? Ou a % de chance disso acontecer em relação a um que escreve software corporativo de workflow de aprovação por exemplo, seria maior ou menor ?

De qualquer forma essa colocação foi super válida para apontar esse pensamento.

Cara, realmente eu não sei, mas para mim escrever teste antes do código já é tão natural que eu escreveria os testes de qualquer forma.

Sérgio, alguns pontos em que eu discordo de você aqui e eu vou ter que escolher precisamente as palavras para que não pareça maluquice.

Eu não discordo exatamente do que você diz, mas discordo do enfoque. A questão do esforço necessário pelo bem do projeto. Eu duvido sim da eficácia do método da forma como você colocou. E devemos sim discutir se é custoso manter.

Devemos sim discutir se é custoso manter os testes porque existem muitas outras coisas que nos tentam enfiar goela abaixo num projeto de software em nome desse mesmo bem a que você se refere. Não seria ótimo se você sempre tivesse toda a documentação do seu sistema atualizada e você soubesse que assim que precisasse era só dar uma folhada e aquela funcionalidade maluca, cheia de poréns estaria bem desenhada na sua frente, detalhadamente e bem da forma que você precisa para simplesmente alterar o que for preciso sem se preocupar com mais nada?

Isso é impossível, isso não vai acontecer nunca, em lugar nenhum. Mas ainda há muita gente que insiste nessa tese, e culpa sempre e invariavelmente a preguiça e a falta de empenho necessários para se manter toda a documentação atualizada. Mas o fato é que a expressão sempre avaliará “true”, porque se a documentação não está atualizada, você é preguiçoso, como a documentação nunca está atualizada, você sempre é preguiçoso.

Em nenhum momento o cara pensa que fazer isso é como enxugar gelo e que vai chegar a maldita hora, por mais esforço que se faça, que a documentação estará desatualizada. (E nessa ânsia de se documentar tudo em UML, MER e sei lá o que mais, não se documenta nem a regra de negócio no bom e velho português mesmo).

E o mesmo acontecerá com testes unitários se forem feitos da forma como você propõe. Testes criados depois do código, embora mais importantes, sofrerão do mesmo problema. Cedo ou tarde, algum código urgente será deixado sem teste, e depois outro e outro e outro. Mas a culpa cairá sempre na preguiça do quem devia ter escrito o teste e não no fato do teste não poder ser escrito depois do código.

E a você é a prova disso quando diz:

Repare que você se inclui aqui, entre aqueles que não sabem vender, como também já admitiu que os seus sistemas têm bem menos testes do que deveriam, ou do que você gostaria que tivessem. Mas logo você que escreveu um texto tão bonito sobre a importância deles? Será que você não está se iludindo com o seu test harness tanto quanto os pseudo-gerentinhos-adoradores-de-cmmi se iludem com um projeto bem documentado?

Eu não acredito nesse esforço heróico pelo bem do projeto e que aquele que não quiser se doar pelo maldito test harness tem que arcar com as consequências. Isso não funciona, nem para nós mesmos. Ainda que acreditemos na importância, nós não vamos fazer esse esforço, simplesmente porque há coisas mais importantes nas quais devemos nos concentrar antes de ficar preocupado em escrever código de testes para funcionalidade já implementada. E escrever mais funcionalidades é uma delas, assistir televisão outra, postar no GUJ, almoçar com a esposa, jogar bola com o filho, cortar coqueiro do quintal do sogro…

O ponto crucial é: Enquanto você não colocar os testes unitários na sua rotina de desenvolvimento você não escreverá testes e você nunca vai colocá-los na sua rotina se tentar escrevê-los depois do código pronto. Escrever um teste para uma classe antes mesmo dela existir, alem de te ajudar a definir a sua interface publica, é escrever o primeiro cliente da sua funcionalidade, é experimentar, avaliar, mudar, opinar, escrever e errar, e errar de novo e mudar a interface, melhorar até finalmente acertar. Isso faz parte da sua rotina de programação, faz parte do que você chama de programar, até chegar o dia em que programar sem isso é estranho.

Por isso eu tenho tanta dificuldade em discernir o que é teste unitário do que é test-first do que é TDD, pra mim é tudo a mesma coisa, para mim tudo isso é programar. Escrever testes não tem que ser custoso, ninguém tem que se conscientizar de nada, ninguém precisa ser acusado de preguiçoso, nem precisa realizar esforço hercúleo nenhum pelo bem do projeto. Não tem custo, não tem preço, não tem nada. Enquanto você está programando os testes vão surgindo e você gosta deles, eles não são um fardo que você tem que se lembrar de carregar, eles fazem parte da sua atividade natural de programar.

Esse seu post e a forma como você chamou a atenção para o peso dos testes unitários fortaleceram bastante em mim a teoria de quem sem Test-Driven Development não é possível ter testes unitários de qualidade.

G

Falou bonito aqui :smiley:
A velha conversa de “o prazo é apertado, não vai dar tempo de ______”. Aqui você completa com qualquer boa prática, desde o básico do OO, criar classes para isolar responsabilidades, reusar ao invés de dar Ctrl-C Crtl-V no código, etc.
As pessoas têm resistência de aceitar que esses 15 minutos a mais não serão a causa no atraso do projeto, pelo contrário, servem para ganhar tempo. E não é aquela coisa teórica tipo “Ahhh no futuro a manutenibilidade do código bla bla bla”, os benefícios são imediatos, sua funcionalidade realmente vai estar pronta e funcionando mais rápido.

S

O ponto é o seguinte : não pode se pode negar a importância de ter documentação ou testes. Você comparou os dois e acho que é isso mesmo. Se cometem os mesmos erros nas duas áreas. A documentação é necessária. Os testes são necessários. Negar isto , para mim, é insanidade e demonstra falta de experiencia e profissionalismo. Agora, que aceitamos que é importante, vamos analisar como fazer.

O como fazer é que vai ditar o custo. Mas seja como for que vc for fazer o custo nunca será zero. E o custo zero é o que vc tem quando não faz.
O que eu argumento é que o custo pode ser zero, mas o risco aumentou brutalmente. Portanto não compensa. Mais vale investir em teste e documentação do que aceitar o risco.

Agora, quando eu digo “investir” eu quero dizer “investir” e não gastar. Criar documentação antes do software estar pronto é bobagem e é gastar (desperdiçar) dinheiro. Fazer o manual do usuário depois que o software está pronto é mais barato , possível e útil. Todos os equipamentos que vc compra vêm com manual. Ok, pode ser muito simples quanto uma página ou complexo como uma bíblia, mas tem manual. Porquê ? Porque isso agrega valor ao produto. Seu produto não irá ficar famoso se ninguém usar. Mas o manual, como tudo o resto é um artefacto opcional. Em projetos on demand, tlv não seja necessário porque o cliente não pediu, e se pediu, ele pagou o custo.

Portanto, testes é importante. Criar testes demanda investir dinheiro. O investimento compensa quando bem feito.
Negar que algumas destas fases é verdade é irrealista.

É possível fazer um test harness errado e mais caro do que deveria? claro. Assim como é possível fazer qq software errado e mais caro do que necessário. Quem vai fazer a diferença é o desenvolvedor. Por isso falei da ética envolvida e da preguiça.

O fato de um sênior não conseguir fazer um test harness não prova que é impossível, nem muito menos prova que não é necessário ou que ele não deveria tentar.

Os testes, tal como a documentação, não precisam cobrir 100% das coisas no dia 1. A escrita é incremental. Vc começa com o caminho critico e vai evoluindo dai. O fato do seu objetivo ser cobertura 100% , e o fato de vc saber que é inalcançável, não deve impedir vc de tentar. Pois se isso fosse assim, vc não trabalha com software para começo de conversa (porque todo o software só está pronto 100% com todas as features possiveis e imagináveis em infinito tempo).

Para mim só é enxugar gelo quando é mal feito.
Poderíamos argumentar que refactorar é enxugar gelo. Mas quando é bem feito, vc refactora 1 vez, 2 no máximo e não todos os dias.

Como vc acha que eu proponho ? Porque eu não propôs nada sobre o “como”. O meu ponto é que simplesmente não é profissional de esquivar deles dizendo que são desnecessários ou que é tudo um complô para vender livros e que a complexidade da empreitada ou o custo também não são desculpas.E que é responsabilidade do desenvolvedor diminuir o custo e a complexidade.

Exatamente. O fato de eu ser ruim de testes e o meu test harness ser fraco e eu não conseguir convencer meus chefes da sua importância não significa que não sejam importantes e que eu posso simplesmente abandonar a ideia sob o pretexto que “eu não preciso disso”. Eu preciso, é fato. Não vale a pena argumentar o contrário. O que vale a pena argumentar é como eu poderia ser mais proficiente nos testes / diminuir custos / vender a ideia melhor.

Eu posso me iludir sobre a simplicidade da iniciativa, mas não sobre a sua importância. Para mim é tudo sobre diminuir risco. E no caso especifico dos testes é também sobre dar um colchão de segurança e remover o medo que os desenvolvedores têm de mudar o que existe.

Nem eu. Por isso que eu falo que os desenvolvedores têm que encontrar formas de diminuir o custo e a complexidade. Não é uma questão de heroismo. É uma questão de ferramentas e processos. Mas mais que isso é uma questão de entender que não se pode dizer que não aos testes.
Como falei antes, Tamanho e Proporção. É isto que vai ditar, quais, quantos, como e quando os testes são feitos. Mas nunca se eles são feitos ou não.

Concordo. Isso é o conceito de Test-First.

Também concordo. Isso é o conceito de TDD (Test Driven Development). O meu ponto é que é possível modelar , avaliar, opinar, etc… sem usar os testes - vc pode usar o próprio cliente normal para isso ou outras técnicas como design patterns , por exemplo. Ou vc pode simplesmente usar a cabeça e pensar nas opções. Eu concordo que usar os testes para modelar é legal, mas não é a única forma. Ao contrario do Test-First que é única forma. Um nega o outro ? Talvez, afinal usar o Test-First para fazer um teste meia boca é contraproducente. Mas ficar produzindo testes adoidado também é. Ou seja, o Test-First significa que vc tem que ter testes antes, mas quantos ? Quais ? um é suficiente ?

O meu argumento é: Não importam esses detalhes, isso faz parte do “como”. O que importa é saber que se vc não faz test-first ( seja qual a forma for) vc está fazendo menos do que poderia. É como modelar sem usar design patterns, é possível, mas é menos do que poderia fazer.

Ótimo. E temos muito que aprender consigo. Isto não é ironia. O ponto é que quem não chegou nesse nível, não pode dizer que é irrelevante ou desnecessário só porque não domina a coisa. Mais que isso, deve entender que isso mesmo que deveria tentar atingir. É a mesma coisa do cara que não usa design patterns porque não sabe como e depois diz que é tudo baboseira e inútil.

Aqui que eu não concordo com vc. Sim é preciso conscientizar. Sim é preciso entender o curso, o risco, as vantagens. Sim é preciso deixar claro que o desenvolvedor não se pode esquivar do problema ignorando-o e se o fizer, isso é preguiça (profissional e pessoal).
Quanto ao esforço hercúleo , de fato, não tem que ser assim. Mas vc tem que estudar e entender das coisas para que seja e pareça fácil. Isso demanda esforço e muitos não querem pagar esse esforço.

Sim. É verdade. Sendo a palavra operacional “qualidade”. Mas não o TDD dos livros. Esse é muito acadêmico, o TDD que vc falou de avaliar , modelar usando o código do teste e influenciando o design da unidade sob teste. Para mim o TDD é opcional porque existem outra formas de desenvolver, mas o test-first é vital. E se eu não faço isso no dia-a-dia é problema meu e a culpa é minha. A técnica é válida. Mas se eu não uso TDD isso é uma opção válida. Se eu não uso, não ha problema.

Resumindo: obrigar todo o mundo a fazer Test-First seria excelente (é a proposta do XP). Obrigar todo o mundo a fazer TDD é contra-producente.

Y

sergiotaborda:
YvGa:

O ponto crucial é: Enquanto você não colocar os testes unitários na sua rotina de desenvolvimento você não escreverá testes e você nunca vai colocá-los na sua rotina se tentar escrevê-los depois do código pronto.

Concordo. Isso é o conceito de Test-First.

Desculpe, eu não havia entendido bem a sua ideia. Como eu disse, eu acho difícil não fazer a associação de test-firs com TDD. Nesse caso realmente concordamos em mais coisas que parecia.

Se voce fala em investimento no aprendizado eu concordo com você. Quando eu digo não tem custo, eu falo contra o frequente argumento de que para se escrever um software usando testes se leva mais tempo do que escrever sem ele. O feedback imediato que um teste unitário já pronto te dá eu acho pouco provável ser compensado por qualquer outra técnica. Escrever um método de teste é mais rápido que subir o servidor acessar a tela, navegar por entre os campos, entrar com os dados e só então verificar se funcionou ou não. Ok, técnicas e ferramentas, podem diminuir o tempo ou até eliminar a necessidade de alguns desses passos, mas dificilmente vai alcançar o tempo de escrever um método rapidamente e rodá-lo indefinidamente assim que desejar. São milésimos de segundos para cada execução.

Eu não sei exatamente o que você chama de TDD dos livros, ou se eu o pratico ou não. Mas eu não levo a regra de “não escrever uma linha de código antes que haja um teste pra ela ao pé da letra”. Eu raramento testo por exemplo o meu controller (no caso do vraptor que uso, ou managed bean do jsf, ou o action do struts ou algo que o valha). Talvez eu esteja errado e alguém traga bons argumentos pra me desmentir, mas eu não ponho lógica neles a ponto de ser necessário testes. É um if-else aqui e ali, um try catch lá, coisa que para qual não acho valeria a pena mockar meio mundo só pra garantir que o catch está tratando a exceção corretamente.

Também não sei exatamente a que tipo de testes você se refere quando diz que test-first é importante. Se for quanto aos testes de aceitação, escritos antes código, eu concordo, são importantes, talvez até mais que TDD para definição de regras de negócio. A grande diferença deles para TDD é que eles não dão o mesmo feedback imediato e quando quebram, quebram em bloco o que muitas vezes não permite a identificação imediata do ponto que quebrou. Eu acho que testes de aceitação e TDD são complementares.

Se você fala de testes funcionais automatizados, quanto a esses eu confesso que ainda não achei um ponto ideal. Eu acho sensacional o Selenium e tudo que ele é capaz, mas ainda não encontrei a fórmula para trabalhar com este tipo de ferramenta. Os meus testes se quebram na menor alteração que eu faça, mesmo quando não deviam. Sim, eu sei, talvez seja falha minha e ainda pretendo me aprofundar mais nele, mas por enquanto tenho pouquíssimos testes com Selenium, justamente pelo altissimo custo de manutenção deles.

Quanto ao obrigar ou não é que é complicado. Eu estou trabalhando numa empresa há pouco mais de seis meses, quando eu cheguei não havia a cultura de testes unitários, eu fui por conta própria colocando testes nos pontos em que ia mexendo e incentivando os meus colegas a fazer o mesmo. Uns receberam bem, já conheciam a técnica de ler e ouvir falar, outros nem deram bola. Hoje um deles já programa usando testes, outros já estão bem adiantados e outros continuam não dando bola.

Mas a minha postura desde o início foi a seguinte: Eu escrevo testes, quem quiser também escreve, mas ninguém é obrigado a nada. E caso for mexer num ponto em que haja testes, pode deixar que eu cuido dos testes. Eu estou praticando TDD de forma absolutamente não intrusiva. O sistema hoje tem mais de 500 testes rodando todos os dias num servidor de integração contínua, a cada vez que alguem sobe código no repositorio os testes são executados, um build é gerado e colocado no servidor de homologação. 500 testes é pouco para um sistema daquele porte, mas é um começo, e o número cresce gradualmente, já que agora eu não sou o único que os escreve.

Mas o ponto que eu insisto com o pessoal lá de cima, que já percebeu os benefícios que os testes trouxeram é: eles tem que comprar a ideia, eles tem que gostar de fazer e incorporar a técnica ao dia-a-dia deles. Para isso acontecer a minha primeira preocupação é: não criar resistência. Não fazer com que os testes atrapalhem a equipe antes de começar a ajudá-la.

Por isso que eu acho complicado simplesmente chamar de preguiça uma posição mais cética dos programadores. Quantas idéias mirabolantes já surgiram e não deram certo? e só serviram como mais uma desculpa pra chamar programador de desinteressado, indiferente, preguiçoso, reacionário entre muitos outros elogios.

Quando você começa a deixar de se divertir com o seu trabalho a qualidade do que você está fazendo começa a cair. Levando isso em conta é que eu digo que ou você adora escrever os testes ou você não os vai escrever. Posso estar errado, mas é isso que me faz acreditar que só com TDD se pode escrever testes unitários. TDD é divertido.

H

Essa foi a parte que mais gostei dessa quinta página.

R

Po Amigo é assim que vc trata seu software?

S

Este tópico me inspirou a voltar a escrever em portugues:

http://alemdocodigo.posterous.com/tdd-nao-aumenta-a-qualidade-do-codigo

Ao meu ver nenhuma prática garante qualidade de código diretamente. Porém existem muitas práticas (TDD, pair programming, peer reviews (ate pull request?), code conventions etc) que podem promover uma reflexão maior sobre o código e uma consequente melhoria na qualidade geral do software.

S

s4nchez:
Este tópico me inspirou a voltar a escrever em portugues:

http://alemdocodigo.posterous.com/tdd-nao-aumenta-a-qualidade-do-codigo

Ao meu ver nenhuma prática garante qualidade de código diretamente. Porém existem muitas práticas (TDD, pair programming, peer reviews (ate pull request?), code conventions etc) que podem promover uma reflexão maior sobre o código e uma consequente melhoria na qualidade geral do software.

Bom post !!!

Respondi lá:

“Esta reflexão sim é a chave para qualidade. XXXXXXX permite que eu reflita sobre cada comando, cada método, cada classe e escreva o melhor código que sou capaz de escrever hoje em dia.”

No meu caso eu faço essa reflexão a cada tecla que pressiono de forma automática e contínua. No meu caso não é o TDD que me incentiva a fazer isso mas a IDE com easy refactory, o Java sendo uma strong typed language e o gosto pela programação.

Se não um computador poderia escrever código… :slight_smile:

Substituia XXXXXX por qualquer coisa e seja feliz. :slight_smile:

Y

s4nchez:
Este tópico me inspirou a voltar a escrever em portugues:

http://alemdocodigo.posterous.com/tdd-nao-aumenta-a-qualidade-do-codigo

Ao meu ver nenhuma prática garante qualidade de código diretamente. Porém existem muitas práticas (TDD, pair programming, peer reviews (ate pull request?), code conventions etc) que podem promover uma reflexão maior sobre o código e uma consequente melhoria na qualidade geral do software.

Interessante o texto do Feathers. Sinceramente, é a primeira vez que eu vejo algum autor “condenando” o uso excessivo de mocks. Embora não me lembre de nenhum apoiando, os mocks sempre foram vistos como algo inerente ao TDD, quase que como vem junto.

E enquanto isso eu os evitava a todo custo. Só uso mock quando preciso simular acesso a recurso externo a aplicacao (diretorios, arquivos, bancos de dados), tento não criar mock de coisas que eu mesmo vou implementar.

É como eu disse láááá no começo do tópico: Não sei se isso é aplicável a todo mundo, não sei se quem programa um framework genérico tem essa possibilidade, mas eu uso mocks o mínimo possível.

R

Aí é que está o ponto. De nada adianta fazer o TDD se os princípios de design OO não forem conhecidos pelo programador. Se você precisa de muitos mocks para escrever um único teste, isso significa que a classe testada possui muitas dependências e o acoplamento entre elas é alto. De fato, essa é a maior crítica que tenho lido e ouvido sobre TDD. É justamente o fato de que ela está sendo vendida e comprada como bala de prata, que basta escrever o teste antes e “puff”, sai um bom design. Outro fato interessante: às vezes, para tentar vender testes automatizados como “divertidos” a impressão que tenho é que os autores escondem os testes de integração, que dependendo da situação, são mais apropriados como ferramenta de teste, mas são sempre mais difíceis de escrever e configurar.

E enquanto isso eu os evitava a todo custo.  uso mock quando preciso simular acesso a recurso externo a aplicacao (diretorios, arquivos, bancos de dados), tento não criar mock de coisas que eu mesmo vou implementar

Interessante, pois a recomendação do Growing-Object-Oriented-Software-Guided-Tests é justamente mockar objetos de sua autoria somente, justamente, porque ao mockar APIs de terceiros, você não pode garantir o ccomportamento das mesmas. O mesmo vale para recursos como sistemas de arquivos, bancos etc. Ou seja, é o típico caso em que testes de integração podem funcionar melhor.

Y

rmendes08:

E enquanto isso eu os evitava a todo custo. Só uso mock quando preciso simular acesso a recurso externo a aplicacao (diretorios, arquivos, bancos de dados), tento não criar mock de coisas que eu mesmo vou implementar
[/code]

Interessante, pois a recomendação do Growing-Object-Oriented-Software-Guided-Tests é justamente mockar objetos de sua autoria somente, justamente, porque ao mockar APIs de terceiros, você não pode garantir o ccomportamento das mesmas. O mesmo vale para recursos como sistemas de arquivos, bancos etc. Ou seja, é o típico caso em que testes de integração podem funcionar melhor.

Veja, eu posso estar errado, mas qual o sentido de eu mockar minhas proprias implementacoes se eu posso simplesmente instancia-las e ter testes integrados? Claro, uma requisicao http quando estiver testando um controller ou um dao quando estiver testando um servido que obrigatoriamente usa acesso a banco voce mocka (ou o próprio servico quando for algo um pouco mais complexo), mas mockar minhas próprias implementacoes?

De qualquer forma eu não li o livro que voce citou como exemplo, então podemos estar usando exemplos em contextos diferentes. Já anotei aqui o nome do livro, já está na lista para ser lido.

Talvez o que o autor seja algo como foi postado neste http://www.guj.com.br/java/278717-tdd-x-baixo-acoplamento tópico em que o teste não testa nada alem do mockito.

R

YvGa:
rmendes08:

E enquanto isso eu os evitava a todo custo. Só uso mock quando preciso simular acesso a recurso externo a aplicacao (diretorios, arquivos, bancos de dados), tento não criar mock de coisas que eu mesmo vou implementar
[/code]

Interessante, pois a recomendação do Growing-Object-Oriented-Software-Guided-Tests é justamente mockar objetos de sua autoria somente, justamente, porque ao mockar APIs de terceiros, você não pode garantir o ccomportamento das mesmas. O mesmo vale para recursos como sistemas de arquivos, bancos etc. Ou seja, é o típico caso em que testes de integração podem funcionar melhor.

Veja, eu posso estar errado, mas qual o sentido de eu mockar minhas proprias implementacoes se eu posso simplesmente instancia-las e ter testes integrados? Claro, uma requisicao http quando estiver testando um controller ou um dao quando estiver testando um servido que obrigatoriamente usa acesso a banco voce mocka (ou o próprio servico quando for algo um pouco mais complexo), mas mockar minhas próprias implementacoes?

De qualquer forma eu não li o livro que voce citou como exemplo, então podemos estar usando exemplos em contextos diferentes. Já anotei aqui o nome do livro, já está na lista para ser lido.

Talvez o que o autor seja algo como foi postado neste http://www.guj.com.br/java/278717-tdd-x-baixo-acoplamento tópico em que o teste não testa nada alem do mockito.

Por exemplo, você tem uma classe X que representa um serviço, e quer testá-la unitariamente. A classe X por sua vez depende de um EntityDAO, porém, esse EntityDAO é uma interface (ou classe abstrata) com duas implementação JdbcEntityDAO e JpaEntityDAO. Você não quer usar as implementações reais pois o testes é unitário, você não quer conectar em um banco de dados. Nesse caso, você mocka o seu EntityDAO. Por sua vez, para testar as implementações do DAO você faz os testes de integração em separado, com um banco de dados reais, drivers reais, etc.

Nesse caso, você pode mockar seu EntityDAO tranquilamente, pois você pode garantir que todas as suas implementações cumprirão com o contrato declarado na interface, diferentemente de um EntityManager por exemplo, que pode apresentar diferenças de comportamento entre implementações diferentes ou mesm entre versões diferentes de provider.

Y

rmendes08:
YvGa:
rmendes08:

E enquanto isso eu os evitava a todo custo. Só uso mock quando preciso simular acesso a recurso externo a aplicacao (diretorios, arquivos, bancos de dados), tento não criar mock de coisas que eu mesmo vou implementar
[/code]

Interessante, pois a recomendação do Growing-Object-Oriented-Software-Guided-Tests é justamente mockar objetos de sua autoria somente, justamente, porque ao mockar APIs de terceiros, você não pode garantir o ccomportamento das mesmas. O mesmo vale para recursos como sistemas de arquivos, bancos etc. Ou seja, é o típico caso em que testes de integração podem funcionar melhor.

Veja, eu posso estar errado, mas qual o sentido de eu mockar minhas proprias implementacoes se eu posso simplesmente instancia-las e ter testes integrados? Claro, uma requisicao http quando estiver testando um controller ou um dao quando estiver testando um servido que obrigatoriamente usa acesso a banco voce mocka (ou o próprio servico quando for algo um pouco mais complexo), mas mockar minhas próprias implementacoes?

De qualquer forma eu não li o livro que voce citou como exemplo, então podemos estar usando exemplos em contextos diferentes. Já anotei aqui o nome do livro, já está na lista para ser lido.

Talvez o que o autor seja algo como foi postado neste http://www.guj.com.br/java/278717-tdd-x-baixo-acoplamento tópico em que o teste não testa nada alem do mockito.

Por exemplo, você tem uma classe X que representa um serviço, e quer testá-la unitariamente. A classe X por sua vez depende de um EntityDAO, porém, esse EntityDAO é uma interface (ou classe abstrata) com duas implementação JdbcEntityDAO e JpaEntityDAO. Você não quer usar as implementações reais pois o testes é unitário, você não quer conectar em um banco de dados. Nesse caso, você mocka o seu EntityDAO. Por sua vez, para testar as implementações do DAO você faz os testes de integração em separado, com um banco de dados reais, drivers reais, etc.

Nesse caso, você pode mockar seu EntityDAO tranquilamente, pois você pode garantir que todas as suas implementações cumprirão com o contrato declarado na interface, diferentemente de um EntityManager por exemplo, que pode apresentar diferenças de comportamento entre implementações diferentes ou mesm entre versões diferentes de provider.

Entendi, e concordo com isso. Apesar de muitas vezes, principalmente quando estou lidando com codigo legado sem testes, eu mockar diretamente um entityManager ou outras interfaces externas.

Mas o que eu quis dizer é que só uso mock quando preciso acessar recursos externos. Normalmente eu tambem prefiro simplificá-los com interfaces minhas.

O problema clássico que vejo no uso de mocks e usá-los onde não deviam estar. Por exemplo, suponha eu eu tenho um processo que lê diversos arquivo de um diretorio, os processa transformando em determinadas informacoes, com validações, processamento de regras de negocio e etc… e depois guarda o resultado do processamento em um banco de dados. O que já vi muito acontecer é a cada passo do processamento, o código acessa o sistema de arquivos, aplica as regras de negócio, e atualiza o banco de dados. E repete o clico n vezes.

E quando se vai por testes não há a preocupação em separar as responsabilidades, fica tudo emaranhado, com chamadas a daos e acesso a arquivos junto com chamadas a regras de negócio. E quando vão testar não separam nada, simplesmente mockam tudo e a salada continua.

Repare que em alguns casos como este, eu sequer precisaria de mock, porque o que eu preciso de fato testar são as regras de negócio que irão “incidir” sobre os dados que vem do arquivo e vão para o banco. Se eu quero testar as regras pouco me importa de onde vem e pra onde vao, o que me importa é que chegando ali vão obedecer o que está determinado pelo meu código. E é isso que eu preciso testar, se eu conseguir isolar este ponto num subsistema a parte eu não preciso de mocks.

R

É justamente esse o ponto da questão. Usar TDD/Mocks não exclui a necessidade de se conhecer os princípios de design OO.

Y

rmendes08:

E quando se vai por testes não há a preocupação em separar as responsabilidades, fica tudo emaranhado, com chamadas a daos e acesso a arquivos junto com chamadas a regras de negócio. E quando vão testar não separam nada, simplesmente mockam tudo e a salada continua.

É justamente esse o ponto da questão. Usar TDD/Mocks não exclui a necessidade de se conhecer os princípios de design OO.

Exatamente o que eu penso, só que muita gente acha que o problema está no TDD e não em seus fracos conhecimentos sobre OO. E muita gente mesmo, inclusive muita gente a favor da técnica.

Y

E a discussão continua, agora é a vez de David Heinemeier Hansson se rebelar contra o TDD.

Simplesmente o criador do Ruby on Rails.

http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html

Isso gerou uma série de discussões bastante interessantes em vídeo com o criador da técnica Kent Beck e um dos evangelizadores, Martin Fowler.

Curiosamente, ambos colocam um ponto discutido nesse tópico. Raramente usam mocks e “sugerem” que o uso excessivo deles indica um problema de design.

Excelente a discussão, muito dos pontos colocados pelo Heinemeier Hansson já foram apontados aqui pelo saoj.

J

Em relação a sistemas de informação o mais importante é automatizar os testes no nível mais alto, o funcional, usando Selenium por exemplo para o caso de aplicações web, o resto é querer brincar de TI.

A

algumas pessoas que acham justamente o contrário: quanto menos teste de UI, melhor.

Gostaria de ler suas razões para chegar a conclusão que teste unitário é brincadeira.

G

Gostaria de ler suas razões para chegar a conclusão que teste unitário é brincadeira.[/quote]
Vai dizer que você também não gosta de encerrar suas discussões com frases de impacto?

A

Haha… Tem uma galera que adora dar resposta de uma linha como se tivesse falando a verdade absoluta, sem justificações.

Geralmente ignoro respostas de usuários assim, mas geralmente não é o caso do javaflex.

Por isso achei que valia a pena discutir isso.

J

algumas pessoas que acham justamente o contrário: quanto menos teste de UI, melhor.

Gostaria de ler suas razões para chegar a conclusão que teste unitário é brincadeira.
Pelos testes funcionais cobrirem o que preciso. Normalmente saber diariamente se o sistema continua funcionando de verdade, e não um método ou sequência de métodos que não garantem se o que o usuário vai usar de fato funciona. O resto o time sempre se fala e se entende, o importante é não por em produção com problema. Pra mim o teste tem que abranger desde a digitação até o retorno do que foi gravado no banco está conforme o digitado originalmente. Nada adianta testes unitários ou integrados se algo no meio do caminho falhar por algum motivo, como por exemplo uma mensagem de validação não aparecer pro usuário conforme o esperado, por erro no javascript, ai você vai ter que fazer teste unitário do javascript também… Outro exemplo, o usuário não conseguir enviar o formulário para gravar o registro porque a nova versão do browser quebrou a versão do jquery usada. Então, quero testar o sistema de fato para o usuário seja lá o que tiver no meio do caminho. Já para quem produz bibliotecas para uso externo é super válido testes unitários, um projeto como o Hibernate por exemplo tem que ter. Eu já cheguei a fazer unitários, até que os funcionais evoluíram a ponto de não fazer sentido o unitário. Mas tudo bem se é válido para você e a maioria, pode ser que você passe por situações que precise do unitário, mas pra mim achei inútil.

TDD então nem se fala, eu parto do princípio de não lidar com problemas que não existem, senão é criado um obstáculo sem necessidade.

A

Ah, agora sim você apresentou seus motivos.

Primeiro uma observação: eu nunca sei qual a definição sendo usada para teste unitário, teste de integração ou teste funcional.
Pela sua descrição eu concluo que unitário é level de classe ou método isolado, funcional é usando o sistema com um agente externo (tipo Selenium) e integração não ficou claro. É isso?

Segundo, outra observação: eu li esse post quando foi lançado, mas agora que o Yvga reviveu com essa nova polêmica, não voltei pra ler tudo novamente. Conclusão: tudo que eu disser pode já ter sido dito.

Eu concordo com a importância dos testes funcionais, mas vejo dois problemas neles: eles são lentos e testam muita coisa de uma só vez.

Pra ter uma ampla cobertura de teste, sua suite inteira demora muito pra rodar (imaginar testar que cada validação javascript foi disparada, cada dado inválido filtrado, etc). E o pior, na minha opinião, quando um teste quebra você não consegue apontar imediatamente o que quebrou: pode ter sido o banco de dados fora do ar, o servidor de aplicação fora do ar, um erro de javascript, uma constraint no banco, um if errado no código backend, um timeout porque a página demorou um pouco mais pra carregar…enfim, para descobrir porque quebrou você gasta um enorme tempo investigando (isso quando não são testes que as vezes passam as vezes falham).

Eu gosto de testes unitários/isolados justamente para evitar esse tipo de coisa. Quando um teste unitário quebra, ele me diz exatamente em que ponto do código está o problema. E sendo rápido, eu posso rodar a cada alteração que faço no código.
Você pode acabar tendo certa redundância entre os funcionais e os unitários, mas eu ainda acredito que valha a pena, justamente pelo feedback rápido que temos do teste unitário.

J

AbelBueno:
Ah, agora sim você apresentou seus motivos.

Primeiro uma observação: eu nunca sei qual a definição sendo usada para teste unitário, teste de integração ou teste funcional.
Pela sua descrição eu concluo que unitário é level de classe ou método isolado, funcional é usando o sistema com um agente externo (tipo Selenium) e integração não ficou claro. É isso?

Segundo, outra observação: eu li esse post quando foi lançado, mas agora que o Yvga reviveu com essa nova polêmica, não voltei pra ler tudo novamente. Conclusão: tudo que eu disser pode já ter sido dito.

Eu concordo com a importância dos testes funcionais, mas vejo dois problemas neles: eles são lentos e testam muita coisa de uma só vez.

Pra ter uma ampla cobertura de teste, sua suite inteira demora muito pra rodar (imaginar testar que cada validação javascript foi disparada, cada dado inválido filtrado, etc). E o pior, na minha opinião, quando um teste quebra você não consegue apontar imediatamente o que quebrou: pode ter sido o banco de dados fora do ar, o servidor de aplicação fora do ar, um erro de javascript, uma constraint no banco, um if errado no código backend, um timeout porque a página demorou um pouco mais pra carregar…enfim, para descobrir porque quebrou você gasta um enorme tempo investigando (isso quando não são testes que as vezes passam as vezes falham).

Eu gosto de testes unitários/isolados justamente para evitar esse tipo de coisa. Quando um teste unitário quebra, ele me diz exatamente em que ponto do código está o problema. E sendo rápido, eu posso rodar a cada alteração que faço no código.
Você pode acabar tendo certa redundância entre os funcionais e os unitários, mas eu ainda acredito que valha a pena, justamente pelo feedback rápido que temos do teste unitário.


Você pode rodar vários testes funcionais em paralelo com selenium grid. Mesmo assim concordo que os unitários são infinitamente mais rápidos, só que independente de ser rápido não me dá uma garantia razoável para por em produção, que é o que me importa, pelos n motivos que comentei, já o dia a dia de desenvolvimento flui naturalmente, onde não existe “problema” para motivar automatizar um “policiamento do desenvolvimento durante o dia todo do que não é para liberar para produção ainda”, as vezes os problemas são outros como saoj já falava antes de todos nós aqui lá em 2012.

Sobre achar difícil detectar o problema, não é bem assim não saber imediatamente onde quebrou. Por exemplo supondo que teste funcional “Gravar Pedido” retornou “ORA-01722: invalid number”, o erro vai ser pontual na maioria dos casos. Resolvendo naturalmente como qualquer erro que pegamos, executando em debug e quando der erro vai parar e resolvemos pontualmente, não tem nada de ruim nisso, o importante é que o teste detectou que houve tela impactada e qual foi o erro para poder resolver em tempo de desenvolvimento tranquilamente, não sendo pego de surpreso em produção por algo místico que os testes unitários podem não pegar.

Sobre definição de cada tipo de teste, também me confundo e nem ligo pra isso, importante é a prática, só sei que uso “o que simula o uso real do usuário”, que muitos podem chamar também de teste de integração. Mas o “integrado” que eu me referia no post anterior não era o “funcional”, era um nível a mais que o unitário, ao invés de testar um método isolado com código fake, chamar um método real, que pode chamar outro com dependências, como por exemplo testar começando da controller até chegar à persistência.

Y

javaflex:
AbelBueno:
Ah, agora sim você apresentou seus motivos.

Primeiro uma observação: eu nunca sei qual a definição sendo usada para teste unitário, teste de integração ou teste funcional.
Pela sua descrição eu concluo que unitário é level de classe ou método isolado, funcional é usando o sistema com um agente externo (tipo Selenium) e integração não ficou claro. É isso?

Segundo, outra observação: eu li esse post quando foi lançado, mas agora que o Yvga reviveu com essa nova polêmica, não voltei pra ler tudo novamente. Conclusão: tudo que eu disser pode já ter sido dito.

Eu concordo com a importância dos testes funcionais, mas vejo dois problemas neles: eles são lentos e testam muita coisa de uma só vez.

Pra ter uma ampla cobertura de teste, sua suite inteira demora muito pra rodar (imaginar testar que cada validação javascript foi disparada, cada dado inválido filtrado, etc). E o pior, na minha opinião, quando um teste quebra você não consegue apontar imediatamente o que quebrou: pode ter sido o banco de dados fora do ar, o servidor de aplicação fora do ar, um erro de javascript, uma constraint no banco, um if errado no código backend, um timeout porque a página demorou um pouco mais pra carregar…enfim, para descobrir porque quebrou você gasta um enorme tempo investigando (isso quando não são testes que as vezes passam as vezes falham).

Eu gosto de testes unitários/isolados justamente para evitar esse tipo de coisa. Quando um teste unitário quebra, ele me diz exatamente em que ponto do código está o problema. E sendo rápido, eu posso rodar a cada alteração que faço no código.
Você pode acabar tendo certa redundância entre os funcionais e os unitários, mas eu ainda acredito que valha a pena, justamente pelo feedback rápido que temos do teste unitário.


Você pode rodar vários testes funcionais em paralelo com selenium grid. Mesmo assim concordo que os unitários são infinitamente mais rápidos, só que independente de ser rápido não me dá uma garantia razoável para por em produção, que é o que me importa, pelos n motivos que comentei, já o dia a dia de desenvolvimento flui naturalmente, onde não existe “problema” para motivar automatizar um “policiamento do desenvolvimento durante o dia todo do que não é para liberar para produção ainda”, as vezes os problemas são outros como saoj já falava antes de todos nós aqui lá em 2012.

Sobre achar difícil detectar o problema, não é bem assim não saber imediatamente onde quebrou. Por exemplo supondo que teste funcional “Gravar Pedido” retornou “ORA-01722: invalid number”, o erro vai ser pontual na maioria dos casos. Resolvendo naturalmente como qualquer erro que pegamos, executando em debug e quando der erro vai parar e resolvemos pontualmente, não tem nada de ruim nisso, o importante é que o teste detectou que houve tela impactada e qual foi o erro para poder resolver em tempo de desenvolvimento tranquilamente, não sendo pego de surpreso em produção por algo místico que os testes unitários podem não pegar.

Sobre definição de cada tipo de teste, também me confundo e nem ligo pra isso, importante é a prática, só sei que uso “o que simula o uso real do usuário”, que muitos podem chamar também de teste de integração. Mas o “integrado” que eu me referia no post anterior não era o “funcional”, era um nível a mais que o unitário, ao invés de testar um método isolado com código fake, chamar um método real, que pode chamar outro com dependências, como por exemplo testar começando da controller até chegar à persistência.

O importante, como diz o Kent Beck na discussão é sentir confiança no código que você escreve. Se você atingiu isso, independente da forma que for, e essa confiança se reflete efetivamente na qualidade do código que você põe em produção então você está fazendo certo, seja lá a técnica que usa.

Eu, particularmente, gosto muito do TDD, como eu nunca gostei dos mocks, o próprio TDD me forçou melhorar as responsabilidades do meu código antes de conseguir testar, eu testo regra. Se chega x tem que sair y, não me importa de onde vem x, nem pra onde vai y.

Quanto ao Selenium eu não consegui me adaptar, achei muito complexo e no final você acaba testando poucos cenários. Talvez seja um problema meu de não ter achado o jeito certo de usar a ferramenta, mas não consegui me acertar com ele ainda.

J

YvGa:
javaflex:
AbelBueno:
Ah, agora sim você apresentou seus motivos.

Primeiro uma observação: eu nunca sei qual a definição sendo usada para teste unitário, teste de integração ou teste funcional.
Pela sua descrição eu concluo que unitário é level de classe ou método isolado, funcional é usando o sistema com um agente externo (tipo Selenium) e integração não ficou claro. É isso?

Segundo, outra observação: eu li esse post quando foi lançado, mas agora que o Yvga reviveu com essa nova polêmica, não voltei pra ler tudo novamente. Conclusão: tudo que eu disser pode já ter sido dito.

Eu concordo com a importância dos testes funcionais, mas vejo dois problemas neles: eles são lentos e testam muita coisa de uma só vez.

Pra ter uma ampla cobertura de teste, sua suite inteira demora muito pra rodar (imaginar testar que cada validação javascript foi disparada, cada dado inválido filtrado, etc). E o pior, na minha opinião, quando um teste quebra você não consegue apontar imediatamente o que quebrou: pode ter sido o banco de dados fora do ar, o servidor de aplicação fora do ar, um erro de javascript, uma constraint no banco, um if errado no código backend, um timeout porque a página demorou um pouco mais pra carregar…enfim, para descobrir porque quebrou você gasta um enorme tempo investigando (isso quando não são testes que as vezes passam as vezes falham).

Eu gosto de testes unitários/isolados justamente para evitar esse tipo de coisa. Quando um teste unitário quebra, ele me diz exatamente em que ponto do código está o problema. E sendo rápido, eu posso rodar a cada alteração que faço no código.
Você pode acabar tendo certa redundância entre os funcionais e os unitários, mas eu ainda acredito que valha a pena, justamente pelo feedback rápido que temos do teste unitário.


Você pode rodar vários testes funcionais em paralelo com selenium grid. Mesmo assim concordo que os unitários são infinitamente mais rápidos, só que independente de ser rápido não me dá uma garantia razoável para por em produção, que é o que me importa, pelos n motivos que comentei, já o dia a dia de desenvolvimento flui naturalmente, onde não existe “problema” para motivar automatizar um “policiamento do desenvolvimento durante o dia todo do que não é para liberar para produção ainda”, as vezes os problemas são outros como saoj já falava antes de todos nós aqui lá em 2012.

Sobre achar difícil detectar o problema, não é bem assim não saber imediatamente onde quebrou. Por exemplo supondo que teste funcional “Gravar Pedido” retornou “ORA-01722: invalid number”, o erro vai ser pontual na maioria dos casos. Resolvendo naturalmente como qualquer erro que pegamos, executando em debug e quando der erro vai parar e resolvemos pontualmente, não tem nada de ruim nisso, o importante é que o teste detectou que houve tela impactada e qual foi o erro para poder resolver em tempo de desenvolvimento tranquilamente, não sendo pego de surpreso em produção por algo místico que os testes unitários podem não pegar.

Sobre definição de cada tipo de teste, também me confundo e nem ligo pra isso, importante é a prática, só sei que uso “o que simula o uso real do usuário”, que muitos podem chamar também de teste de integração. Mas o “integrado” que eu me referia no post anterior não era o “funcional”, era um nível a mais que o unitário, ao invés de testar um método isolado com código fake, chamar um método real, que pode chamar outro com dependências, como por exemplo testar começando da controller até chegar à persistência.

O importante, como diz o Kent Beck na discussão é sentir confiança no código que você escreve. Se você atingiu isso, independente da forma que for, e essa confiança se reflete efetivamente na qualidade do código que você põe em produção então você está fazendo certo, seja lá a técnica que usa.

Eu, particularmente, gosto muito do TDD, como eu nunca gostei dos mocks, o próprio TDD me forçou melhorar as responsabilidades do meu código antes de conseguir testar, eu testo regra. Se chega x tem que sair y, não me importa de onde vem x, nem pra onde vai y.

Quanto ao Selenium eu não consegui me adaptar, achei muito complexo e no final você acaba testando poucos cenários. Talvez seja um problema meu de não ter achado o jeito certo de usar a ferramenta, mas não consegui me acertar com ele ainda.


Exatamente, confiança no código, entrosamento do time e buscar parceria com o cliente. É por ai mesmo o melhor caminho para não precisar que as “siglas” resolvam os problemas.

Regra testo no Selenium mesmo, o teste executa as entradas inválidas e espera que a mensagem de validação seja exibida na tela, e depois executa as entradas válidas esperando a gravação retornar sucesso. Sei que TDD o propósito é outro, de já começar testando o que está fazendo imediatamente, mas exatamente isso que acho desmotivante. A empolgação pra começar a criar a tela de fato e ir conversando com o cliente mostrando prévias acaba compensando as vantagens vendidas pelo TDD. É muito complexo sim chegar numa infraestrutura para teste via selenium webdriver que facilite as coisas para a equipe, é um grande investimento que depois traz lucros, o importante é ir atacando aos poucos cada tipo de funcionalidade.

Criado 18 de julho de 2012
Ultima resposta 3 de jul. de 2014
Respostas 90
Participantes 18