Sobre testes de software
Uma visão um pouco mais aprofundada e razoável sobre testes
Há três anos, após sair do curso de jornalismo, comecei a trabalhar com tecnologia de maneira profissional. Eu já tinha um fundo de conhecimento e algumas "brincadeiras", mas nada que me tenha adquirido experiência no mercado de trabalho.
No meu primeiro ano como desenvolvedor web, fiquei abismado com a quantidade de coisas que teria que aprender para me tornar competitivo. Nisso, estavam incluídos os testes automatizados de software, para ter certeza que o que eu estava desenvolvendo era confiável.
"Testes automatizados? Pra quê?"
Automatizar o processo de testes de um software é um ponto crucial para obter confiança de que as coisas estão funcionando sem o processo maçante de testar cada pedacinho de código manualmente.
Digamos que seu software, um aplicativo web, tenha 10 features. A cada alteração você testará manualmente no browser para ter certeza que as coisas funcionam? Não, né? Seria algo chato e inviável, porque tomaria um tempo que você poderia estar gastando desenvolvendo novas features ou consertando bugs.
É pra isso que fazemos testes. Unitários, de integração e end-to-end, para citar os mais famosos. Esse processo nos dá garantias de que estamos entregando algo de qualidade e que seguem os requisitos pré-definidos, sem o processo chato de testar tudo de cada vez repetidamente. Deixa que a máquina faz esse serviço pra ti!
"Testes são perda de tempo"
Aham. Você certamente terá bastante tempo procurando um emprego após ser demitido por causa de um bug que gerou milhões em prejuízo para sua (então) empresa.
Brincadeiras à parte (não é tão brincadeira não!), testes são importantes. Além de ter garantia de que as coisas funcionam, eles, de certa forma, te forçam a fazer um "code review", e muitas vezes te fazem pensar sobre a maneira em como você escreve seu código, além de detectar bugs em casos de uso em que você não conseguiu pensar na hora em que desenvolvia.
Então, da próxima vez que seu gestor se aproximar e dizer que não tem tempo/dinheiro para fazer testes por causa de um deadline ou budget curto, fale pra ele que vale mais a pena "gastar tempo" fazendo testes do que perder tempo no futuro consertando um Frankenstein todo desorganizado porque as coisas não foram feitas do jeito certo — e os bugfixes introduzem novos bugs!
O dilema dos testes unitários
"Testes unitários são muito parecidos com ir ao ginásio. Você sabe que é bom para você, todos os argumentos fazem sentido, então você começa a malhar. Há uma corrida inicial, o que é ótimo, mas depois de alguns dias você começa a se perguntar se vale a pena. Você está tirando uma hora do seu dia para trocar de roupa e correr em uma roda de hamster e você não tem certeza se realmente está ganhando outra coisa senão pernas e braços doloridos.
Então, depois de uma ou duas semanas, assim que a dor estiver desaparecendo, um deadline se aproxima. Você precisa passar todas as horas restantes tentando fazer um trabalho “útil”, para cortar coisas estranhas, como ir à academia. Você sai do hábito e, quando o deadline termina, você volta à estaca zero. Se você conseguir voltar para a academia, você se sentirá tão dolorido quanto estava na primeira vez que foi.
Você faz algumas leituras para ver se está fazendo algo errado. Você começa a sentir um irracional despeito em relação a todas as pessoas felizes e em forma que exaltam as virtudes de malhar. Você percebe que não tem muito em comum. Eles não têm que dirigir 15 minutos para ir ao ginásio, há um em seu prédio. Eles não precisam discutir com ninguém sobre os benefícios do exercício; é apenas algo que todo mundo faz e aceita como importante. Quando um grande prazo se aproxima, eles não são informados de que o exercício é desnecessário mais do que o seu chefe pediria para você parar de comer." (Retirado daqui)
O que testar, então? E como fazer isso?
Isso depende muito. Hoje em dia, com o avanço da comunidade open source, é muito comum utilizarmos frameworks e bibliotecas para abstrair algum ou a maior parte do trabalho. Esse código de terceiros já foi testado. Você não precisa testar de novo. Vou ilustrar isso.
Trabalhando com React, por exemplo, você não precisa testar se, quando clicado no botão, a função de login é chamada. Isso é algo que o time do React garante. Eles fazem, eles testam. A única coisa a ser testada de forma unitária por você nesse pedaço de código é a função de login que você mesmo escreveu.
Ainda assim, testes unitários não me passam a maior confiança do mundo que meu código funciona como esperado. Explico. Em um post do Kent C. Dodds, que recomendo MUITO que você leia, ele posta essa GIF:
Me sinto assim testando de forma unitária. "Tudo funciona". O seu botão de login, o formulário. Mas e o fluxo previsto no documento de requisitos?
É aí que entram os testes de integração. A linha entre teste de integração e teste unitário é tênue, é verdade, mas deixe-me explicar:
Fazendo testes de integração eu tenho como, na maioria das vezes, "montar o corpo", entende? Eu consigo certificar que o todo funciona bem para executar certa tarefa. Uma outra dica que acho valiosa é escrever os testes de acordo com o documento de requisitos: com isso, você não foge do escopo, mantendo o foco nas tarefas necessárias.
Para entender melhor sobre os testes de integração, leia o artigo do Kent. É sério. Vale lembrar que os testes de integração NÃO excluem os testes unitários. São coisas que se complementam. O teste unitário serve pra saber se tem duas pernas, dois braços, um tronco e uma cabeça. O teste de integração serve pra saber se, se juntando tudo, temos o resultado esperado.
Sobre cobertura de código
É bonitinho manter 100% do código coberto. Mas é inútil na maioria das vezes. Vivi isso na pele: em uma empresa que trabalhei, a API que desenvolvi tinha cobertura de código de 100%, mas eu sentia que o código era frágil, que a mais leve alteração quebrava as coisas, assim como andar sobre ovos.
Confesso que não sabia testar muito naquela época, mas depois que comecei a ler os artigos do Kent, as coisas parecem fazer muito mais sentido e não me incomoda mais ter cobertura de 80% (no máximo). Arrisco dizer que os únicos testes que faço hoje são de integração, seguindo à risca o documento de requisitos.
É isso. Se tiver qualquer dúvida, sugestão, ou se apenas acha que eu disse abobrinhas nesse texto, berra aí nos comentários! Como leitura, recomendo esse post do Kent (eu gosto desse cara!) sobre testes de detalhes de implementação e como fazer menos testes, mas testes melhores. Um abraço!