Entenda de uma vez por todas o que são testes unitários, para que servem e como fazê-los

Um certo dia, navegando por comunidades de desenvolvimento de software me deparei com a seguinte imagem:

Pirâmide de testes

Confesso que na primeira vez não entendi do que a imagem se tratava , mas tive certeza de que um coelho barato era melhor que uma tartaruga cara.

O tempo passou, eu finalmente aprendi o que são testes unitários, o que esse coelho barato representa e gostaria de te ajudar a entender também.

Mas o que são testes unitários?

Um teste unitário basicamente é o teste da menor parte testável de um programa.

Tá, mas o que isso quer dizer?

Se você programa em uma linguagem que suporte paradígma funcional por exemplo, a menor parte testável do seu código deve ser uma função. Então um teste unitário seria o teste de qualquer função. No caso de orientação a objetos seria o teste de um método de seu objeto.

Bom… como tudo é mais fácil de entender na prática, vamos ao código!

No exemplo abaixo, temos uma função que soma dois números e retorna o valor da soma.

Para testar este código, só o que precisamos fazer é executar a função e verificar se seu valor de saída é o que esperamos.

Pronto! Já temos nosso primeiro teste unitário. Bem fácil não é?

Bom.. Agora que você já entendeu o que são e como são feitos testes unitários, você deve estar se perguntando:

Para que servem testes unitários?

Perguntar para que servem testes unitários ou qualquer outro teste automatizado é uma ótima pergunta, afinal existem diversas formas que aparentemente são mais rápidas de testar se minha função está fazendo o que deveria. Eu poderia simplesmente executar o código para verificar se está funcionando. Então, por que motivo eu vou escrever outro código para testar o meu código? O Que garante que o segundo código funciona? Quem testa o teste?

Testes unitários, assim como qualquer teste automatizados não servem principalmente para verificar sem uma função específica está funcionando, mas sim para garantir que sua aplicação continue funcionando após alguma alteração em sua base de código.

Por que escrever testes unitários?

Pode parecer tentador em um primeiro momento não escrever testes para uma função que você acaba de desenvolver, afinal, costuma-se escrever mais código para testar uma função, que o próprio código da função. Mas você deve lembrar que irá passar a maior parte do tempo de desenvolvimento de um sistema trabalhando em sua manutenção.

Sua aplicação em pouco tempo terá algumas centenas de funções sendo executadas, e em muitas vezes executando umas às outras, sua base de código fica enorme e logo torna-se humanamente impossível de ser testada de forma manual após qualquer alteração. Testes unitários na maioria das vezes levam apenas alguns segundos para testar toda sua aplicação.

Por onde começar?

Existem diversas ferramentas de testes unitários para cada linguagem de programação. Você pode começar lendo a documentação destas ferramentas a partir de seus exemplos.

Neste link você pode encontrar algumas destas ferramentas classificadas por linguagem.

Tá, mas ainda não entendi o lance do Coelho barato e da Tartaruga cara

Não poderia encerrar este post sem antes explicar o que a pirâmide de testes quer dizer.

Ela é um conceito desenvolvido por Mike Cohn que diz que você deve ter muito mais testes de unidade (testes unitários) que testes de GUI que são testes mais a nível de usuário. Como clicar em um link por exemplo.

O Conceito da pirâmide explica o quanto testes de GUI são custosos em relação a testes unitários, pois eles demoram muito mais tempo para serem executados e também são de difícil manutenção, enquanto os testes unitários são muito mais simples, rápidos e baratos.

Bônus!

Implementei uma versão um pouco mais completa do teste de exemplo da função soma em Javascript e em Ruby. Você pode conferir o código neste link