Nos textos sobre TDD, frequentemente leio sobre "remover duplicação" ou "melhorar a legibilidade" durante a etapa de refatoração. Mas o que me faz remover uma função não utilizada?
Por exemplo, digamos que exista uma classe C
com métodos a()
e b()
. Agora, eu acho que seria bom ter um método f()
que seja direcionado C
. De fato, f()
substitui todas as chamadas para, b()
com exceção dos testes de unidade que definiram / descreveram b()
. Não é mais necessário - exceto para os testes.
É salvo apenas remover b()
e todos os testes que o usaram? Isso faz parte de "melhorar a legibilidade"?
unit-testing
refactoring
tdd
readability
TobiMcNamobi
fonte
fonte
Respostas:
Sim, claro. O código mais fácil de ler é aquele que não existe.
Dito isto, refatorar geralmente significa melhorar o código sem alterar seu comportamento. Se você pensa em algo que melhora o código, faça-o. Não há necessidade de encaixá-lo em algum buraco de pombo antes que você possa fazê-lo.
fonte
Remover um método público não é "refatoração" - a refatoração está alterando a implementação enquanto continua a passar nos testes existentes.
No entanto, a remoção de um método desnecessário é uma alteração de design perfeitamente razoável.
O TDD explica isso até certo ponto, porque, ao revisar os testes, você pode observar que está testando um método desnecessário. Os testes estão direcionando seu design, porque você pode ir "Veja, este teste não tem nada a ver com o meu objetivo".
Pode se revelar mais em níveis mais altos de teste, em conjunto com ferramentas de cobertura de código. Se você executar testes de integração com cobertura de código e ver que os métodos não estão sendo chamados, é uma pista que um método não é usado. A análise de código estático também pode indicar que os métodos não são usados.
Existem duas abordagens para remover um método; ambos trabalham em diferentes circunstâncias:
Exclua o método Siga os erros de compilação para excluir qualquer código e teste dependente. Se você achar que os testes afetados são descartáveis, efetue as alterações. Caso contrário, reverta.
Exclua os testes que considera obsoletos. Execute todo o seu conjunto de testes com cobertura de código. Exclua os métodos que não foram exercidos pelo conjunto de testes.
(Isso pressupõe que sua suíte de testes tenha uma boa cobertura para começar).
fonte
IMHO o ciclo TDD típico será assim:
escreva testes com falha para f () (provavelmente com base nos testes para b ()): os testes ficam vermelhos
implementar f () -> testes ficam verdes
refatorar : -> remover b () e todos os testes para b ()
Para a última etapa, considere remover b () primeiro e ver o que acontece (ao usar uma linguagem compilada, o compilador deve reclamar apenas dos testes existentes; caso contrário, os testes de unidade antigos para b falharão, por isso claro que você precisa removê-los também).
fonte
Sim.
O melhor, mais livre de erros e mais legível é o código que não existe. Esforce-se para escrever o máximo de código possível, cumprindo seus requisitos.
fonte
É desejável remover
b()
uma vez que não seja mais usado, pelo mesmo motivo que é desejável não adicionar funções não usadas em primeiro lugar. Quer você chame de "legibilidade" ou qualquer outra coisa, tudo o mais é igual, é uma melhoria no código que não contém nada para o que não seja útil. Por uma questão de ter pelo menos uma medida específica pela qual é melhor não tê-la, removê-la garante que seu custo futuro de manutenção após essa alteração seja zero!Não achei necessária nenhuma técnica especial para removê-la com seus testes, pois qualquer pensamento de substituição
b()
por algo novo deve, é claro, ser acompanhado por uma consideração de todo o código que está sendo chamado atualmenteb()
, e os testes são um subconjunto de "todo o código "A linha de raciocínio que geralmente funciona para mim é que, no momento em que percebo que isso
f()
se tornoub()
obsoleto,b()
deve ser pelo menos preterido, e estou procurando encontrar todas as chamadasb()
com a intenção de substituí-las por chamadas paraf()
, I considere também o código de teste . Especificamente, seb()
não for mais necessário, eu posso e devo remover seus testes de unidade.Você está certo de que nada me obriga a notar que
b()
não é mais necessário. É uma questão de habilidade (e, como diz Slim, relatórios de cobertura de código em testes de nível superior). Se apenas testes de unidade e nenhum teste funcional se referiremb()
, posso ser cautelosamente otimista de que não faz parte de nenhuma interface publicada e, portanto, removê-la não é uma mudança de quebra para nenhum código que não esteja sob meu controle direto.O ciclo vermelho / verde / refatorado não menciona explicitamente a remoção de testes. Além disso, a remoção
b()
viola o princípio de abrir / fechar, pois claramente seu componente está aberto para modificações. Portanto, se você quiser pensar nesta etapa como algo fora do TDD simples, vá em frente. Por exemplo, você pode ter algum processo para declarar um teste como "ruim", que pode ser aplicado neste caso para remover o teste, alegando que ele testa algo que não deveria estar lá (a função desnecessáriab()
).Acho que, na prática, a maioria das pessoas provavelmente permite que uma certa quantidade de redesenho seja realizada junto com um ciclo de vermelho / verde / refator, ou eles consideram que a remoção de testes de unidade redundantes é uma parte válida de um "refator", embora seja estritamente falando não é refatoração. Sua equipe pode decidir quanto drama e papelada devem ser envolvidos para justificar essa decisão.
De qualquer forma, se isso
b()
fosse importante, haveria testes funcionais para isso, e esses não seriam removidos levemente, mas você já disse que existem apenas testes de unidade. Se você não distinguir adequadamente entre testes de unidade (gravados no design interno atual do código, que você alterou) e testes funcionais (gravados em interfaces publicadas, que talvez você não queira alterar), será necessário ter mais cuidado sobre a remoção de testes de unidade.fonte
Uma coisa para sempre tentar lembrar é que agora estamos usando REPOSITÓRIOS DE CÓDIGO com CONTROLE DE VERSÃO. Na verdade, esse código excluído não se foi ... ainda está lá em algum lugar de uma iteração anterior. Então estrague tudo! Seja liberal com a tecla delete, porque você sempre pode voltar e recuperar esse método precioso e elegante que você pensou que poderia ser útil algum dia ... se isso acontecer algum dia. Está lá.
Obviamente, isso acompanha a advertência dos males e o perigo de versões não compatíveis com versões anteriores ... aplicativos externos que dependiam da implementação da sua interface, que agora ficam órfãos pelo seu código (repentinamente) obsoleto.
fonte