O custo dos testes unitários

Os benefícios de uma boa suíte de testes unitários são inegáveis: código com menos acoplamento, segurança no refactoring (e principalmente na eliminação de código morto), ausência de erros de regressão, verificabilidade automática, etc. É até estranho pensar que alguém optaria por desenvolver software sem testes unitários automáticos.

Mas a verdade é que não existe almoço grátis. Não há muito o que discutir quanto a isso. Então qual é o custo associado a uma suíte abrangente de testes unitários?

O que os testes fazem é exercitar o código e verificar os resultados obtidos. E, mesmo que você não vá guardar seus testes para o futuro, de algum modo você os executa. Seja criando um programa de chamada e imprimindo os resultados para verificação manual. Seja rodando o código num REPL qualquer. Seja iniciando a aplicação e clicando em alguns botões. De algum modo você exercita seu código antes de subir as alterações para o repo. E você faz isso com vários dados de entrada até atingir um nível satisfatório de confiança.

Correto?

Tendo isso em mente, chegamos ao ponto central da questão: os testes unitários automatizados são somente o registro em código de algo que já ia ser feito de qualquer jeito. Se, ao invés de disparar a aplicação para conferir suas mudanças, você escrever um teste que acione o código e verifique os resultados, você vai levar o mesmo tempo. Não há nenhum custo adicional em fazer isso.

Mas por que eu tomei o cuidado de destacar o “adicional” no parágrafo anterior? Porque os testes unitários só saem “de graça” se você realmente está fazendo isso. Se você vai subir seu código para o repo sem executar, simplesmente porque você acredita que ele é muito simples e obviamente não tem como falhar, então já não estamos falando da mesma coisa. Estamos comparando maçãs com bananas.

Se você publica código sem verificá-lo, seus testes unitários terão um custo alto: o custo de saber que o código funciona.