BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Notícias Refactoring em TDD deve incluir os testes?

Refactoring em TDD deve incluir os testes?

Favoritos

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?

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

  • Seu comentário está aguardando aprovação dos moderadores. Obrigado por participar da discussão!

    Só se vc tiver testes dos testes rs.

  • Ah se tudo fosse tão simples assim...

    by Fabricio M,

    Seu comentário está aguardando aprovação dos moderadores. Obrigado por participar da discussão!

    Mesmo sem mudar requisitos de negócio, podemos querer alterar o modo como separamos as responsabilidades dentro do projeto. Assumindo que tudo foi construído com TDD de forma decente (testes realmente unitários, e não end-to-end, acoplando as várias camadas no mesmo teste), novas classes/métodos poderão ser criadas e classes inteiras poderão deixar de existir e, consequentemente os seus testes unitários. E aí? Do ponto de vista dos requisitos funcionais, não estou alterando o sistema, apenas refatorando-o. Porém estou fazendo alterações significativas na estrutura da aplicação, e não vejo como fazer isso sem alterar os testes.

    Alguém vê uma alternativa?

    []'s
    Fabricio

  • Experiencia

    by Thiago Ramos,

    Seu comentário está aguardando aprovação dos moderadores. Obrigado por participar da discussão!

    Trabalho com ATDD e TDD utilizando mocks. A pouco tempo atrás fiz um refatoramento em uma classe a qual possuia muitos ifs e dependia de muitras outras classes. Fiz um refactoring utilizando basicamente um padrão chamado chain of responsibillity. Eu fiz a funcionalidade o tempo todo prestando bastante atenção se os testes de aceitação iriam quebrar e eles nunca quebraram, porém os testes unitários quebraram e tive que refatorá-los, mudei as classes de teste, diminui a responsabilidade de teste de algumas e adicionei outras para as quais havia criado efetuando assim testes para a responsabilidade das classes as quais havia criado.
    Creio que as vezes, uma refatoração exige este tipo de mudança. Como eu tinha testes de aceitação que testavam a funcionalidade como um todo(black-box) não me preocupei em ter alguns testes unitários falhando no fim, pois como havia mudado a forma como os objetos estavam se comunicando e suas dependencias era de se esperar que alguns testes unitários quebrassem, mas nunca os testes de aceitação.
    Por isso acho extremamente importante trabalhar não só com TDD, mas também com ATDD. Enquanto um verifica o código, o último verifica a funcionalidade como um todo.

    Valeu.

    Thiago Ramos.

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

BT