Testes de Unidade são realmente nescessários?

@leandronsp, os problemas do mundo corporativo sempre vão girar em torno do que eu chamo de fator lucro: se está dando lucro, não mexe.
Se a empresa possui um departamento de desenvolvimento, alguém ganha dinheiro, tem lucro, com retrabalho.
Se a empresa terceiriza isso, tem alguém que também lucra com isso.
Logo, qual o interesse em fazer código bom? Coeso, testado e de fácil manutenção? O pessoal da empresa onde trabalho chama isso de empregabilidade. Você desenvolve, cria problemas e garante que vai ter vaga para corrigir o problema que não existiria se você programasse direito.

@Luis_Augusto_Santos quanto ao fator lucro, isso que fazem beira a burrice, pq dá sim pra ter lucro com coisa bem feita. Basta o “manager” que tá encarregado saber buscar informação e aplicar o que precisa ser feito pra aumentar o lucro.

Se nem o “manager” é bem preparado, quem dirá o “developer” que ele contratar. Aí já começa a entrar em outro assunto, mas o foco do problema está mesmo onde você destacou acima: falta de treinamento e conhecimento, e isso começa de cima.


Presenciei um caso de um conhecido onde uma consultoria XXX (multinacional renomada com XX anos de história e bla bla bla) contratou um desenvolvedor Java, mas como ele não tinha os skills necessários pra atender a demanda do cliente, ao invés de treiná-lo adequadamente, colocaram-no pra RECRUTAR outro desenvolvedor Java com skills próprios para aquele cliente em específico. Nonsense total.

1 curtida

Testes são fundamentais.

Mas para complementar o já falado, testes unitários não são o único tipo que existe. Ao realizar uma entrega ao cliente por exemplo, o que importa é ter testes de aceitação. Ao colocar várias partes de um sistema para trabalhar em conjunto é interessante ter testes de integração. Da mesma forma que fazer manualmente testes é também importante dependendo da aplicação, e pode ser a única forma de identificar alguns defeitos.

Testes unitários são interessantes mas nem tudo é suscetível a ser testado assim de uma forma boa, mas para CRUDs, e sistemas simples pode ser aplicado sem problemas.

Mas, na minha opinião, se vai escolher entre fazer unit tests e testes de integração, se for pra ser um ou outro, é melhor codificar os testes de integração do que unitários, devido a que assim você vai poder avaliar se a funcionalidade inteira está OK com todas as partes funcionando em conjunto, não apenas um pedacinho isolado que é o que o teste unitário avalia. Por isso acho bobagem só focar em testes unitários, e esquecer dos vários outros tipos que existem.

Concordo, para o cliente o que importa são os testes de aceitação da funcionalidade que de fato será utilizada, e não os meios (isso é opção de TI). Onde trabalho os analistas de qualidade tem como opção de ferramenta o Selenium. A previsibilidade da aceitação é natural pela presença do cliente, não é mundo isolado de TI como fábrica de software (ai sim doutrinas e diversas siglas podem ser necessárias).

1 curtida

Bom mas mesmo que fosse um mundo isolado de TI, onde você vende uma biblioteca para 3os usarem, seu teste de aceitação pode ser simplesmente uma versão de um teste de integração. E o importante sempre é isso, garantir que os requisitos do cliente são atendidos, e isso é feito com aceitação.

É bom como você falou manter a perspectiva que testes unitário serve para outras coisas: é um auxilio ao desenvolvimento. Serve para identificar especificamente quais métodos estão com problemas, sendo que num teste de integração você não tem essa granularidade. Com isso você consegue testar pre e pos condições, coisa que pode ser feita automaticamente algumas linguagens que possibilitam, e dá até pra emular usando o sistema de tipos, mas não é comum ver normalmente. E pra finalizar outra utilidade é no caso de linguagens com características de tipagem dinamica (incluindo não só linguagens totalmente dinâmicas mas também onde há queries SQL no codigo e frameworks Java que façam uso pesado de reflection) para garantir que o código “compila” como deveria, substituindo no caso um papel que poderia ser feito por um compilador melhor ou SGBD.

Exatamente. Como falei no primeiro post, principalmente para quem disponibiliza frameworks e bibliotecas isso tudo pode ser positivo, ai tenho que concordar. Para atender a “atividade fim” o que importa pro cliente é garantir os requisitos finais para o seu negócio, com testes funcionais. Durante o protótipo e desenvolvimento é importante constante feedback natural com o cliente, para melhor previsibilidade de aceitação do resultado final. Os meios técnicos ficam como opção da TI, se a equipe precisa seguir mais alguma diretriz técnica para conseguir manter bem o sistema.

Se o processo é realmente iterativo nao deve fazer diferença se os testes são escritos antes ou depois. O benefício para o código vai ser o mesmo quando se está constantemente redesenhando o código e eliminando débito técnico.

Aliás, o processo que você descreveu como TDD, parece muito a experiência de desenvolver numa linguagem com REPL.

1 curtida

É normal pedir aval do gerente pra esse tipo de coisa?

Na minha época gerente lidava com preservação da condição das instalações físicas, auxiliava caso precisasse trocar de monitor, cadeira, essas coisas.

Nao li a thread toda, mas por um momento fiquei com medo. Achei que todos estavam falando que testes unitários não era necessários. Depois vi que alguns estavam brincando.

Não consigo ver projetos sem testes unitários. É uma loucura um projeto não ter testes automatizados. Nenhum programador deve, ou deveria, confiar no seu código, por mais que o cara seja bom. Quantas vezes voce nao alterou aquele código e falou, agora vai, e não foi? rs…

Testes de unidade e de integração juntos dá uma segurança tremenda, e não é uma segurança apenas enganadora, quando se escreve bons testes. Ou seja, projeto sem testes, é um projeto falho, na minha opinião.

Escrever um bom código, pensar numa boa arquitetura, não leva bem mais tempo? Náo seria mais fácil fazer algo mais gambiarra para entregar o projeto pro cliente logo? Afinal, pro cliente final, tanto faz se o código tá limpo ou não, o que importa é funcionar. Sim, um bom código, leva bem mais tempo, porém evita diversas manutenções futuras e as vezes até a necessidade de jogar o projeto no lixo e reescrever do zero. O mesmo é pra criar testes. Leva mais tempo, porém você está fazendo aquilo, a fim de garantir saúde para seu projeto.

1 curtida

Concordo, mas quando foi falado acima da importância de ter testes unitários, isto não quer dizer que NÃO é pra termos outros tipos de testes. Teste unitário não substitui nenhum tipo de teste, e nenhum outro tipo de teste substitui unitário.

Isto só se aplica pra quem não faz TDD. Pra quem aplica test-driven (BDD + TDD + [qualquer coisa]DD), é comum começar top-down, ou seja, no final da entrega você tem testes de UI (aceitação), de integração e os unitários.

Sim, você tem razão. Por isso que quem faz as coisas test-driven não cai nesse problema, pois escreve todo e qualquer tipo de teste sem dor.

Beleza, da pra usar TDD sim.

Mas como falei nem tudo da pra desenvolver com TDD. Por exemplo, imagina um caso de uso num jogo onde o usuário faz clique em um objeto na tela, e o visual dele muda para ter um highlight neon ao redor. Fora isso o importante é ter o sistema testado, não é ter usado TDD ou não.

De fato, projetos sem teste algum geralmente têm tendência a serem caros. Quando não vão à falência total, perduram no mercado durante anos, sendo caros como são, sangrando a conta bancária de alguém que acredita que está economizando dinheiro.

E complementando: projeto que só tem testes de integração ou os testes mais “high-level” (e.g Selenium) também tende a ter problemas de manutenção. Mesmo que as features sejam consistentes de uma ponta à outra, no médio e longo prazo esses testes passam a ser cada vez mais caros. Claro que, pra quem gosta de pagar caro, isto não é um problema pq sempre tem quem goste de jogar tempo e dinheiro fora :stuck_out_tongue:

Reiterando, de forma geral:

  • Teste unitário não exime necessidade de outros testes (integração, UI, manual, etc)
  • Outros tipos de testes não eximem necessidade de testes unitários
  • BDD e TDD são baratos, pois evita a necessidade de manter um esquadrão gigante de developers e testers pra manter a consistência do produto

Sim, nem tudo dá pra desenvolver com TDD pq TDD faz parte do workflow test-driven. Mais importante do que usar o termo BDD e/ou TDD, vejo que é importante ter o mindset test-driven, pois desta forma resolve o teu problema em questão: com BDD você especifica que o visual deve mudar quando o usuario faz clique no objeto; pode-se escrever cenarios no Cucumber (como exemplo), obviamente os cenarios vao falhar e daí em diante você continua aplicando BDD/TDD para os componentes; com isso, naturalmente vão surgir testes de integração e unitários, e no final de tudo quando teu cenário passar, a funcionalidade está pronta.

Geralmente confundimos BDD com TDD e vice-versa. Pra mim é tudo um só: test-driven, não importa o termo. Sempre top-down, orientado a funcionalidade e também testabilidade/design/integração dos componentes necessários pra feature.

Você respondeu meu “como faz?” dizendo “depois de ter elaborado, é só implementar”. Está pre-supondo que é possível elaborar um teste razoável, que foi justamente o que eu perguntei como faria. Sinceramente eu não vejo como, pois tem coisas que são subjetivas, da pra implementar o glow de diferentes jeitos com efeitos que são difíceis de quantificar qual é melhor ou pior, exceto claro o caso em que dá um erro de compilação rodar o mesmo!

Bom, só perguntei porque você disse que dava pra fazer testes unitários em tudo, e eu sinceramente não acho que seja o caso. No caso que citei pode ser testado sim mas observando “manualmente” com o sistema rodando, mas não vejo como testar algo que depende da experiência do usuário de forma automatizada.

Isso inclui outros requisitos de um sistema como implementação de bibliotecas de UI, a própria UX do sistema tem vários fatores difíceis de quantificar, e coisas que dependam do “feeling”. Você pode tentar ignorar esses aspectos de um sistema, mas teste automatizado em geral, mesmo sendo algo util, está longe de ser uma panaceia. E por isso TDD e BDD são metodologias que se não cumprem tudo o que prometem, justamente por prometerem resolverem tudo usando os testes automatizados.

PS: Desculpa, deu tilt aqui e editei o post antigo sem querer, em lugar de criar outro respondendo! rs

Dado que o componente ainda não existe, e que pra quem faz test-driven já tem o teste de aceitação e integração falhando, o teste unitário consiste em garantir que o componente chama outro componente (ou lib externa) que faz o efeito. No teu caso específico é um teste de mock (nem sempre é assim), e uma vez que esse teste passa e o lib/componente externo também tem testes, os testes de integração e aceitação também vão passar.

Enfim, não vou tentar te convencer a nada. Só expus meu ponto na thread através de experiências e literaturas. Cabe a cada um de nós absorver o que for útil (ou não).

Acho que faz diferneça sim, pelo simples fato de que a gente pode viciar no que foi implementado e não enxergar caminhos de teste não pensados na hora da implementação.

Uma situação análoga é quando passamos um tempão escrevendo, por exemplo, um artigo. No final, podemos achar que ele está impecável, mas com certeza alguém diferente (e não viciado no texto, como nós estamos) vai encontrar erros/inconsistências. Escrever o teste antes seria uma espécie de simulação dessa terceira pessoa, já que ainda não implementamos a funcionalidade.

Bem, pelo menos é isso que os caras mais experientes da comunidade falam (e eu concordo).

Na minha situação sim, o manager está por dentro de todo o desenvolvimento (ele é formado em computação) e opina sobre as decisões tomadas, além de participar sempre dos encontros onde as discussões técnicas ocorrem. Ele que guia o fluxo do projeto, junto com outros caras mais técnicos.

ok, mas não existe terceira pessoa. Por que assumir que a mesma pessoa viciada numa determinada implementação vai ter um lampejo de criatividade assim que começar a escrever os testes primeiro, e começar a testar todos os casos e situações possíveis?

Claro que existe, o ambiente de produção com milhares de usuários pondo tudo à prova simultaneamente.

Não acho que vai fazer tudo 100%, todo mundo erra. Contudo, com certeza a pessoa vai pensar em mais situações além daquelas que implementou, quando se trata de um componente mais complexo do que um get/set, com alguns possíveis fluxos de execução.

Sinceramente, vocês acham mesmo que vale a pena discutir este tipo de coisa?
Vamos começar lá pelo começo. Quantos aqui seguem processos? Muitos dirão que processos não servem para nada. Outros que são fundamentais.
E quem já trabalhou com bancos de dados (relacionais) normalizados (de verdade)? Aposto que, ao menos uma vez na vida, vocês tiveram que dar uma de DBA ou, pior, viram o DBA fazer coisas que, do ponto de vista da normalização, são verdadeiras aberrações. Em prol do quê? Cada um irá defender seu lado.
Especificação? Quantos trabalham em empresas onde um sistema é 100% especificado (ou uma sprint é 100% especificada) e onde essa especificação é feita com qualidade? E quantos sistemas vocês mesmos foram os analistas, desenvolvedores e testadores?
Boas práticas são fundamentais. Ponto.
Quem está acostumado ao XGH (extreme go horse) dificilmente enxergará as benesses de um scrum bem implementado ou de um BDD.
Mercadologicamente falando, de 100 sistemas rodando por aí, quantos vocês acham que foram feitos seguindo as boas práticas? Quantos são bem testados?

Por que não? O @pfk66 parece ser um cara muito experiente, eu gosto muito dessas discussões que temos as vezes, os pontos dele sempre me fazem parar para pensar e refazer meu pensamento.

Não é porque todo mundo faz errado que eu vou fazer também. Não me forço a fazer as coisas certas, faço porque gosto mesmo hehe

1 curtida