Testes unitários / Mocks são realmente necessários?

46 respostas
R

Bill Burke fez um barulho no post sobre JavaEE X Spring, mas o que muitas pessoas não notaram é que teve uma discussão intensa nos comentários
sobre a necessidade de se fazer testes unitários.

Uma das opiniões dos leitores, que Bill Burke disse concordar completamente, é essa

“…Test in the real environment and get results that are truly valid. Stop kidding yourself with mocks…”

A discussão foi tão grande, que ele acabou de lançar um post sobre mocks!

No post ele volta a discutir a necessidade de teste unitário e integração.

E o que você acha? Vale a pena investir em testes unitários ou ficar só com testes de integração e fazer o uso de ferramentas como o Arquillian?

46 Respostas

I

Vix, este topico vai gerar mta discussao :slight_smile:

Mas com certeza TUDO a favor de testes unitarios.

Cara, eu nao sei mais o que é desenvolver sem escrever pelo menos um teste com cenario ideal pra aquela funcao. Imagina toda vez que for gerar uma release, vc ter que ficar fazendo TODOS os testes funcionais, passando por todas as telas e todas as funcionalidades? Ai de repente acha um erro (nunca acha erros né? rs) e tem que fazer os testes tudo de novo, para ver se essa solucao nao quebrou nada.

Inumeras vezes meus testes e de outras pessoas foram quebrados, por coisas que eu nao tinha nem nocao que podia quebrar. Imagina se vc, em um projeto JEE, usa maven e jboss, ai toda vez que fizer uma alteracao, vc tem que recompilar o projeto pelo maven e subir o jboss pra testar apenas uma funcionalidade. Bem mais rápido vc escrever um teste unitário (que ficara pra sempre no projeto) e rodar pra ver se realmente funciona.

Imagina chega um estagiario novo, e faz alteracao em um ENUM, colocando um registro no meio, e no sistema, tinha outro estagiario (que ja saiu da empresa) que fez a funcionalidade pelo ordinal do enum. Aparentemente está OK, depois de 1 ano, vc ve que o sistema tava salvando tudo errado. Mas e agora? E pra saber desde quando o sistema está gravando errado? Pensa no tempo e no custo que isso vai custar ao projeto.

Testes unitarios é totalmente necessário para um desenvolvimento de software. Nao estou falando isso porque li a respeito, mas sim porque vi a diferenca e a necessidade na prática.

O ideal é no momento que estiver criando o projeto, nao passar pra outra camada sem escrever testes unitarios pra ele antes. Pq se vc for fazer todo o sistema, pra depois comecar a escrever os testes, “nao vai dar tempo” de escrever, e vai acabar ficando com menos prioridade.

X

Testes Unitários são independentes dos testes de integração assim como estes são independentes de dos testes de aceitação.

Testes unitários podem ser vistos como uma forma de projeto, aplicando TDD ou simplesmente de garantir que uma pequena parte do sistema funcione.

A industria faz isso a banstante tempo utilizando-se de Pokas-Yokes para garantir que parte da montagem das peças que compõem um produto não não sejam feitas de maneira inadequada. Isso não elemina os testes finais com o produto acabado mas evita grandes problemas como danos ao produto ou ter que desmontar todo um produto para corrigir um problema e pode evitar que um problema seja encotrado só no cliente.

Para nós o problema de só fazer testes de integração ou aceitação é que alguns problemas podem passar se só ser pegos em produção e mesmo que seja encontrado uma falha nesses testes demora-se muito mais para corrigi-los do que desenvolver um teste um unitário.

Testes unitários também facilitam a refatoração, pois dão um feedback rápido para o programador sobre as mudanças efetuadas.

A

Os testes unitários são importantes tanto quanto os outros, pois erros encontrados nas fases preliminares são bem mais rápidos de serem corrigidos do que os somente descobertos na fase de aceitação, por exemplo. Ainda, acredito não ser útil/necessário fazer mocks para todos os processos, pois é dispendido um tempo a mais somente para fazê-los.

H

Não entendo essa idéia de que existe uma regra geral sobre quais testes fazer, quais deixar de lado.

Testes são uma ferramenta e como tal deve ser usado conforme o caso.

Se você não sabe o melhor para o seu caso não vai ser um blogueiro na net que vai saber.

H

Quando possível eu gosto de utilizar objeto real. Para teste de DAO por exemplo, eu gosto de utilizar HSQLD. O DAO irá se comportar como realmente deve.

Agora, se você tem uma classe que faz cobrança de cartão de crédito a um cliente… como você vai fazer se não tiver um mock? Ou algum simulador?

Acho necessário sim o mock, mas não para todas as situações.

L

É como este mesmo pensamento que testes são perca de tempo e a coisa é desenvolver, eu já vi muita mas muita merda mesmo acontecendo, dai o tempo para achar a merda e corrigir é bem maior do que se o cara tivesse perdido um tempinho nos testes unitários e mocks…

Em questão de software tem que se levar Murph a serio, se não meu amigo vc ta f*****.

D

Provavelmente a maioria das pessoas que acha testes unitários desnecessários é a maioria que considera análise e design de um sistema como algo totalmente fútil. Documentação, então, nem se fala. Já pensaram em uma especificação de caso de uso sem fluxos alternativos ou de exceção?
Eu sou sincero em falar que acho testes um saco, porém, admito que sem eles é impossível garantir qualidade no produto que se desenvolve.
Nenhum software está 100% testado, pois por mais que se pense em 200 possibilidades diferentes, pode ocorrer a 201ª e tudo ir por água abaixo.
São riscos, mas, quanto mais testes realizados, menores eles são.
E isso inclui os testes unitários.

W

Não imagino mais meu mundo sem mocks ou teste unitários :slight_smile:

A

+1

M

Eu também penso assim, mas sempre evitando o uso excessivo de mocks, preferindo sempre um objeto com comportamentos reais.

F

Testes de unidade são importantes para garantir regras de negócio com maior corretude. Então tem de tomar cuidado pra não sair criando testes para toda e qualquer classe do sistema; testes de unidade tem custo e devem ser utilizados em classes que tem maior prioridade para serem testadas (classes de maior valor do ponto de vista de negócio).
O problema que tem muito desenvolvedor que considera todos os métodos do sistema uma unidade de teste.

W

AlexandreGama:

Não imagino mais meu mundo sem mocks ou teste unitários

+1

Trabalhei em um lugar em que aprendi a automatizar os testes de integração (eles não faziam automação de testes unitários, mas não impediam você de fazer), achava fantástico a segurança que ele dava em mudanças futuras e ao mesmo tempo entendia que a cada teste criado, seria mais um código a manter, o que se não fosse feito adequadamente seria apenas mais um ponto crítico do que uma ajuda. Até ai tudo bem, peguei o ritmo e chegamos ao ponto de ter no mímino 80% de cobertura de testes, e testes com finalidades concretas que ajudavam… Não era TDD mas ainda em certos momentos ajudava até mesmo no design da aplicação.

O problema, é que depois que sai de la, nunca mais achei em outro ambiente interesse em automação de testes, e nos lugares que tentei fazer eu senti até uma marginalização por parte dos demais. Até certo ponto entendi, por que o tipo de sistema desenvolvido por essa empresa, era menor e com ciclo de vida bem menor (durava 3, 4 meses no máximo), mas agora estou em outra empresa que tem um produto que deve durar anos, e que será o carro chefe da empresa, está em fase final de desenvolvimento, e nada foi construído baseado em testes, ou com algum suporte para isso. Temos apenas um ou outro aventureiro que tenta escrever algo que ele ache util em algum momento, mas não é a regra. Nesse caso, o projeto que já está atrasado, e muito. Parece ser muito frágil quanto a mudanças, é fácil perceber que se em certo ponto alguém adicionar algo, pode quebrar outros pontos. Como entrei com o projeto andando, confesso que tenho medo de alterar partes do sistema (Aqui lembro do XGH) sem a segurança que tinha antes.

Quanto ao TDD e uso de mocks em si, eu não usei tão fortemente, mas eles devem ser muito uteis em caso que vc dependa de algo que ainda não tenha acesso, ou ainda para evitar o carregamento de uma série de coisas que não seriam interessantes apenas para validar uma lógica.

H

drsmachado:
Provavelmente a maioria das pessoas que acha testes unitários desnecessários é a maioria que considera análise e design de um sistema como algo totalmente fútil. Documentação, então, nem se fala. Já pensaram em uma especificação de caso de uso sem fluxos alternativos ou de exceção?
Eu sou sincero em falar que acho testes um saco, porém, admito que sem eles é impossível garantir qualidade no produto que se desenvolve.
Nenhum software está 100% testado, pois por mais que se pense em 200 possibilidades diferentes, pode ocorrer a 201ª e tudo ir por água abaixo.
São riscos, mas, quanto mais testes realizados, menores eles são.
E isso inclui os testes unitários.

A idéia de que testes unitários servem para criar software infalível (qualidade é quando o software é entregue no prazo e fazendo apenas o que o cliente pediu) é discutível já que esses testes são escritos por pessoas, e estes estão sujeitos a falha ou má compreensão do problema.

Pra mim testes servem mais como documentação, e como tal podem ser úteis, principalmente em ambientes com alta taxa de rotatividade de progamadores.

T

jakefrog:
Quando possível eu gosto de utilizar objeto real. Para teste de DAO por exemplo, eu gosto de utilizar HSQLD. O DAO irá se comportar como realmente deve.

Agora, se você tem uma classe que faz cobrança de cartão de crédito a um cliente… como você vai fazer se não tiver um mock? Ou algum simulador?

Acho necessário sim o mock, mas não para todas as situações.

A operadora de cartão fornece simuladores.
Trabalhei em um sistema onde tínhamos que simular operações cartões de débito, bastava apontar pro servidor de testes e a operação era mockada pela operadora, não por nós, exatamente com o mesmo protocolo e toda a chatice.
Não sei dizer mais detalhes a respeito pq não fui eu quem desenvolveu isso, era manutenção apenas.

X

Concordo com você em parte sobre isso. Claro que se o desenvolvedor entendeu errado e não é “bem aquilo” que o cliente queria o projeto esta errado. Mas aquilo que você fez, mesmo não atendendo a necessidade do cliente é funcional.

Qualidade é mais do que isso. Eu posso entregar um sistema no prazo que faz o que o cliente queria mas tão cheio de gambiarras que se eu alterar uma linha o sistema todo deixa de funcionar.

Os testes podem ser usados como documentação, mas são mais do que isso! Eles visam favorecer principalmente a evolução gradativa do sistema, garantido que ao realizar uma alteração eu não vou “quebrar” nenhuma funcionalidade. Eles são fundamentais para refactoring!

Y

Escrever testes unitarios eh bastante dificil, ao contrario do que se tenta propagar por aí. Todos os programadores que conheci (pessoalmente) e diziam não gostar de testes unitários, ou que eram trabalhosos ou não compensavam, pecavam na verdade não na hora de fazer o teste, mas nos conceitos básicos de orientação a objetos. Classes extremamente acopladas, com muita responsabilidade, com acesso a dados misturado com regra de negocio e assim por diante.

Por isso quando vão testar precisam fazer uso excessivo de mock, o que complica ainda mais o que já não é simples. Os mocks são para testar fronteiras e existem menos fronteiras do que regra de negócio. Se voce precisa de um mock para testar uma regra há algo errado com sua aplicação. Voce só vai precisar de mock para testar a reação do seu código com as fronteiras do sistema. Logo, se você tem essas fronteiras espalhadas para todo lado, a culpa nao eh dos testes.

Programar com teste é mais produtivo, mais seguro e mais divertido. Se alguém gosta de programar e não gosta de escrever teste unitário, pode ter certeza que é porque não aprendeu ainda a programar com testes. E existem programadores extraordinários, com enorme conhecimento de arquitetura de máquina, conhecimento de baixo nível, conhecimento da plataforma que desenvolvem, de otimização de algorítimo e coisas do gênero e que mesmo assim não são bons designers de código.

Por isso eu repito, se voce não gosta de teste unitário é porque ainda não se deu ao trabalho de estudá-lo a fundo. É muito mais divertido programar com testes. E quanto aos mocks, que eu também não gosto, eles são exceção, não regra, para testes unitários.

L

Já usei muito mock em testes, mas hoje penso várias vezes antes de usar. Com o passar do tempo, a manutenção de testes com mock acaba ficando cada vez mais complicada e começo a duvidar da eficácia dos mesmos. Claro que existem casos (integração com sistemas de terceiros por exemplo) em que você acaba sendo obrigado a usar mocks, a não ser que possua um simulador do sistema.

Hoje prefiro que os testes sejam os mais reais e próximos da realidade possíveis, ou seja, de integração mesmo.

T

LucianoM86:
Claro que existem casos (integração com sistemas de terceiros por exemplo) em que você acaba sendo obrigado a usar mocks, a não ser que possua um simulador do sistema.

No final das contas esse simulador do sistema acaba atuando como um mock.

O problema no final das contas não são os mocks, mas o mesmo de todos os outros recursos: a péssima utilização (design patterns que o diga).

Ia dizer aqui o mesmo que falo sobre o Singleton: use apenas na presença de um adulto responsável. Mas pensando melhor, acabaria dizendo o mesmo pra programação como um todo.
O povo descobre um recurso novo e quer sair enxutando cada canto da p* do sistema com isso, de todo modo possível.
Calma ae galera, cada coisa no seu lugar pombas!

A

LucianoM86:
Já usei muito mock em testes, mas hoje penso várias vezes antes de usar. Com o passar do tempo, a manutenção de testes com mock acaba ficando cada vez mais complicada e começo a duvidar da eficácia dos mesmos. Claro que existem casos (integração com sistemas de terceiros por exemplo) em que você acaba sendo obrigado a usar mocks, a não ser que possua um simulador do sistema.

Hoje prefiro que os testes sejam os mais reais e próximos da realidade possíveis, ou seja, de integração mesmo.


Concordo. No início do projeto os mocks são mais produtivos, justamente pelo fato de poderem simular situações que ainda não estão totalmente implementadas. Já com o sistema implementado acho que o mais produtivo é realizar os testes das fases posteriores (sistema, aceitação, etc), que permitem verificar se o que deveria funcionar ainda está funcionando e o que devia ser feito realmente está sendo feito.

H

Tchello:
jakefrog:
Quando possível eu gosto de utilizar objeto real. Para teste de DAO por exemplo, eu gosto de utilizar HSQLD. O DAO irá se comportar como realmente deve.

Agora, se você tem uma classe que faz cobrança de cartão de crédito a um cliente… como você vai fazer se não tiver um mock? Ou algum simulador?

Acho necessário sim o mock, mas não para todas as situações.

A operadora de cartão fornece simuladores.
Trabalhei em um sistema onde tínhamos que simular operações cartões de débito, bastava apontar pro servidor de testes e a operação era mockada pela operadora, não por nós, exatamente com o mesmo protocolo e toda a chatice.
Não sei dizer mais detalhes a respeito pq não fui eu quem desenvolveu isso, era manutenção apenas.

Maneiro. Vou pesquisar sobre isso. Valeu! =D

Y

Adelar:
LucianoM86:
Já usei muito mock em testes, mas hoje penso várias vezes antes de usar. Com o passar do tempo, a manutenção de testes com mock acaba ficando cada vez mais complicada e começo a duvidar da eficácia dos mesmos. Claro que existem casos (integração com sistemas de terceiros por exemplo) em que você acaba sendo obrigado a usar mocks, a não ser que possua um simulador do sistema.

Hoje prefiro que os testes sejam os mais reais e próximos da realidade possíveis, ou seja, de integração mesmo.


Concordo. No início do projeto os mocks são mais produtivos, justamente pelo fato de poderem simular situações que ainda não estão totalmente implementadas. Já com o sistema implementado acho que o mais produtivo é realizar os testes das fases posteriores (sistema, aceitação, etc), que permitem verificar se o que deveria funcionar ainda está funcionando e o que devia ser feito realmente está sendo feito.

Mocks nao sao produtivos nunca, eu acho. Eles sao necessarios em alguns pontos, mas nao se deve ter mocks espalhados para todo lado nos testes. Se voce tem ha algo errado (na maioria dos casos).

Esses tais testes de fases posteriores deixam passar coisas que os testes unitarios nao deixam (e vice-versa), pequenas alteracoes que causam efeitos colaterais em situacoes excepcionais, aquelas que raramente sao executadas e por tanto raramente testadas. Esses casos normalmente sao deixados de lado pelos testes tradicionais.

Testes de integracao tambem sao necessários, mas são pesados logo sao rodados com cada vez menos frequencia, o que demora cada vez mais para acusar um erro. E quando acusa, eles sao abrangentes demais e fazem com que voce precise debugar o codigo atras do erro. Testes unitarios e de integracao sao complementares, se voce tem um mas nao tem outro é bastante provavel que voce tenha um sistema propenso a falhas.

E

Interessante post que o Shoes fez em 2007 sobre testes: http://blog.fragmental.com.br/2007/10/31/programadores-profissionais-escrevem-testes-ponto-final/

Também ele fala sobre os testes nesta entrevista: http://www.revistawide.com.br/index.php/entrevista-phillip-calcado/

Testes são importantes, muitos erros você pega logo de cara, uma vez que você acostuma a programar testando dificilmente consegue voltar a velha forma de programar tudo e testar mais tarde.

Utilizo TDD atualmente em qualquer projeto que eu esteja, utilizo JUnit, Mockito, Selenium, também utilizo o Sonar para os padrões de qualidade do código e cobertura de teste, são ferramentas ideais e de grande auxílio quando estou desenvolvendo.

Quando comecei a utilizar TDD, notava que tinha dificuldade de começar pelos testes, era diferente do que eu estava acostumado, mas uma vez que você “pega a manha” de como faz, vc acostuma, vc sente falta quando não há testes, vc sente que aquilo não vai funcionar como vc quer.
Teste são importantes, fazem toda a diferença.
Com testes vem a refatoração, ou seja, você consegue melhorar a qualidade do seu código, torná-lo mais simples para futuras manutenções.

Montei uma pequena apresentação para o FISL de 2011 sobre o assunto, para quem quiser ler: www.slideshare.net/eduardo.bregaida/refatorao-de-cdigo-com-capito-nascimento-verso-completa

Abraços

V

Eu já trabalhei num sistema que um dos mocks seria tão complexo de escrever, que constituiria um projeto à parte. Foi mais fácil usar o equipamento diretamente.

Por mim, essa é mais uma situação onde mocks foram vendidos como “bala de prata”. Creio que seja o caso de avaliar. Em muitos sistemas CRUD, eu particularmente acho mais fácil e rápido subir um BD de testes na máquina de cada desenvolvedor, do que usar mocks em memória. Sem falar que o teste acaba ficando mais confiável.

Por isso, no final das contas, a resposta acaba sendo a de sempre: “Depende”.

V

Eduardo Bregaida:
Interessante post que o Shoes fez em 2007 sobre testes: http://blog.fragmental.com.br/2007/10/31/programadores-profissionais-escrevem-testes-ponto-final/

Também ele fala sobre os testes nesta entrevista: http://www.revistawide.com.br/index.php/entrevista-phillip-calcado/

Testes são importantes, muitos erros você pega logo de cara, uma vez que você acostuma a programar testando dificilmente consegue voltar a velha forma de programar tudo e testar mais tarde.

Utilizo TDD atualmente em qualquer projeto que eu esteja, utilizo JUnit, Mockito, Selenium, também utilizo o Sonar para os padrões de qualidade do código e cobertura de teste, são ferramentas ideais e de grande auxílio quando estou desenvolvendo.

Quando comecei a utilizar TDD, notava que tinha dificuldade de começar pelos testes, era diferente do que eu estava acostumado, mas uma vez que você “pega a manha” de como faz, vc acostuma, vc sente falta quando não há testes, vc sente que aquilo não vai funcionar como vc quer.
Teste são importantes, fazem toda a diferença.
Com testes vem a refatoração, ou seja, você consegue melhorar a qualidade do seu código, torná-lo mais simples para futuras manutenções.

Montei uma pequena apresentação para o FISL de 2011 sobre o assunto, para quem quiser ler: www.slideshare.net/eduardo.bregaida/refatorao-de-cdigo-com-capito-nascimento-verso-completa

Interessante… mas creio que ninguém questionou a importância dos testes.
O questionamento está num ponto específico: usar ou não mocks nesses testes.

Qual é a sua opinião sobre isso, em particular? Ajudam ou atrapalham?

E

ViniGodoy:
Eduardo Bregaida:
Interessante post que o Shoes fez em 2007 sobre testes: http://blog.fragmental.com.br/2007/10/31/programadores-profissionais-escrevem-testes-ponto-final/

Também ele fala sobre os testes nesta entrevista: http://www.revistawide.com.br/index.php/entrevista-phillip-calcado/

Testes são importantes, muitos erros você pega logo de cara, uma vez que você acostuma a programar testando dificilmente consegue voltar a velha forma de programar tudo e testar mais tarde.

Utilizo TDD atualmente em qualquer projeto que eu esteja, utilizo JUnit, Mockito, Selenium, também utilizo o Sonar para os padrões de qualidade do código e cobertura de teste, são ferramentas ideais e de grande auxílio quando estou desenvolvendo.

Quando comecei a utilizar TDD, notava que tinha dificuldade de começar pelos testes, era diferente do que eu estava acostumado, mas uma vez que você “pega a manha” de como faz, vc acostuma, vc sente falta quando não há testes, vc sente que aquilo não vai funcionar como vc quer.
Teste são importantes, fazem toda a diferença.
Com testes vem a refatoração, ou seja, você consegue melhorar a qualidade do seu código, torná-lo mais simples para futuras manutenções.

Montei uma pequena apresentação para o FISL de 2011 sobre o assunto, para quem quiser ler: www.slideshare.net/eduardo.bregaida/refatorao-de-cdigo-com-capito-nascimento-verso-completa

Interessante… mas creio que ninguém questionou a importância dos testes.
O questionamento está num ponto específico: usar ou não mocks nesses testes.

Qual é a sua opinião sobre isso, em particular? Ajudam ou atrapalham?

Então Vini o próprio tópico tem a questão

Testes unitários / Mocks são realmente necessários?

O que eu tentei falar é que eu acho sim que ajudam, como eu falei acima e são muito importantes, depende da situação, apenas quis explicar melhor como me ajudou.
Mocks são muito interessantes, vejo mta gente reclamando que demora muito para fazer testes com Mock, mas temos que levar em consideração que um tempo maior de desenvolvimento acarretará em um tempo menor de manutenção.

Além disso os mocks nos ajudam a isolar as camadas, por exemplo camada de Negócio do projeto, eu quero testar algumas regras de negócio mas não quero que meu código acesse o banco de dados e etc, o mock serve exatamente aí.

Como vc msm disse, mocks não são “bala de prata”, não servem para todas as situações, tem isso também.

Bom espero que tenha ficado mais claro agora.

Abraços :smiley:

V

Ah bom, é verdade.
É que fui pelo artigo, não pelo título. :slight_smile:

E

ViniGodoy:
Ah bom, é verdade.
É que fui pelo artigo, não pelo título. :)

Entendi, eu respondi pq acabei dando uma geral na discussão aqui, dai achei interessante relembrar o post do Shoes rs.

Vlw Vini :smiley:

S

Esse assunto é mais polêmico que mamilos hehehe!

Mas vamos lá…

Pra mim os mocks são necessários sim desde que a sua implementação esteja correta. Existem casos de que quando um mock seja muito trabalhoso de se montar é por que sua classe(classe mockada) não foi corretamente implementada, ou se você tem vários mocks distintos para um método é hora de refatorar esse método fracionando para chegar o mais próximo do que o método deve (e só) realmente fazer.

No final das contas cabe ao desenvolvedor decidir usar o mock ou não.

D

Bom eu nunca usei mocks, na verdade trabalho em um ambiente sem cultura de testes, desatualizado, onde agilidade, boas práticas, inovação, passam longe. Até por isso, estou cumprindo meu aviso prévio lá e vou caçar uma vaga melhor no mercado.

Tenho estudado TDD por conta, estou lendo um livro e tenho mais 2 engatilhados para ler. EStou muito interessado por este assunto, o próprio conceito de mock, stubs, ainda não está 100% claro pra mim, mas está no pipeline de estudo.

Bom lá onde trabalho já integramos com diversos sistemas de terceiros. O que o pessoal costumava fazer era gerar uns retornos fakes no código mesmo para ter o que exibir nas telas, grids, etc…depois de bem adiantada a parte visual conforme o desenvolvimento ia andando eram gerados simuladores ou quando a integração era com banco ai o DAO buscava direto do banco mesmo, era gerada uma massa fake, etc…

Bom nessa experiência o que pude observar é que toda vez que o sistema ia pra homologação no cliente ou deploy em produção pipocavam erros que não aconteciam nos simuladores ou base fake pq assim como os mocks, e o cara disse lá na thread do Bill Burke:

“When you DO use mocks you are testing in an environment that is biased toward a passing test. An artificial environment will always make invalid assumptions about the behavior and stability of that environment.”

Bom eu acho que nesse ponto não tem muito o que fazer mesmo, é só testando a quente que a coisa vai ferver mesmo, é na base de produção que vai ter um cara lá com um nome escroto gigantesco truncado e o sistema não vai conseguir fazer o match em algum ponto. Ou vai ter um senhor lá com 103 anos de idade e algum infeliz fez alguma conta envolvendo idade pensando somente em 2 dígitos, etc…

Mas até aí, acho que o cara que inventou o mock, ou o teste unitário, ou o que quer que seja, nunca pensou em cobrir todos esses cenários, na verdade o que percebo é que alguns acham que o teste unitário é a verdade, “ah, deu verde, blz tá funcionando”. Não é bem assim. Na verdade estudando TDD percebe-se (se eu estiver errado me corrijam) que o simples teste em si depois de pronto é o que gera menos valor no processo, é o menos “importante” digamos assim, como li no livro de DDD do Jimmy NIlson, ele cita um colega dele que fala que o verdadeiro valor do TDD está no vermelho e não no verde.

Os testes são importantes e é extremamente necessário ter essa cobertura de testes (sejam feitos antes via TDD ou não) principalmente para refactoring, mas o resultado de um teste ao meu ver não é nem nunca vai ser algo 100% confiável.

Então o problema as vezes é que o pessoal gerencia mal as expectativas.

Sobre o que usar, como disse ainda estou estudando essas coisas etc, mas sou mais um na onda do “depende”.

Minha conclusão baseado no que usei é que simuladores e bases fakes muitas vezes mais atrapalham do que ajudam até pelo tempo que se consome para construir (simulador de web service por exemplo é um saco, mainframe então…), gera mais código para manter (depois de 2 anos vai um outro cara que não participou daquele desenvolvimento mexer em uma rotina que precisa do simulador, não funciona nada e demora 1 dia para descobrir que a base que tava apontando nem existe mais ou o banco migrou de servidor) então nos últimos projetos minha ideia era ou atuar em um legado o mais próximo possível da realidade como uma cópia da base de produção mascarada ou então usar uma solução o mais simples possível e gastar o tempo outrora gasto em construir essas porcarias para revisar melhor o código, discutir as implementações com os programadores, fazer pareamento, etc…

abs

R

O que me deixa mais feliz nessa discussão é que em um fato todos nós concordamos… Temos SIM que automatizar os testes!

Uma das vantagens que eu vejo nos testes unitários que eu não vi nas discussões propostas pelos Bill, é que eles ajudam e muito no design da sua aplicação…
Principalmente quando falamos sobre baixo acoplamento (entre classes e até com o proprio framework)!

Com testes unitários, temos a tendência sempre em pensar nas classes usando muito de IoC, especialmente injeção de dependência… resultando em classes com pouca responsabilidade (SRP) e bem coesas (SoC)
Pensamos assim, pois se nao fizer dessa forma, vc não será capaz de testá-la! simples! (A não ser que vc tenha um container para te prover essas dependencias)

Outra vantagem é que hj em dia é mto mais facil vc fazer testes unitários do q de integração… talvez algum dia, com as facilidades que ferramentas como o Arquillian trazem, os testes unitarios tornaram-se um pouco inúteis…MMMMMMMMMMASSSSSS, eu nao vejo como os testes de integração ajudam no design!.. Bom, vc já tem um container que irá startar e lhe prover todas as dependencias… até mesmo se o seu objeto estiver muito acoplado e fazendo muita coisa (mesmo aquelas q ele nao deveria fazer)

Mas bom… vamos ver como vai ficar…

D

Pois é Raphael, isso também me deixa feliz, mas o que deixa triste é o fato de um grupo bem restrito de profissionais ter esse conhecimento, se preocupar com esse tipo de coisa, se atualizar, etc…

Como disseram, você fala de testes ai nas consultorias da vida nego torce o nariz, só pensam em cronograma e custo, quando nós que atuamos com desenvolvimento deveríamos pensar em software como uma arte.

É foda cara, você pergunta para um médico, advogado, engenheiro, todos sabem citar pelo menos um autor famoso da área deles, já na TI ninguém sabe, ninguém lê.

Por isso que dou muito valor ao GUJ, aprendi muito aqui e continuo aprendendo, os assuntos vêm a tona em uma thread e aí dá para ir buscar informação na net, em outros sites, mas se nem o assunto surgisse, talvez eu fosse mais um desses caras que estão ai no mercado que por exemplo nunca ouviram falar em pattern por exemplo.

T
  • 1

Um dia desses escrevi algo aqui sobre como os desenvolvedores deviam procurar se esforcar mais em absorver a cultura de modelagem com TDD.

Y

Entao, eu acho que eh justamente ai que esta o problema do mock. Quando o acoplamento eh alto o uso de mock eh bem mais frequente, o que torna os testes dificeis e chatos.

O problema eh que eh dificil reconhecer o problema no meu codigo e bem mais facil dizer que teste eh perda de tempo.

F

Sou a favor do teste unitário, desenvolver com TDD melhora o código, “expande horizontes” e evita erros.

Um fato indiscutivel é: se não é uma cultura da equipe… se os testes são “impostos” ao desenvolvedor… o teste é perda de tempo.

“pior do que uma aplicação sem teste, é uma aplicação com testes viciados ou desatualizados”. (não lembro o autor, não é conhecido mas eu concordo)

R

YvGa:

Entao, eu acho que eh justamente ai que esta o problema do mock. Quando o acoplamento eh alto o uso de mock eh bem mais frequente, o que torna os testes dificeis e chatos.

O problema eh que eh dificil reconhecer o problema no meu codigo e bem mais facil dizer que teste eh perda de tempo.

Então… bacana o seu pensamento… mas em minha opinião isso não é culpa do mock… mas sim do seu objeto.

Se vc está tendo q mocar muita coisa, entra no q vc disse… está com acoplamento muito alto…

Só discordo com vc qndo vc diz q é dificil reconhecer o problema… em minha opinião não é…
aliás, o problema está mto bem descrito no setUp inicial dos seus testes

Testes unitários deveriam ser fáceis e divertidos de se fazer… se no setUp inicial dos seus testes vc esta tendo q mocar muita coisa, recebendo muitas dependencias no constructor do seu objeto, isso pode ser sinal de q vc nao esteja seguindo o SRP e SoC
Bom, mais um vez… teste unitário te ajudando no seu design

Mas como eu disse, a culpa não é do mock… ele é apenas um facilitador… resta agora nós sabermos utilizá-lo corretamente

S

Sou contra testes unitários. Na verdade entendi recentemente porque eu sou contra os testes unitários. Como tudo na vida, existem duas correntes diametralmente opostas no desenvolvimento de software:

1 - Teórica, que acha que complexidade indica que o programador é foda, que quanto mais classes e interfaces melhor, que as classes precisam ser isoladas e cheio de padrões GOF para serem bonitas, que bonecas russas é a melhor maneira de fazer software, etc.

2 - Prática, que acredita no princípio KISS, que não admite complexidade, que entende que deve ser fácil olhar apara um sistema e entendê-lo sem ter que fazer um esforço cerebral muito grande, que entende que o número de classes, entidades e interfaces de um sistema deve ser minimizado, que prefere uma hierarquia simples de heranca a bonecas-russas, etc.

Para o 1, teste unitário dá um alívio, do tipo: eu fiz um sistema gigantesco e complexo que nem eu mesmo entendo, mas pelo menos tenho um coverage de testes unitários em 90%. Na prática o quanto esses testes vão evitar bugs? Pouco. Na prática os testes unitários garantem a qualidade do sistema? Não.

Para o 2, testes unitários são totalmente desnecessários e um pé no saco. Como falaram aí em cima, é porque “esse grupo não entende nada de desenvolvimento de software”, UML, padrões GOF, bonecas-russas, etc.

Y

Raphael Lacerda:
YvGa:

Entao, eu acho que eh justamente ai que esta o problema do mock. Quando o acoplamento eh alto o uso de mock eh bem mais frequente, o que torna os testes dificeis e chatos.

O problema eh que eh dificil reconhecer o problema no meu codigo e bem mais facil dizer que teste eh perda de tempo.

Então… bacana o seu pensamento… mas em minha opinião isso não é culpa do mock… mas sim do seu objeto.

Se vc está tendo q mocar muita coisa, entra no q vc disse… está com acoplamento muito alto…

Só discordo com vc qndo vc diz q é dificil reconhecer o problema… em minha opinião não é…
aliás, o problema está mto bem descrito no setUp inicial dos seus testes

Testes unitários deveriam ser fáceis e divertidos de se fazer… se no setUp inicial dos seus testes vc esta tendo q mocar muita coisa, recebendo muitas dependencias no constructor do seu objeto, isso pode ser sinal de q vc nao esteja seguindo o SRP e SoC
Bom, mais um vez… teste unitário te ajudando no seu design

Mas como eu disse, a culpa não é do mock… ele é apenas um facilitador… resta agora nós sabermos utilizá-lo corretamente

Quando eu disse que eh dificil reconhecer que o problema esta no codigo, eu estava me referindo aos que nao procuram melhorar as praticas, e com isso melhorar seu codigo. Acham mais facil apontar a hipotetica dificuldade de algumas tecnicas, nao reconhecendo que esta dificuldade vem justamente do seu codigo mal escrito, nao da tecnica em si.

No mais, concordo plenamente com voce.

Cara, eu concordo plenamente com voce sobre os seus dois casos, nao teria como concordar mais. Complexidade deve ser removida do codigo a todo custo, classes e interfaces tem que ter razao para existir, nao se deve utilizar padroes a nao ser que simplifique o codigo (que diminua a complexidade).

Resumindo, e abusando do seu exemplo para concluir meu raciocinio. Tudo que for feito no caso 1, deve ir até, e somente até, um ponto que nao comprometa o caso 2.

Agora a parte que eu discordo. Testes unitarios nao sao um pé no saco (pelo menos pra mim, eu acho mais facil e mais rapido desenvolver com testes) e muito menos desnecessarios, eles ajudam, e muito, a manter as coisas simples, varrem a complexidade, geram documentacao executavel e ainda dao confianca para ir em frente.

Testes unitarios garantem qualidade? Logico que nao, o que garante qualidade é a experiencia do programador, nada mais. Teste unitario é uma entre muitas ferramentas que estao disponiveis para escrever codigo de qualidade. Voce pode usá-la ou nao. Eu prefiro usar e insisto em dizer que quem nao gosta, normalmente nao gosta porque ainda nao se deu ao trabalho de estuda-la a fundo.

A

Em uma opiniao é uma das partes mais importantes ter os testes unitarios na aplicação, porque no dia que houver um problema ter-se-a uma base por onde comecar a verificar o erro.
Quanto aos mocks não sou a favor, mas deve-se fazer quando realmente for necessário.

J

Saoj, concordo com você em quase tudo…
Só acho que as vezes, por algum motivo, realmente precisamos criar a tal boneca-russa…
E em muitos casos os testes unitários realmente ajudam a ganhar mais qualidade.

Adotamos aqui da seguinte maneira:
Precisa desacoplar, o teste unitário será benéfico: Fazemos
É simplesmente um CRUD: Não fazemos

Já vi sistema que tinha mais classe de teste do que do sistema em si… e o sistema era buguento ao extremo…
Os testes passavam bem… o problema eram os bugs que ocorriam devido a sequência de interações feitas… Tinha-se muitos testes integrados também com Selenium, mas era praticamente impossivel prever todas as situações e no fim das contas a conclusão que cheguei é: Testes não fazem magica e pioram sua produtividade!

Hoje não concordo com processos tão engessados… tem de passar por 200 camadas para um print na tela… tem de fazer teste unitário para todas as classes… tem que usar DI e IoC em tudo… não pode ter herança… tudo tem que ser feito através de interface… acho que no final das contas o resultado é: o software demora mais para ficar pronto e a qualidade não é tão melhor assim! Tento achar o meio termo das coisas!

N

saoj:
Sou contra testes unitários. Na verdade entendi recentemente porque eu sou contra os testes unitários. Como tudo na vida, existem duas correntes diametralmente opostas no desenvolvimento de software:

1 - Teórica, que acha que complexidade indica que o programador é foda, que quanto mais classes e interfaces melhor, que as classes precisam ser isoladas e cheio de padrões GOF para serem bonitas, que bonecas russas é a melhor maneira de fazer software, etc.

2 - Prática, que acredita no princípio KISS, que não admite complexidade, que entende que deve ser fácil olhar apara um sistema e entendê-lo sem ter que fazer um esforço cerebral muito grande, que entende que o número de classes, entidades e interfaces de um sistema deve ser minimizado, que prefere uma hierarquia simples de heranca a bonecas-russas, etc.

Para o 1, teste unitário dá um alívio, do tipo: eu fiz um sistema gigantesco e complexo que nem eu mesmo entendo, mas pelo menos tenho um coverage de testes unitários em 90%. Na prática o quanto esses testes vão evitar bugs? Pouco. Na prática os testes unitários garantem a qualidade do sistema? Não.

Para o 2, testes unitários são totalmente desnecessários e um pé no saco. Como falaram aí em cima, é porque “esse grupo não entende nada de desenvolvimento de software”, UML, padrões GOF, bonecas-russas, etc.

Completamente de acordo!

L

Melhor aprender a escrever testes decentemente do que fazer testes só pra ter cobertura e não garantir nada!

D

Não conhecia esse termo bonecas russas, o que significa?

S

É quando vc usa composição e o pattern decorator ao extremo, ou seja, vc sai colocando uma objeto dentro do outro, fazendo proxies, wrappers, delegates, etc.

Fica bem abstraído, separado, mas difícil de entender na minha opinião.

Foto das bonecas => http://www.baixaki.com.br/papel-de-parede/15642-boneca-russa.htm

D

Valeu

É não posso falar sem nunca ter visto aplicado e tal mas só de ouvir falar já soa esquisito.

Parece ser aquele coisa que bem aplicada pode até dar algum resultado, porém, se perder a mão um pouquinho já vira um macarrão daqueles.

C

O Matroska Pattern nunca é bom.
Ele é diferente de “Prefira composição à herança”. Ele é “encapsule tudo em tudo e use!”

Eu também não gosto muito do conceito de teste unitário.
Talvez por causa das minhas experiências profissionais, talvez por eu ser alguém acomodado, mas eu sempre vi todo o qualquer sistema como uma junção de muitas e muitas peças distintas. A complexidade de todo sistema que já trabalhei está na junção de todas as peças. O teste de uma peça só deveria ser relevante se esta peça for complexa E única, sem a possibilidade de quebrar em pequenas outras peças.

J

Concordo!
Por exemplo, componentes que são utilizados por outros sistemas e que fazem calculos muito complexos.
Trabalhei em um componente destes e digo que quanto mais testes unitários era melhor… eles realmente ajudavam!

Criado 3 de maio de 2012
Ultima resposta 18 de mai. de 2012
Respostas 46
Participantes 28