La copertura del codice evidenzia metodi inutilizzati: cosa devo fare?

59

Sono stato incaricato di aumentare la copertura del codice di un progetto Java esistente.

Ho notato che lo strumento di copertura del codice ( EclEmma ) ha evidenziato alcuni metodi che non vengono mai chiamati da nessuna parte.

La mia prima reazione è non di scrivere test unitari per questi metodi, ma per metterli in evidenza al mio line manager / team e chiedere perché queste funzioni sono lì per cominciare.

Quale sarebbe l'approccio migliore? Scrivi prove unitarie per loro o domanda perché sono lì?

    
posta Lucas T 28.05.2018 - 10:52
fonte

7 risposte

119
  1. Elimina.
  2. Commit.
  3. Dimenticate.

Motivazione:

  1. Il codice morto è morto. Per la sua stessa descrizione non ha scopo. Potrebbe aver avuto uno scopo a un certo punto, ma non c'è più, e quindi il codice dovrebbe sparire.
  2. Il controllo della versione garantisce che durante l'evento unico raro (che ho esperienza) qualcuno venga in seguito cercando il codice che può essere recuperato.
  3. Come effetto collaterale, puoi migliorare istantaneamente la copertura del codice senza fare nulla (a meno che il codice morto non venga testato, il che è raro).

Avvertenza dai commenti: la risposta originale presupponeva che tu avessi verificato accuratamente che il codice è, senza dubbio, morto. Gli IDE sono fallibili e ci sono diversi modi in cui il codice che sembra morto potrebbe in effetti essere chiamato. Fai entrare un esperto a meno che tu non sia assolutamente sicuro.

    
risposta data 28.05.2018 - 10:58
fonte
55

Tutte le altre risposte si basano sul presupposto che i metodi in questione siano davvero inutilizzati. Tuttavia, la domanda non ha specificato se questo progetto è autonomo o una libreria di qualche tipo.

Se il progetto in questione è una libreria, i metodi apparentemente inutilizzati possono essere utilizzati al di fuori del progetto e rimuoverli interromperà gli altri progetti. Se la libreria stessa viene venduta ai clienti o resa disponibile pubblicamente, potrebbe essere addirittura impossibile rintracciare l'utilizzo di questi metodi.

In questo caso, ci sono quattro possibilità:

  • Se i metodi sono privati o pacchetti-privati, possono essere rimossi in sicurezza.
  • Se i metodi sono pubblici, la loro presenza può essere giustificata anche in assenza di un utilizzo effettivo, per la completezza della funzionalità. Dovrebbero comunque essere testati.
  • Se i metodi sono pubblici e non necessari, rimuoverli sarà un cambiamento irrisolto e se la libreria segue versioning semantico , questo è consentito solo in una nuova versione principale.
  • In alternativa, i metodi pubblici possono anche essere deprecati e rimossi successivamente. Questo dà un po 'di tempo per gli utenti API di passare dalle funzioni deprecate prima che vengano rimosse nella prossima versione principale.
risposta data 28.05.2018 - 18:02
fonte
31

Innanzitutto controlla che lo strumento di copertura del codice sia corretto.

Ho avuto situazioni in cui non hanno rilevato metodi richiamati tramite riferimenti all'interfaccia, o se la classe è caricata dinamicamente da qualche parte.

    
risposta data 28.05.2018 - 12:04
fonte
15

Poiché Java è compilato staticamente, dovrebbe essere abbastanza sicuro rimuovere i metodi. La rimozione del codice morto è sempre buona. C'è una certa probabilità che ci sia un pazzo sistema di reflection che li esegue in runtime, quindi controlla prima con altri sviluppatori, ma altrimenti rimuovili.

    
risposta data 28.05.2018 - 10:59
fonte
9

What would the best approach be? Write unit tests for them, or question why they're there?

Eliminare il codice è una buona cosa.

Quando non riesci a eliminare il codice, puoi sicuramente contrassegnarlo come @Deprecated , che documenta la versione principale che hai come obiettivo rimuovere il metodo. Quindi puoi eliminarlo "dopo". Nel frattempo, sarà chiaro che non dovrebbe essere aggiunto alcun nuovo codice che dipenda da questo.

Non consiglierei di investire in metodi deprecati, quindi nessun nuovo test unitario solo per colpire obiettivi di copertura.

La differenza tra i due è principalmente se i metodi fanno parte o meno dell'interfaccia pubblicata . L'eliminazione arbitraria di parti dell'interfaccia pubblicata può costituire una spiacevole sorpresa per i consumatori che dipendevano dall'interfaccia.

Non posso parlare ad Eclemma, ma dalle mie esperienze una delle cose di cui bisogna fare attenzione è la riflessione. Se, ad esempio, utilizzi i file di configurazione del testo per scegliere a quali classi / metodi accedere, la distinzione usata / non utilizzata potrebbe non essere ovvia (sono stato bruciato da quella volta accoppiata).

Se il tuo progetto è una foglia nel grafico delle dipendenze, il caso della deprecazione è indebolito. Se il tuo progetto è una libreria, allora il caso della deprecazione è più strong.

Se la tua azienda utilizza un mono-repo , l'eliminazione è un rischio inferiore rispetto al caso multi-repo.

Come indicato da l0b0 , se i metodi sono già disponibili nel controllo del codice sorgente, recuperarli dopo l'eliminazione è un passo avanti esercizio. Se fossi davvero preoccupato di doverlo fare, pensa a come organizzare i tuoi commit in modo che tu possa recuperare le modifiche cancellate se ne hai bisogno.

Se l'incertezza è abbastanza alta, potresti considerare commentare il codice , piuttosto che eliminarlo. È un lavoro extra nel percorso felice (in cui il codice eliminato non viene mai ripristinato), ma rende più facile il ripristino. La mia ipotesi è che dovresti preferire un'eliminazione diretta fino a quando non sei stato masterizzato da questo un paio di volte, il che ti fornirà alcune informazioni su come valutare "l'incertezza" in questo contesto.

question why they're there?

Il tempo investito nel catturare la tradizione non è necessariamente sprecato. Sono stato conosciuto per eseguire una rimozione in due passaggi: in primo luogo, aggiungendo e inserendo un commento che spieghi cosa abbiamo appreso sul codice e poi eliminando il codice (e il commento).

Potresti anche usare qualcosa di analogo ai record di decisioni architettoniche come modo per catturare la tradizione con il codice sorgente.

    
risposta data 28.05.2018 - 16:27
fonte
9

Uno strumento di copertura del codice non è onnisciente, onniveggente. Solo perché il tuo strumento afferma che il metodo non viene chiamato, ciò non significa che non sia chiamato. C'è una riflessione e, a seconda della lingua, ci possono essere altri modi per chiamare il metodo. In C o C ++ potrebbero esserci macro che costruiscono nomi di funzioni o metodi e lo strumento potrebbe non vedere la chiamata. Quindi il primo passo sarebbe: fare una ricerca testuale per il nome del metodo e per i nomi correlati. Chiedi ai colleghi esperti. Potresti scoprire che è effettivamente usato.

Se non sei sicuro, metti un assert () all'inizio di ogni metodo "inutilizzato". Forse viene chiamato. O una dichiarazione di registrazione.

Forse il codice è davvero prezioso. Potrebbe essere un nuovo codice su cui un collega ha lavorato per due settimane, e che lui o lei avrebbe acceso domani. Non è chiamato oggi perché la chiamata verrà aggiunta domani.

Forse il codice è in realtà una parte preziosa 2: il codice potrebbe eseguire alcuni test di runtime molto costosi che potrebbero trovare le cose che vanno storte. Il codice viene attivato solo se le cose vanno veramente male. È possibile che si stia eliminando un prezioso strumento di debug.

È interessante notare che il peggior consiglio possibile "Elimina, commetti, dimentica". è il più votato (Recensioni del codice? Non si eseguono revisioni del codice? Che diavolo stai facendo in programmazione se non esegui le revisioni del codice?)

    
risposta data 28.05.2018 - 20:33
fonte
6

A seconda dell'ambiente in cui viene eseguito il software, è possibile accedere se il metodo viene mai chiamato. Se non viene chiamato entro un periodo di tempo adeguato, il metodo può essere rimosso in modo sicuro.

Si tratta di un approccio più cauto rispetto alla semplice eliminazione del metodo e potrebbe essere utile se si esegue un ambiente altamente sensibile ai guasti.

Accediamo a un canale di% #unreachable-code dedicato con un identificativo univoco per ciascun candidato per la rimozione, ed è risultato essere piuttosto efficace.

    
risposta data 28.05.2018 - 19:26
fonte

Leggi altre domande sui tag