Testes de Unidade são realmente nescessários?

É uma discussão no estilo mac x windows ou linux x windows.
Você faz por achar certo. Eu faço, a empresa me obriga. Outros não fazem por não serem solicitados e assim vai.
Agora, se formos discutir como seria a melhor forma de implementar um modelo de testes em um ambiente corporativo que peca em todos os aspectos, aí sim, eu acho produtivo.

1 curtida

Acho que para discutir profissionalismo de alguém baseado no uso ou nao de testes, esse argumento deveria ser baseado em fatos(pesquisas realizadas com projetos reais) e nao em opiniao, experiência pessoal ou apelo a autoridade.

Eu gosto de testes unitários (e de linguagens estáticas), pois sinto que os dois me dao mais segurança. Porém isso é uma opiniao que nao vou impor como verdade a todos, e nem dizer que o mercado é ruim por falta de um ou outro.

2 curtidas

Então pessoal, vou deixar meu feedback sobre testes.
Tenho 12 anos de experiencia em desenvolvimento, trabalho com várias linguagens.
Quando conheci os testes de unidades, testes e integração e tudo mais, acreditava que isso se travada uma tremenda baboseira e não dei importância.
Algum tempo depois, me deparei com uma questão em que, o sistema ficou tão grande que, era alterar alguma coisa e, com certeza alguma outra quebraria. Era certeza isso!
Então, comecei a escrever testes para pegar esses problemas e, vi que os testes me ajudaram a garantir a qualidade do sistema. Garantir que, ao colocar alguma coisa em produção, os testes me davam um feedback e segurança de dizer com peito estufado “o sistema ta no ar”.
Mesmo em sistemas pequenos é primordial fazer testes. Digo isso pois, sistemas pequenos podem crescer e se tornar um frankenstein sem controle.
Em resumo: testes darão certeza de que o software desenvolvido estará funcional da forma como é esperado.
Ferramentas
Uso algumas ferramentas. No Eclipse uso Coverage para obter feedback de quanto o código está coberto por testes.
Também uso um plugin Coverage no Jenkins para dar um feedback para equipe de quanto o código está coberto por testes.
E, ainda é possível escrever métricas para impedir o build de um código caso ele não atenda uma métrica estabelecida. Ex.: posso dizer ao Jenkins que invalide uma build caso o código esteja com menos de 80% de cobertura de testes.
Tenho um lema: não abra mão da qualidade

O ambiente de produção existe independente se a pessoa escreve teste primeiro ou depois.

Headbanging-drive design?

A questão não é quantas soluções o programador é capaz de pensar, mas qual que efetivamente separa a parte stateful (não-testavel) da parte stateless (testável).

@romero.dias, muito bonito teu testemunho.
Quando entrei na empresa onde hoje trabalho, há 3 anos atrás, me disseram que um dos pilares era qualidade. Que se abria mão de tudo, exceto da qualidade.
Três anos depois e eu digo que ninguém nunca prezou pela qualidade aqui. Ou o conceito de qualidade que aqui se tem é: funcionou, tá valendo.
Como o pessoal tem falado aí, muito mais de cada um do que “requisito de mercado”. Difícil o gestor que tenha maturidade para entender quão necessário é perder um tempo para garantir a qualidade (e garantir que os testes são efetivos).

Em ambientes corporativos é mais comum o teste do sistema completo, geralmente feito por humanos.

Com relação a testes unitários, pra que facilitar o entendimento do sistema pra quem esta chegando agora de fora? :wink:

Isso se encaixa em documentação, também.

@Luis_Augusto_Santos eu entendo que isso define quem é: Junior/Pleno/Sênior/Arquiteto. Após alguns anos surrando código vemos o que realmente importa. Não adianta fazer (go horse) o código funcionar e, algum tempo depois o cliente descobrir um bug por quebra de código legado.

@romero.dias, acho que isso define um desenvolvedor/analista preocupado com o que faz, não o seu nível de conhecimento. Alguns sabem todo o funcionamento das implementações e as regras das especificações java, mas fogem de testes unitários como o demo foge da crucis.

@Luis_Augusto_Santos conhecimento todos tem, porem existe a responsabilidade de aplicar esse conhecimento, isso é o que diferencia. Quem faz a diferença é quem coloca em prática, acompanha e monstra os resultados.

A responsabilidade é de todos. Cabe sim, a quem tem mais experiência, ensinar a quem não tem os meios mais adequados.
Aí voltamos ao que eu já disse: problemas na base, no ensino. Em qual faculdade/curso/etc você é ensinado a testar? Eu tive dois módulos de engenharia de software na faculdade. E lembro que tive três aulas de testes (caixa preta, caixa branca, cocoon e mais uns conceitos). De que isso adianta?
No meu TCC, isso nem foi cobrado (até por que, se fosse, eu teria reprovado).
Ou seja, professores não dão a mínima para os testes (amostragem em universo pessoal).

Isso ai! Eu costumo dizer: “Conhecimento bom é conhecimento disseminado”.
As faculdades não preparam o aluno para o mercado de trabalho, para as boa práticas de engenharia de software, etc…

Cara, que bons tempos o GUJ parece estar revivendo. Enfim, teve um tempo atrás onde uma conversa desse nipe já teria descambado para agressões pessoais e coisinhas sem sentido sem nenhum tipo de argumento. Coisas do tipo “bobo, feio e mal” mesmo… Kkkkkkkkkkkk

Já que assim não foi, todos mantiveram o nível e elevaram a discussão, vou me intrometer em algo que não entendo em sua plenitude, mas que acho que posso contribuir, devido aos meus 14 anos de mercado na fuça.

Já tentei estudar TDD por conta e em alguns cursos (que se mostraram bem fracos) durante os meus últimos 8 anos e sempre esbarro em algumas “coisitas” que espero assim colaborar com a discussão e quem sabe arranjar um “professor/tutor” no caminho.

Uma delas é código extremamente legado em produção com framework absurdamente antigo, classes com mais de 9.000 linhas de código (isso mesmo, 9K) e urgências pra ontem em produção. Tudo isso mais uma timeline agressiva em algumas outras situações sempre me fizeram deixar os testes automatizados pra “depois” no trampo atual.

Porém, uma coisa que levo comigo é sempre olhar para as referências em tudo o que pretendo fazer na minha vida e olhar o que eles estão fazendo. Cara, Martin Fowler com certeza é um desses caras e esse cara simplesmente me diz que testar é importante… Não, mais do que isso, é primordial, essencial, preciso, necessário… caras, eu com certeza levo isso muito a sério e por muito tempo o fato de não fazer os testes realmente me consumiu… Como eu me achava um bosta completo por meu código não ser coberto pelos testes… Aí todo um movimento do mercado e tals e eu sempre me sentindo pra trás.

Só que aí algumas coisas aconteceram e percebi que já tinha alguns softwares entrando em produção, gerando valor e até hoje estão lá com poucas manutenções traumáticas, uma qualidade que eu garanto (já que outra pessoa fez manutenções em tempo razoável) e eu meio que aceitei que eu tinha um buraco pra corrigir na minha carreira, afinal, ainda precisava aprender sobre testes automáticos, mas já não me achava tão bosta assim, afinal tinha sistema no ar gerando valor pra alguém e isso é minha métrica fundamental. Mas ok, minha busca continuou e eu precisava entender que se o sistema estava agregando valor sem testes, o que dizer se ele estivesse coberto por testes? Quão melhor não seria?

Foi quando achei alguém que veio trabalhar conosco que já tinha implementado testes em sua empresa anterior (sem nomes, pois não tenho autorização da pessoa pra isso)… Esse cara vendeu a ideia pra chefia, já que pra mim não era necessário, afinal eu já comprei a ideia e era/é uma meta na minha carreira profissional.

O fato é que eu enxerguei a luz no fim do túnel e o projeto de cobrir nossos Sistemas por testes automáticos estava saindo do papel.

Pra minha frustração 1 mês depois o cara simplesmente desistiu do processo, pois a nossa base de código tinha alguns empecilhos para que os testes fossem confiáveis (nunca entendi bem porque, exatamente por não conhecer a técnica) e ele desistiu saindo da empresa um tempo depois. Um outro colega que hoje trabalha com a gente e que também já trabalhou em uma empresa que cobria seus códigos com testes, simplesmente disse que precisaremos de um tempo para conseguir implantar a coisa da forma correta e que a quantidade de refactor que essa escrita de testes vai trazer, ele tem quase certeza que será impagável (ou seja, ninguém vai bancar $$ a alteração).

Enfim, no final das contas, ainda tenho alguns projetos pessoais que vou usando algumas coisas que acredito serem testes automatizados e me ajudam em alguns momentos, mas algumas coisas que faço (principalmente unitários) simplesmente não consigo enxergar valor nenhum na ponta final.

Como disse, meu problema hoje pode ser eu mesmo… Confesso que ainda não desenvolvo orientado por testes, pois ainda não sei COMO fazer isso, e as pessoas que já me disseram que o fazem no final das contas nunca conseguiram responder algumas de minhas perguntas práticas sobre nossos problemas da vida real. Como estamos com uma arquitetura nova na empresa, estamos nascendo ela já com os testes e em breve faremos uma rodada de validação com o time pra trocar ideia do valor que a prática nos trouxe e eu preciso me lembrar de voltar nesses posts e opinar.

É isso, se alguém quiser me ajudar no processo de aprendizagem, ficaria muito grato, mas ajuda seria pra me mostrar um problema real que foi resolvido com a cobertura de testes exemplificando situações que seriam desastrosas que os testes simplesmente evitaram essas situações em código real em produção. De preferência como o colega colocou aí cima, em uma base de código onde o prazo foi agressivo (não abusivo para a situação), o banco relacional não normalizado por um DBA que nem te conhece e as vezes te odeia e um código de 2005-2006 com um framework antigo e com features duvidosas.

O pedido é sério e garanto que o objetivo do post NÃO É (eu sei que pode parecer) desmerecer os testes automatizados. Eu realmente quero aprender na prática, não apenas na teoria, onde estou errando e o que não estou enxergando. Talvez meu bloqueio seja exatamente tentar resolver o passado com testes quando eu deveria estar me focando apenas em produtos que estão nascendo.

Talvez o bloqueio seja a desmotivação de não conseguir cobrir o passado com testes automáticos (pelo menos me parece bem mais difícil o fazer em código já antigo e mal escrito no legado) e me frustrar achando que não irei conseguir. Confesso, isso já me fez colocar a técnica em cheque, hoje não mais.

Por hora, apenas peço que realmente acabem esse discurso de que quem não pratica TDD é um BOSTA total e todos os que praticam são os profissionais que valem a pena… Acho que na prática, o que vale mesmo é software que na ponta o usuário esteja usando e tendo valor agregado, quer ele seja coberto por testes ou não…

REPITO, é importante, NÃO ESTOU desmerecendo testes automatizados, só quero mesmo entendê-los e, o quanto antes, usá-los em meus projetos.

Abraços a todos e obrigado pelo alto nível do papo :wink:

Sim.

@adriano_si realmente é muito mais difícil escrever testes em projeto legado que não tem testes, por isso que alguns na thread disseram sobre o benefício em escrever testes desde o princípio de um projeto (principalmente test-driven), pra evitar esse tipo de problema no futuro.

Mas em momento algum foi dito (ou até mesmo insinuado) que quem não escreve teste é um b*sta e só quem faz teste é valorizado. Na verdade foi apenas mostrado com experiências pessoais a importância de desenvolver test-driven, só isso. Nem todos pensam assim e isso é normal, afinal, de acordo com aquele velho clichê, muito comum por sinal aqui no GUJ: não existe bala de prata.

Num sistema legado, como não temos como voltar no passado :stuck_out_tongue:, o que resta é não escrever teste algum ou escrever testes quando for adicionar funcionalidade. Por exemplo, em projetos legados com muito código difícil de ser testado, eu costumo escrever testes apenas nos pontos onde vou adicionar feature ou corrigir um bug. Ao corrigir um bug, escrevo o teste que reproduz o bug (com os cenarios que forem necessarios no momento), e meu trabalho se resume em fazer o(s) teste(s) passar(em).

Obviamente podemos esquecer alguns cenários (nunca dá pra pensar em todos 100%), mas dessa forma já cobre bem alguns aspectos. Ao mexer numa classe que não tem teste, o que faço é escrever o teste para aquela classe apenas referente a feature/bug que estou trabalhando, não cobrindo as demais funcionalidades da classe, a não ser que outra funcionalidade externa seja dependência da que estou trabalhando. Posso não estar fazendo 100% correto, alguns TDDers que levam by the book podem não concordar comigo, mas é assim que tenho feito :smiley:

Eu citei apenas como eu faço com os unitários, sem contar que também nesse conta coloco teste de UI (ou aceitação, por exemplo Cucumber) e integração (chamada de controller, output across componentes, API’s).

EDIT:
Ah, sobre os testes de UI, nem sempre os faço, acabo analisando de acordo com a story que vou trabalhar. Se faz sentido, escrevo um cenario happy path no Cucumber e vou “descendo” no modo test-driven em integração e unitarios mas cobrindo mais cenarios de acordo com a especificação. Em alguns casos, eu me lembro de algum cenario que nao foi previsto e depois adiciono na especificação, mas é mais comum eu não lembrar. Quando estou fazendo pair-programming já é mais fácil pensar em mais cenarios, afinal são 2 pessoas pensando no problema.

Os testes de UI são muito caros, eu sempre tento discutir se são mesmo necessários pra determinada feature/bug a ser trabalhado. TDDers vão me matar kkkkk

Bom meu ponto anterior foi justamente por esse lado. Você talvez por ser o que tem costume de trabalhar, etc, acha que UI é secundário.

Mas isso no geral não é assim, é o que o usuário vê, pro usuário seu sistema pode ser perfeito por dentro mas se não atender o jeito que ele vai usar, ele simplesmente não vai comprar.

Interface com usuário ainda é mais critico quando o que você desenvolve é baseado em interação e a experiência do usuário como é o caso de desenvolver bibliotecas de UI (se não testar UI nesse caso, vai testar o que? hahah), coisas envolvendo gráficos, entrada do usuário, e que muitas vezes tem um aspecto subjetivo e estético.

Como falei há casos em que não só é caro, como é praticamente impossível testar de forma automatizada pelo fato de que bolar o teste em si não é trivial. Por isso minha conclusão é que TDD e BDD não atendem todos os casos, como querem prometer que fazem.

1 curtida

Escrever testes automatizados é muito caro pra quem trabalha com OO porque a maior parte do código é statefull, assim como a UI, e não pode ser testado de maneira confiável.

1 curtida

Não acho UI secundário de todo, mas existem features que podem ser testadas de forma mais barata utilizando outros métodos de teste. É questão de avaliar cada caso. Eu não disse em nenhum ponto desta thread que não testo UI at all.

Sim, isso é óbvio. Ninguém compra (ou ao menos não deveria comprar) algo que não atende as expectativas.

Com razão. Há casos que o custo de automatizar algo é muito alto, tem que avaliar alternativas mais baratas.

Pra testar um sistema stateful é fácil, vc o coloca num estado inicial e executa os testes desejados usando os parametros de entrada.

Depois é só rezar para os testes executem da mesma forma, toda vez para os mesmos parametros de entrada, e algum estado interno escondido não faz com que uma sequencia de eventos de entrada coloque o sistema num estado ruim, pq senão aí lascou :confused:

Isso é fato. Cada empresa tem seu cenário, geralmente em fábrica/consultoria, pela rotatividade de jovens, tem mais preocupação com teste do código que os próprios programadores usam, do que a funcionalidade para o usuário final. O ritmo desse ambiente exige diversas siglas para o desenvolvimento não virar o caos, além de se preocuparem mais em prever situações por não ter o feedback natural do cliente, diferente quando se está diretamente na atividade fim, onde você já faz parte do negócio. Claro que isso não é regra, tem empresas de TI que são pagas para se preocupar em manter a qualidade do que de fato vai ser usado.