quarta-feira, 25 de agosto de 2010

Porque eu escrevo os testes antes

Depois de um bom tempo insistindo, e com a ajuda também do pessoal da minha equipe que sempre incentivou (exigiu? =P) essa prática, hoje em dia já se tornou natural para mim escrever o teste antes da implementação.

Minha ideia ao escrever esse post é lhe dizer alguns motivos de porque eu acho que você também deveria fazer isso.

#1 Uma prática de design

Já dizia o pessoal do livro The Rspec Book que BDD não é uma prática de testes e sim uma prática de design. Usamos o BDD para nos guiar sobre o que deve ser criado para satisfazer as necessidades de nosso produto, sem desperdícios. Se você escreve o teste depois você não se beneficia disso.

#2 Não se influenciar pela implementação

Quando você escreve o teste você deve se concentrar no que você espera de sua aplicação, sem pensar em como você vai implementar isso. Se você pensar na implementação antes ou, pior, você implementar antes do teste, você pode criar um teste influenciado pela implementação. O que pode fazer com que sua implementação tenha mais coisa do que o necessário e, ainda, pode fazer com que seu teste saiba demais sobre a implementação e a engesse.

Você deveria poder trocar a implementação sem precisar alterar o teste (refatoração), se seu teste sabe demais sobre a implementação, talvez você não consiga fazer isso e tenha grandes prejuízos (todo mundo tem que ficar alterando os testes a cada mudança).

Escrever o teste antes vai deixar seu código mais enxuto e sem desperdícios, focando apenas no necessário.

#3 Mais fácil se certificar que o teste funciona

Quando você escreve o teste antes você faz com que ele falhe e, após a implementação, ele deve passar. Isso já é uma prova de que seu teste está cobrindo o que você está criando. Se você escreve o teste depois você não tem tanta certeza sobre essa cobertura e, se você não tem o costume de retroceder a parte implementada pra ver se o teste realmente falha, talvez você crie testes que não cubram nada de novo.

#4 Não ter o "dever" de escrever o teste depois

Se você escreveu antes você usufruiu de diversos benefícios e no final já estava com tudo pronto, o teste realmente se mostra parte do desenvolvimento (o que ele é de fato). Se você não o fez, no final de tudo você ainda tem que escrever os testes, o que pode parecer um fardo (tudo está "pronto" e eu tenho que "perder" tempo com o teste).

Concluindo

Se sua equipe escreve testes depois, eu lhe digo que vale muito a pena tentar mudar essa ordem. Diria até que não faz sentido escrever o teste depois.

Não é tão difícil assim obter essa prática, basta um pouco de disciplina e, se precisar de ajuda, dicas sobre como testar determinada coisa, me coloco a disposição pra conversar. Não sou nenhum expert de testes, mas gosto bastante de falar sobre o assunto, me adiciona no gtalk, e-mail, twitter ou o que você preferir que eu tento ajudar com o que eu puder.

Até o próximo post!

sábado, 21 de agosto de 2010

Identificando specs lentos com rspec

Recentemente em um projeto me passaram a tarefa de diminuir o tempo de execução dos testes, para facilitar a integração contínua.

Lembrei então de um comando do rspec que havíamos usado em um projeto anterior que facilita muito a tarefa de identificar quais são os testes críticos.

Não sei quantos conhecem (eu não conhecia há dois projetos atrás), mas um dos formatos do rspec é o "profile", que mostra no final dos testes um top 10 dos mais lentos e o tempo que cada um demorou.

Basta executar assim:

spec spec/ -f profile

ou, em sua versão resumida:

spec spec/ -f o

O resultado é similar ao abaixo:

Profiling enabled.
..................

Top 10 slowest examples:
0.0011200 Donald::MergeTool with $EDITOR variable not seted up with unmerged files with --vim argument should call vim
0.0010110 Donald::MergeTool with $EDITOR variable not seted up with no unmerged files should send an error message
0.0009800 Donald::MergeTool with $EDITOR variable not seted up with unmerged files with no arguments should call vim
0.0009340 Donald::MergeTool with $EDITOR variable as mate with unmerged files with no arguments should call mate
0.0009170 Donald::MergeTool with $EDITOR variable not seted up with unmerged files with --gvim argument should call gvim
0.0008920 Donald::MergeTool with $EDITOR variable not seted up with unmerged files with -g argument should call gvim
0.0008910 Donald::MergeTool with $EDITOR variable not seted up with unmerged files with -t argument should call textmate
0.0008830 Donald::MergeTool with $EDITOR variable not seted up with unmerged files with --mvim argument should call mvim
0.0008820 Donald::MergeTool with $EDITOR variable not seted up with unmerged files with --textmate argument should call textmate
0.0008750 Donald::MergeTool with $EDITOR variable not seted up with unmerged files with -m argument should call mvim

Finished in 0.026412 seconds

18 examples, 0 failures