Por um lado, eu quase nunca sento e escrevo testes de unidade. Os testes de unidade são um meio para um fim, não um fim em si mesmos. Eles são uma maneira de responder "esse código faz a tarefa básica que deveria".
Por exemplo, algumas pessoas escrevem uma função e, em seguida, abrem uma sessão interativa para testá-la em alguns valores e verificar se está funcionando:
def fact x
if x == 0
1
else
x * fact(x-1)
end
end
>> fact 10
=> 3628800
>> fact 7
=> 5040
Mas agora você descobre um bug:
>> fact -1
SystemStackError: stack level too deep
from (irb):2:in `fact'
from (irb):5:in `fact'
from (irb):10
Então você conserta:
def fact x
if x < 0
raise "Can't take the factorial of a negative number"
elsif x == 0
1
else
x * fact(x-1)
end
end
>> fact -1
RuntimeError: Can't take the factorial of a negative number
from (irb):3:in `fact'
from (irb):10
Mas agora você realmente deve testar para garantir que ainda funcione:
>> fact 10
=> 3628800
>> fact 7
=> 5040
Como você pode ver, você continua repetindo os mesmos testes ... e precisa comparar os resultados visualmente. O teste de unidade é uma maneira de evitar a repetição neste caso; reduz quanto trabalho você precisa fazer. E embora este seja um pequeno exemplo bobo, no mundo real, torna-se cada vez mais importante e cada vez mais difícil testar manualmente. O que isso significa, é claro, é que as pessoas simplesmente não testam os componentes individuais; eles apenas testam o programa inteiro. Mas então surgem erros, e eles são muito mais difíceis de encontrar. Ou ocorrem erros e são corrigidos, mas alguém introduz o mesmo erro novamente, porque ninguém adicionou um caso de teste para garantir que isso não acontecesse. Ou alguém analisa um grande pedaço de código e diz: "Não faço ideia do que isso deve fazer, pois não está documentado e não possui testes ... se eu corrigir esse bug, não faço ideia se vou quebrar outra coisa dependendo dele; talvez eu apenas reescreva isso do zero. "
Os testes de unidade reduzem todo o trabalho extra nesses casos. A melhor maneira de torná-los divertidos é garantir que as pessoas entendam todo o trabalho que estão substituindo e a flexibilidade extra resultante de saber o que cada parte do código deve fazer. Até certo ponto, as pessoas precisam ter um pouco mais de experiência em escrever e manter uma grande base de códigos para entender o quão importante o teste de unidade pode ser; se todo o código deles for algo que eles escrevem uma vez e jogam fora, eles nunca o entenderão.
E os testes de unidade não devem ser escritos após o fato, como uma tarefa extra depois que você tiver um código que "sabe" que já funciona. Os testes de unidade devem ser escritos primeiro ou, no mínimo (desde que você às vezes se esqueça de escrevê-los primeiro) logo após escrever o código em questão. Isso se chama desenvolvimento orientado a teste e pode ajudar a melhorar suas APIs; se você escrever os testes que exercitam as APIs primeiro, aprenderá onde as APIs são difíceis de usar antes de escrever o código e poderá reprojetar muito mais facilmente do que se você apenas adicionasse os testes posteriormente.
MbUnit
biblioteca mudou minha vida. O teste automático é importante. O teste automático economiza tempo. O teste automático economiza dinheiro. O teste automático pode salvar vidas. O teste automático é o único caminho. O teste automático é mais uma rede de segurança. Quando sou uma das 50 pessoas trabalhando em uma arquitetura enorme, sinto-me como mais um tijolo na parede. Com testes unitários, estou no controle.