Um discussão muito saudável foi iniciada no Tectura pelo Carlos Alberto. Na discussão ele questiona:
O que vocês consideram uma boa refatoração? Começam novamente pelo teste? ou alteram o código fonte, e depois o teste? Qual a ordem em que ocorrem as mudanças?
Em outros termos a discussão caminha para uma discussão sobre se o conceito de refactoring do código/projeto deve ou não incluir uma visita de refactoring também aos testes.
Lembrando que a discussão é contextualizada em um desenvolvimento orientado por testes (TDD), o que significa que discute-se não uma estratégia de testes e sim uma abordagem de design. Vale reforçar também que refatorar não é simplesmente alterar o código, as técnicas de refactoring buscam um aprimoramento do design e não uma otimização de performance, por exemplo, alterando o algoritmo interno de processamento.
Uma das questões que surgem é: deve-se aprimorar o design dos testes com refactoring?
Parece que é consenso que os testes podem e devem ser refatorados para melhorar a qualidade do seu próprio código, contudo, não se deve de maneira alguma alterar em um refactoring do teste o que é efetivamente testado. O refactoring deve se limitar a abordagem da construção do teste. Muitas pessoas compartilham esta opinião, inclusive Guilherme Silveira:
Um padrão comum que começa a crescer e a perder controle são os objetos de ajuda para o teste: mesmo testes de unidade costumam trabalhar com classes de modelo não isoladamente. É comum instanciar seus objetos diretamente e configurá-los atraves de setters (pensando em java), depois passamos a usar builders e ObjectMothers e a medida que esses começam a cheirar mal (code smell), refatoramos para outras abordagens.
Essa posição é reforçada pelo Lucas Gonçalves na sua colocação:
Refatorar é melhorar o design da aplicação sem mudar o comportamento. Ou seja, durante a refatoração você não deveria quebrar nenhum teste, e também não escrever nenhum teste, já que você não está alterando o comportamento.
e faz uma ressalva:
Mas é bem comum durante a refatoração descobrir casos não cobertos pelos testes e aí escrever mais testes.
Como pode-se imaginar essa linha é muito tênue já que não há testes dos testes que possam garantir que o refactoring não alterou o escopo dos testes.
Parece que a estratégia comum ao fazer refactoring dos testes é garantir que código passa pelos testes existentes (green), refatorar apenas testes que estejam passando (caso opte por refatorar o projeto mesmo com testes falhando) e garantir que continuem passando.
Caso haja novas regras de negócio deve-se criar os testes primeiro (afinal é TDD) e depois implementar as regras seguindo o fluxo red-green-refactor.
Caso haja novos cenários a serem testados no código existente deve-se testá-los sem refatorar o código de teste existente e somente após passar todos testes (existentes e novos) optar pela refatoração dos testes.
Qual é sua opinião? Refatorar testes quando e como?