A cobertura do código destaca métodos não utilizados - o que devo fazer?


59

Fui encarregado de aumentar a cobertura de código de um projeto Java existente.

Notei que a ferramenta de cobertura de código ( EclEmma ) destacou alguns métodos que nunca são chamados de qualquer lugar.

Minha reação inicial não é escrever testes de unidade para esses métodos, mas destacá-los para meu gerente / equipe de linha e perguntar por que essas funções existem para começar.

Qual seria a melhor abordagem? Escreva testes de unidade para eles ou pergunte por que eles estão lá?


1
Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
maple_shaft

Respostas:


118
  1. Excluir.
  2. Cometer, entregar.
  3. Esqueço.

Fundamentação da petição:

  1. Código morto está morto. Por sua própria descrição, não tem propósito. Pode ter um objetivo em um ponto, mas isso se foi e, portanto, o código deveria ter desaparecido.
  2. O controle de versão garante que, no (na minha experiência) raro evento único, que alguém chegue mais tarde procurando esse código, ele possa ser recuperado.
  3. Como efeito colateral, você melhora instantaneamente a cobertura do código sem fazer nada (a menos que o código morto seja testado, o que raramente é o caso).

Advertência a partir dos comentários: A resposta original supunha que você tinha verificado completamente que o código está, sem dúvida, morto. Os IDEs são falíveis e existem várias maneiras pelas quais o código que parece morto pode ser chamado. Traga um especialista, a menos que tenha certeza absoluta.


118
Geralmente, eu concordo com essa abordagem, mas se você é novo em um projeto e / ou desenvolvedor júnior, é melhor perguntar ao seu mentor / superior antes de excluir. Dependendo do projeto, alguns métodos podem não parecer usados, mas podem ser chamados / usados ​​por código externo que não está no código do projeto ao qual você tem acesso. Pode ser um código gerado automaticamente, para que sua remoção alcance apenas o ruído do histórico de log. Seu IDE pode não conseguir encontrar acesso baseado em reflexão de dentro do projeto. Etc. pp. Se você não tem certeza sobre esses casos de canto, pergunte pelo menos uma vez.
Frank Hopkins

11
Embora eu concorde com o núcleo desta resposta, a pergunta literal era "devo questionar por que eles estão lá?" . Essa resposta pode dar a impressão de que o OP não deve perguntar à equipe antes de excluir.
Doc Brown

58
Eu adicionaria uma etapa primeiro - verifique o log de culpa do git para obter as linhas de código não utilizadas. Se você encontrar a pessoa que as escreveu, poderá perguntar para que servem. Se as linhas forem novas, há uma boa chance de alguém estar planejando usá-las em breve (nesse caso, elas provavelmente devem ser testadas em unidade agora).
Bdsl # 28/18

10
Há tantas coisas erradas nessa resposta, expressas em comentários ou outras respostas, que não acredito que essa seja a resposta mais votada e aceita.
User949300

11
@Emory A melhor maneira de começar em uma nova equipe é quebrar a compilação excluindo descuidadamente as coisas, porque você achava que ninguém precisava delas. Garante que você é popular do dia 1. Claro que pode não ser necessário (porque cada aplicação grande, mais velho tem sempre 100% código de cobertura tosse ), mas isso é uma péssima ROI.
Voo 29/05

55

Todas as outras respostas são baseadas na suposição de que os métodos em questão são realmente não utilizados. No entanto, a pergunta não especificou se esse projeto é independente ou se é uma biblioteca de algum tipo.

Se o projeto em questão for uma biblioteca, os métodos aparentemente não utilizados podem ser usados ​​fora do projeto e removê-los quebraria esses outros projetos. Se a própria biblioteca for vendida aos clientes ou disponibilizada publicamente, pode ser impossível rastrear o uso desses métodos.

Nesse caso, existem quatro possibilidades:

  • Se os métodos forem privados ou privados de pacotes, eles poderão ser removidos com segurança.
  • Se os métodos forem públicos, sua presença poderá ser justificada mesmo sem uso real, para garantir a integridade dos recursos. Eles devem ser testados embora.
  • Se os métodos forem públicos e desnecessários, removê-los será uma mudança significativa e se a biblioteca seguir o controle de versão semântico , isso será permitido apenas em uma nova versão principal.
  • Como alternativa, os métodos públicos também podem ser preteridos e removidos posteriormente. Isso dá algum tempo para que os consumidores da API façam a transição das funções obsoletas antes de serem removidas na próxima versão principal.

9
Além disso, se ele é uma biblioteca as funções estão lá para sermos mais completos
PlasmaHH

Você pode elaborar como eles devem ser testados? Se você não sabe por que o método existe, provavelmente não sabe o que ele deve fazer.
No U

Nomes de métodos como filter_name_exists, ReloadSettingsou addToSchema(escolhidos aleatoriamente em 3 projetos arbitrários de código-fonte aberto) devem fornecer algumas dicas sobre o que o método deve fazer. Um comentário javadoc pode ser ainda mais útil. Não é uma especificação adequada, eu sei, mas poderia ser suficiente para criar alguns testes que podem impedir pelo menos regressões.
Zoltan 30/05

1
métodos públicos em uma classe ou interface privada não devem ser considerados públicos para esse fim. Da mesma forma, se uma classe pública é aninhada dentro de uma classe privada, não é realmente pública.
Emory 31/05

30

Primeiro verifique se sua ferramenta de cobertura de código está correta.

Eu tive situações em que eles não perceberam os métodos chamados através de referências à interface ou se a classe é carregada dinamicamente em algum lugar.


Obrigado, vai fazer. No Eclipse, faço uma pesquisa na base de código para a função e nada aparece. Se você tiver outras sugestões de como fazer uma pesquisa mais abrangente, ficaria muito grato.
Lucas T

3
sim, você deve verificar outros projectos que pode importar a classe como uma dll
Ewan

7
Essa resposta parece incompleta. "Primeiro verifique se a sua ferramenta de cobertura de código está correta. Se estiver, então .... [insira o restante da resposta] ". Especificamente, o OP quer saber o que fazer se a ferramenta de cobertura de código estiver correta.
Jon Bentley

1
@jonbentley O OP está pedindo a melhor abordagem para o relatório de ferramentas. "Verifique manualmente" porque é bem óbvio do contexto que está incorreto
Ewan

15

Como o Java é compilado estaticamente, deve ser bastante seguro remover os métodos. A remoção de código morto é sempre boa. Há alguma probabilidade de que exista algum sistema de reflexão maluco que os execute em tempo de execução; portanto, verifique primeiro com outros desenvolvedores, mas remova-os.


9
+1 para verificar com as pessoas, é meio que seguir o princípio da menor surpresa. Você não quer que alguém gaste muito tempo procurando o método que foi deixado lá alguns commits anteriormente. Além disso, em alguns casos extremos, o código morto pode ser o material novo que já está registrado, mas ainda não foi conectado a nenhum lugar (embora, nesse caso, deva ser bem documentado com comentários e testado).
Frax 28/05

4
Bem, a menos que o código use reflexão para chamar os métodos "não utilizados", mas nesse caso você tem problemas muito maiores, e estamos ansiosos para ver o código em thefailywft.com (faça um teste rápido para verificar se algum código usa um ClassName. classe).
MTilsted

2
Ele é estaticamente compilado, mas há também a invokedynamicinstrução, então, você sabe ...
corsiKa

@MTilsted: Existem muitas estruturas que chamarão o código usando strings - eu posso pensar em pelo menos o Spring e o Hibernate no topo da minha cabeça.
Jhominal 29/05

9

Qual seria a melhor abordagem? Escreva testes de unidade para eles ou pergunte por que eles estão lá?

Excluir código é uma coisa boa.

Quando você não pode excluir o código, certamente pode marcá-lo como @ Deprecated , documentando qual versão principal você está direcionando para remover o método. Então você pode excluí-lo "mais tarde". Nesse meio tempo, ficará claro que nenhum novo código deve ser adicionado que depende dele.

Eu não recomendaria investir em métodos obsoletos - portanto, não há novos testes de unidade apenas para atingir as metas de cobertura.

A diferença entre os dois é principalmente se os métodos fazem ou não parte da interface publicada . A exclusão arbitrária de partes da interface publicada pode ser uma surpresa desagradável para os consumidores que dependiam da interface.

Não posso falar com EclEmma, ​​mas, pelas minhas experiências, uma das coisas com as quais você precisa tomar cuidado é a reflexão. Se, por exemplo, você usar arquivos de configuração de texto para escolher quais classes / métodos acessar, a distinção usada / não utilizada pode não ser óbvia (fui queimado por isso algumas vezes).

Se o seu projeto for uma folha no gráfico de dependência, o caso de descontinuação será enfraquecido. Se o seu projeto for uma biblioteca, o caso de descontinuação será mais forte.

Se sua empresa usa um mono-repo , a exclusão é um risco menor do que no caso de vários repo.

Conforme observado por l0b0 , se os métodos já estiverem disponíveis no controle de origem, recuperá-los após a exclusão é um exercício direto. Se você estava realmente preocupado com a necessidade de fazer isso, pense em como organizar seus commits para que você possa recuperar as alterações excluídas, se precisar delas.

Se a incerteza for alta o suficiente, considere comentar o código , em vez de excluí-lo. É um trabalho extra no caminho feliz (onde o código excluído nunca é restaurado), mas facilita a restauração. Meu palpite é que você deve preferir uma exclusão direta até que você se queime por isso algumas vezes, o que lhe dará algumas idéias sobre como avaliar a "incerteza" nesse contexto.

pergunta por que eles estão lá?

O tempo investido na captura do conhecimento não é necessariamente desperdiçado. Soube realizar uma remoção em duas etapas: primeiro, adicionando e enviando um comentário explicando o que aprendemos sobre o código e, em seguida, excluindo o código (e o comentário).

Você também pode usar algo análogo aos registros de decisão arquitetônicos como uma maneira de capturar o conhecimento com o código-fonte.


9

Uma ferramenta de cobertura de código não é onisciente, onisciente. Só porque sua ferramenta afirma que o método não é chamado, isso não significa que não é chamado. Há reflexão e, dependendo do idioma, pode haver outras maneiras de chamar o método. Em C ou C ++, pode haver macros que constroem nomes de função ou método, e a ferramenta pode não ver a chamada. Portanto, o primeiro passo seria: faça uma pesquisa textual pelo nome do método e pelos nomes relacionados. Pergunte a colegas experientes. Você pode achar que é realmente usado.

Se você não tiver certeza, coloque um assert () no início de cada método "não utilizado". Talvez seja chamado. Ou uma declaração de log.

Talvez o código seja realmente valioso. Pode ser um novo código no qual um colega esteja trabalhando há duas semanas e que ele ligará amanhã. Não é chamado hoje porque o pedido será adicionado amanhã.

Talvez o código seja realmente valioso, parte 2: o código pode estar executando alguns testes de tempo de execução muito caros, capazes de descobrir que as coisas estão dando errado. O código é ativado apenas se as coisas realmente derem errado. Você pode estar excluindo uma valiosa ferramenta de depuração.

Curiosamente, o pior conselho possível "Excluir. Confirmar. Esqueça". é o mais alto classificado. (Revisões de código? Você não faz revisões de código? O que você está fazendo de programação se não faz revisões de código?)


Eu respeitosamente discordo de "EXCLUIR. COMPROMETIR. ESQUECER" ser o pior conselho. (Eu acho que é o melhor.) Sua abordagem também é boa. Eu acho que o pior conselho possível seria escrever testes de unidade que exercitem o "código morto", mas não façam afirmações. A ferramenta de cobertura de código será levada a pensar que eles são usados.
Emory 29/05

3
Nada na resposta "Excluir. Confirmar. Esquecer" diz para não fazer a revisão do código. É perfeitamente possível (e aconselhável, IMHO) revisar o código depois que ele foi confirmado (mas antes da implantação :-)).
Sleske

@sleske Como você revisa o código que não existe mais? Essa resposta também não menciona "revisão".
User949300

@ user949300: Se uma alteração de código precisa ou não ser revisada é uma pergunta separada e independente de o código ser adicionado, alterado ou excluído (adicionar código pode ser ainda mais desastroso do que excluí-lo, consulte, por exemplo, a vulnerabilidade Heartbleed). Além disso, a resposta (agora) diz "trazer um especialista", o que parece bem próximo de uma revisão de código.
Sleske

1
@ user949300: Quanto a "Como você revisa o código que não existe mais" - eu espero que seja óbvio: olhando a alteração na sua ferramenta de controle de versão de sua escolha. De que outra forma você revisaria as alterações (alguma alteração)?
Sleske #

6

Dependendo do ambiente em que o software é executado, é possível efetuar logon se o método for chamado. Se não for chamado dentro de um período de tempo adequado, o método poderá ser removido com segurança.

Essa é uma abordagem mais cautelosa do que apenas excluir o método e pode ser útil se você estiver executando em um ambiente altamente sensível a falhas.

Registramos em um #unreachable-codecanal de folga dedicado com um identificador exclusivo para cada candidato a remoção, e provou ser bastante eficaz.



então "um período de tempo adequado" é mais longo (embora eu goste de um "homem depois da meia-noite") #
Jamie Bull
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.