Eventuali strumenti / suggerimenti su come confutare l'argomento sulla qualità della copertura del codice


11

Ora so che le persone potrebbero considerare questa domanda duplicata o posta più volte, nel qual caso apprezzerei un collegamento a domande pertinenti con la risposta alla mia domanda.

Sono stato recentemente in disaccordo con alcune persone sulla copertura del codice. Ho un gruppo di persone che vogliono far cadere il nostro team guardando la copertura del codice sulla base dell'argomento che una copertura del 100% non significa test di buona qualità e quindi un codice di buona qualità.

Sono stato in grado di respingere vendendo l'argomento secondo cui la copertura del codice mi dice cosa non è stato testato di sicuro e ci aiuta a concentrarci su quelle aree.

(Quanto sopra è stato discusso in modo simile in altre domande SO come questa - /programming/695811/pitfalls-of-code-coverage )

L'argomento di queste persone è che il team reagirebbe creando rapidamente test di bassa qualità e quindi perdere tempo senza aggiungere una qualità significativa.

Mentre capisco il loro punto di vista, sto cercando un modo per rendere più solida la copertura del codice introducendo strumenti / framework più solidi che si occupino di più criteri di copertura (Functional, Statement,Decision, Branch, Condition, State, LCSAJ, path, jump path, entry/exit, Loop, Parameter Value etc) .

Quello che sto cercando è un suggerimento per una combinazione di tali strumenti di copertura del codice e pratiche / processi da accompagnare che possa aiutarmi a contrastare tali argomenti mentre mi sento a mio agio con la mia raccomandazione.

Accolgo con favore anche eventuali commenti / suggerimenti di accompagnamento basati sulla tua esperienza / conoscenza su come contrastare tale argomento, perché mentre soggettiva, la copertura del codice ha aiutato il mio team a essere più consapevole della qualità del codice e del valore dei test.


Modifica: per ridurre la confusione sulla mia comprensione della debolezza della copertura tipica del codice, voglio sottolineare che non mi riferisco agli strumenti Statement Coverage (o alle linee di codice eseguite) (ce ne sono molti). In effetti ecco un buon articolo su tutto ciò che non va: http://www.bullseye.com/statementCoverage.html

Stavo cercando qualcosa di più di una semplice dichiarazione o copertura di linea, approfondendo più criteri e livelli di copertura.

Vedi: http://en.wikipedia.org/wiki/Code_coverage#Coverage_criteria

L'idea è che se uno strumento può dirci la nostra copertura sulla base di più criteri, ciò diventa una ragionevole valutazione automatizzata della qualità del test. Non sto assolutamente cercando di dire che la copertura della linea sia una buona valutazione. In realtà questa è la premessa della mia domanda.


Modifica:
Ok, forse l'ho proiettato un po 'troppo drammaticamente, ma hai capito. Il problema riguarda l'impostazione di processi / politiche in generale in tutti i team in modo omogeneo / coerente. E la paura è generale di come garantire la qualità dei test, come allocare tempo garantito senza avere alcuna misura ad esso. Quindi mi piace avere una caratteristica misurabile che, se eseguito il backup con processi appropriati e gli strumenti giusti, ci consentirebbe di migliorare la qualità del codice pur sapendo che il tempo non viene speso in processi dispendiosi.


EDIT: finora quello che ho dalle risposte:

  • Le revisioni del codice dovrebbero coprire i test per garantire la qualità dei test
  • Test La prima strategia aiuta a evitare i test scritti dopo il fatto per aumentare semplicemente la copertura%
  • Esplorazione di strumenti alternativi che coprono criteri di test diversi dalla semplice dichiarazione / linea
  • L'analisi del codice coperto / numero di bug rilevati contribuirebbe ad apprezzare l'importanza della copertura e fornire un caso migliore
  • Soprattutto, fidati del contributo del Team per fare la cosa giusta e lottare per le loro convinzioni
  • Blocchi coperti / N. di test - Discutibile ma con un certo valore

Grazie per le fantastiche risposte finora. Li apprezzo davvero. Questo filo è meglio di ore di brainstorming con i poteri che sono.


4
Nessuno da nessuna parte suggerisce di incontrare una copertura del codice del 100% , che è davvero una folle commissione.
Jimmy Hoffa,

1
Grazie. E lo so già e lo riconosco. E anche le persone tendono ad associare la copertura del codice al 100% con una copertura del 100% (o linea) in genere. Inoltre non ha resistito - Jimmy, ti stavano cercando dappertutto.
MickJ,

3
"allora il team reagirebbe creando rapidamente test di bassa qualità e quindi perdere tempo senza aggiungere una qualità significativa" - ottimo team!
Piotr Perak,

Ok, forse l'ho proiettato un po 'troppo drammaticamente, ma hai capito. Il problema riguarda l'impostazione di processi / politiche in generale in tutti i team in modo omogeneo / coerente. E la paura è generale di come garantire la qualità dei test, come allocare tempo garantito senza avere alcuna misura ad esso. Quindi mi piace avere una caratteristica misurabile che, se eseguito il backup con processi appropriati e gli strumenti giusti, ci consentirebbe di migliorare la qualità del codice pur sapendo che il tempo non viene speso in processi dispendiosi.
MickJ,

1
@JimmyHoffa - Il software per lo spazio critico di solito richiede una copertura del codice del 100%.
mouviciel,

Risposte:


9

In base alla mia esperienza, la copertura del codice è utile quanto la realizzi . Se scrivi buoni test che coprono tutti i tuoi casi, superare questi test significa che hai soddisfatto i tuoi requisiti. In realtà questa è l' idea esatta che utilizza Test Driven Development . Scrivi i test prima del codice senza sapere nulla sull'implementazione (a volte questo significa che un altro team scrive interamente i test). Questi test sono impostati per verificare che il prodotto finale faccia tutto quello che le tue specifiche dicono che è stato fatto, e POI scrivi il codice minimo per superare quei test.

Il problema qui, ovviamente, è che se i tuoi test non sono abbastanza forti, perderai casi limite o problemi imprevisti e scriverai codice che non soddisfa veramente le tue specifiche. Se sei veramente impegnato ad usare i test per verificare il tuo codice, allora scrivere buoni test è una necessità assoluta, o stai davvero perdendo tempo.

Volevo modificare la risposta qui perché mi sono reso conto che non ha veramente risposto alla tua domanda. Vorrei leggere quell'articolo wiki per vedere alcuni dei benefici dichiarati di TDD. Dipende da come la tua organizzazione funziona meglio, ma TDD è sicuramente qualcosa in uso nel settore.


+1 per il suggerimento che la scrittura dei test migliora innanzitutto la qualità dei test, quindi una combinazione di Test prima con Copertura del codice è sicuramente utile.
MickJ,

Sì, ho sempre scoperto che se scrivi i test dopo aver sviluppato il codice, testerai solo le cose che sai che il tuo codice passerà, o scriverai i test in un modo che complimenta l'implementazione, che davvero non aiuta nessuno. Se scrivi i tuoi test indipendentemente dal codice, ti concentri su ciò che il codice dovrebbe fare piuttosto che su ciò che fa .
Approvato il

Grazie @Ampt. Oltre a rafforzare il processo con TDD, ci sono strumenti di copertura del codice che consigli, che si occupano di più criteri di copertura in modo più esaustivo, contribuendo così a convalidare la qualità dei test scritti almeno in una certa misura?
MickJ,

Potrei capirti in modo errato, ma stai suggerendo che strumenti diversi ti diranno una copertura diversa per i tuoi test? È sempre stata la mia esperienza che gli strumenti di copertura guardano solo l'esecuzione dei test e registrano quali righe di codice vengono eseguite. Gli strumenti di commutazione non dovrebbero quindi avere alcun impatto sulla copertura, poiché il numero di linee eseguite rimane lo stesso. Diffiderei di uno strumento che offre maggiore copertura per lo stesso test. Detto questo, non credo che colpire ogni riga di codice sia una buona valutazione della qualità del test in quanto è completezza . I buoni test provengono da buoni requisiti.
Approvato il

Grazie. Quello a cui ti riferisci è Statement Coverage(o righe di codice eseguite). Stavo cercando qualcosa di più della semplice copertura delle dichiarazioni o delle linee, andando più in profondità nei multiple coverage criterialivelli. Vedi: en.wikipedia.org/wiki/Code_coverage#Coverage_criteria e en.wikipedia.org/wiki/Linear_Code_Sequence_and_Jump . L'idea è che se uno strumento può dirci la nostra copertura sulla base di più criteri, ciò diventa una ragionevole valutazione automatizzata della qualità del test. Non sto assolutamente cercando di dire che la copertura della linea sia una buona valutazione. In realtà questa è la premessa della mia domanda.
MickJ,

6

Prima di tutto, le persone fanno avvocato copertura del 100%:

La maggior parte degli sviluppatori considera adeguata la "copertura delle dichiarazioni al 100%". Questo è un buon inizio, ma difficilmente sufficiente. Un ID standard di copertura migliore per soddisfare la cosiddetta "copertura filiale al 100%", ...

Steve McConnell, Codice completo , Capitolo 22: Test degli sviluppatori.

Come hai già detto tu e altri, la copertura del codice per il solo scopo di ottenere una copertura da sola non è molto probabile. Ma se non riesci a far eseguire una riga di codice, perché è scritta?

Suggerirei di risolvere l'argomento raccogliendo e analizzando i dati sui tuoi progetti.

Per raccogliere i dati, utilizzo personalmente i seguenti strumenti:

  • JaCoCo e il plug-in Eclipse associato EclEmma per misurare la copertura del codice.
  • Ant script per la costruzione automatizzata, test e reporting.
  • Jenkins per build continue: qualsiasi modifica al controllo del codice sorgente genera una build automatica
  • Plugin JaCoCo per Jenkins: acquisisce le metriche di copertura per ogni build e traccia i grafici delle tendenze. Consente inoltre la definizione di soglie di copertura per progetto che influiscono sullo stato di integrità della build.
  • Bugzilla per il monitoraggio dei bug.

Una volta che hai installato questo (o qualcosa di simile), puoi iniziare a esaminare i tuoi dati più da vicino:

  • sono stati trovati più bug in progetti scarsamente coperti?
  • sono stati trovati più bug in classi / metodi scarsamente coperti?
  • eccetera.

Mi aspetto che i suoi dati potranno sostenere la propria posizione sulla copertura del codice; quella è stata sicuramente la mia esperienza. In caso contrario, tuttavia, forse la tua organizzazione può avere successo con standard di copertura del codice inferiori a quelli che desideri. O forse i tuoi test non sono molto buoni. Si spera che l'attività si concentri sullo sviluppo di software con meno difetti, indipendentemente dalla risoluzione del disaccordo sulla copertura del codice.


Mi piace molto questa risposta. Grazie per i suggerimenti sugli strumenti e, cosa più importante, mi piace l'idea dell'approccio basato sui dati per giustificare la copertura del codice. Anche se tendo a prendere le parole dei team sul valore di esso e non lo metterei in discussione comunque. Può forse aiutarmi a costruire un caso più solido per la nostra esperienza finora. Grazie!
MickJ,

4

L'argomento di queste persone è che il team reagirebbe creando rapidamente test di bassa qualità e quindi perdere tempo senza aggiungere una qualità significativa.

Questo è un problema di fiducia , non di strumenti .

Chiedi loro perché, se credessero davvero in quella affermazione, si sarebbero fidati del team di scrivere qualsiasi codice?


Perché sanno che la funzionalità del codice è la linea di fondo, quindi: test, documentazione, commenti, recensioni, ecc. Possono essere sacrificati senza conseguenze immediate; anche se sono d'accordo, è un brutto segno.
JeffO,

Ok, forse l'ho proiettato un po 'troppo drammaticamente, ma hai capito. Il problema riguarda l'impostazione di processi / politiche in generale in tutti i team in modo omogeneo / coerente. E la paura è generale di come garantire la qualità dei test, come allocare tempo garantito senza avere alcuna misura ad esso. Quindi mi piace avere una caratteristica misurabile che, se eseguito il backup con processi appropriati e gli strumenti giusti, ci consentirebbe di migliorare la qualità del codice pur sapendo che il tempo non viene speso in processi dispendiosi.
MickJ,

3

Ok, forse l'ho proiettato un po 'troppo drammaticamente, ma hai capito. Il problema riguarda l'impostazione di processi / politiche in generale in tutti i team in modo omogeneo / coerente.

Penso che sia questo il problema. Gli sviluppatori non si preoccupano (e spesso per eccellenti ragioni) di politiche coerenti o globali e vogliono la libertà di fare ciò che ritengono giusto piuttosto che aderire alle politiche aziendali.

Il che è ragionevole se non si dimostra che i processi e le misure globali hanno valore e un effetto positivo sulla qualità e sulla velocità di sviluppo.

Cronologia normale:

  1. dev: hey, guarda - Ho aggiunto le metriche di copertura del codice alla nostra dashboard, non è fantastico?
  2. manager: certo, aggiungiamo obiettivi obbligatori e conformità su quelli
  3. dev: non importa, la copertura del codice è stupida e inutile, lasciamo perdere

1
+1 Ho visto così troppe volte per non essere d'accordo. Nel mio caso, anche se la conversazione va un po 'così dev: hey, guarda - Ho aggiunto le metriche di copertura del codice alla nostra dashboard, non è fantastico? manager: certo, tutto ciò che pensate migliora la qualità è eccezionale. Responsabile capo dei manager: Penso che dobbiamo avere un processo tra i team. Penso che la copertura del codice sia inutile a meno che non possiamo garantire valore dal costo speso.
MickJ,

2

Nella mia esperienza, ci sono alcune cose da combinare con la copertura del codice per rendere utile la metrica:

Recensioni di codice

Se riesci a puntare i test errati allo sviluppatore, può aiutare a limitare il numero di test errati che forniscono questa copertura insignificante.

Tracciamento dei bug

Se hai un sacco di copertura del codice su un modulo, ma hai ancora molti / gravi bug in quell'area, allora potrebbe indicare un problema in cui quello sviluppatore ha bisogno di miglioramenti con i suoi test.

pragmatica

Nessuno arriverà al 100% con buoni test su codice non banale. Se come capo squadra guardate la copertura del codice, ma invece di dire "dobbiamo arrivare all'N%!" identifichi lacune e chiedi alle persone di "migliorare la copertura nel modulo X" che raggiunga il tuo obiettivo senza offrire alle persone l'opportunità di giocare con il sistema.

Blocchi coperti / N. di test

La maggior parte degli strumenti di copertura del codice elenca i blocchi coperti contro i blocchi non coperti. La combinazione di questo con il numero di test effettivi consente di ottenere una metrica che indica quanto siano "ampi" i test, che indicano test errati o progettazione accoppiata. Questo è più utile come delta da uno sprint a un altro, ma l'idea è la stessa: combina la copertura del codice con altre metriche per ottenere maggiori informazioni.


+1 Buoni suggerimenti, in particolare mi piacciono i blocchi coperti / il numero di test e le revisioni del codice. Sebbene facciamo già revisioni del codice, sarebbe utile sottolineare l'importanza di rivedere i test più da vicino.
MickJ,

2

Ecco i miei 2 centesimi.

Ci sono molte pratiche che hanno ricevuto molta attenzione di recente perché possono apportare benefici allo sviluppo del software. Tuttavia, alcuni sviluppatori applicano queste pratiche alla cieca: sono convinti che applicare una metodologia sia come eseguire un algoritmo e che dopo aver eseguito i passaggi corretti si dovrebbe ottenere il risultato desiderato.

Qualche esempio:

  • Scrivi test unitari con una copertura del codice del 100% e otterrai una migliore qualità del codice.
  • Applica TDD in modo sistematico e otterrai un design migliore.
  • Abbina la programmazione e migliorerai la qualità del codice e ridurrai i tempi di sviluppo.

Penso che il problema di base con le affermazioni di cui sopra sia che gli umani non sono computer e scrivere software non è come eseguire un algoritmo.

Quindi, le affermazioni di cui sopra contengono alcune verità ma semplificano un po 'troppo le cose, ad esempio:

  • I test unitari rilevano molti errori e la copertura del codice indica quali parti del codice vengono testate, ma testare cose banali è inutile. Ad esempio, se facendo clic su un pulsante si apre la finestra di dialogo corrispondente, l'intera logica che invia l'evento del pulsante al componente che apre la finestra di dialogo può essere testata da un semplice test manuale (fare clic sul pulsante): paga all'unità testare questa logica?
  • Mentre TDD è un buon strumento di progettazione, non funziona bene se lo sviluppatore ha una scarsa comprensione del dominio del problema (vedi ad esempio questo famoso post ).
  • La programmazione della coppia è efficace se due sviluppatori possono lavorare insieme, altrimenti è un disastro. Inoltre, gli sviluppatori esperti potrebbero preferire discutere brevemente i problemi più importanti e quindi programmare separatamente: passare molte ore a discutere molti dettagli che entrambi sanno già che può essere sia noioso che una grande perdita di tempo.

Tornando alla copertura del codice.

Sono stato in grado di respingere vendendo l'argomento secondo cui la copertura del codice mi dice cosa non è stato testato di sicuro e ci aiuta a concentrarci su quelle aree.

Penso che devi valutare caso per caso se vale la pena avere una copertura del 100% per un determinato modulo.

Il modulo esegue alcuni calcoli molto importanti e complicati? Quindi vorrei testare ogni singola riga di codice ma anche scrivere unit test significativi (unit test che hanno senso in quel dominio).

Il modulo svolge attività importanti ma semplici come l'apertura di una finestra di aiuto quando si fa clic su un pulsante? Un test manuale sarà probabilmente più efficace.

L'argomento di queste persone è che il team reagirebbe creando rapidamente test di bassa qualità e quindi perdere tempo senza aggiungere una qualità significativa.

Secondo me hanno ragione: non è possibile applicare la qualità del codice solo richiedendo una copertura del codice del 100%. L'aggiunta di più strumenti per calcolare la copertura e fare statistiche non aiuterà. Piuttosto, dovresti discutere quali parti del codice sono più sensibili e dovrebbero essere testate ampiamente e quali sono meno soggette a errori (nel senso che un errore può essere scoperto e risolto molto più facilmente senza usare i test unitari).

Se invii una copertura del codice del 100% agli sviluppatori, alcuni inizieranno a scrivere test di unità stupidi per adempiere ai loro obblighi invece di provare a scrivere test sensati.

come allocare tempo garantito senza avere alcuna misura ad esso

Forse è un'illusione che tu possa misurare l'intelligenza e il giudizio umani. Se hai colleghi competenti e ti fidi del loro giudizio, puoi accettare quando ti dicono "per questo modulo, aumentare la copertura del codice porterà pochissimi benefici. Quindi non dedichiamoci del tempo" o ", per questo modulo abbiamo bisogno più copertura possibile, abbiamo bisogno di una settimana in più per implementare test unitari sensibili ".

Quindi (di nuovo, questi sono i miei 2 centesimi): non cercare di trovare un processo e impostare parametri come la copertura del codice che deve adattarsi a tutti i team, a tutti i progetti e a tutti i moduli. Trovare un processo così generale è un'illusione e credo che quando ne avrai trovato uno non sarà ottimale.


Tutto vero e sono già d'accordo. Se noti che non supporto la copertura del codice al 100%. Si tratta di migliorare il suo valore utilizzando tecniche, strumenti e processi di scommessa. Aiuta anche a comprendere appieno i criteri di copertura del codice (la maggior parte assume che si tratti di una riga / istruzione). +1 per il tuo eccellente post.
MickJ,

2

"il team reagirebbe creando rapidamente test di bassa qualità e quindi perdere tempo senza aggiungere una qualità significativa"

Questo è un rischio reale, non solo teorico.

L'eccesso di codice da solo è una metrica disfunzionale. Ho imparato quella lezione nel modo più duro. Una volta l'ho sottolineato senza la disponibilità di metriche o pratiche di bilanciamento. Centinaia di test che catturano e mascherano le eccezioni, e senza affermazioni è una cosa brutta.

"suggerimento per una combinazione di tali strumenti di copertura del codice e pratiche / processi da accompagnare"

Oltre a tutti gli altri suggerimenti, esiste una tecnica di automazione in grado di valutare la qualità dei test: test di mutazione ( http://en.wikipedia.org/wiki/Mutation_testing ). Per il codice Java, PIT ( http://pitest.org/ ) funziona, ed è il primo strumento di test di mutazione che ho incontrato che fa.

Come notate, la mancanza di copertura del codice è facilmente identificabile come un rischio di qualità del software. Insegno che la copertura del codice è una condizione necessaria, ma insufficiente, per la qualità del software. Dobbiamo adottare un approccio bilanciato di scorecard alla gestione della qualità del software.


1

La copertura del codice non è certamente una prova di buoni test unitari, in quanto sono corretti.

Ma a meno che non possano fornire un modo per dimostrare che tutti i test unitari sono buoni (per qualsiasi definizione di bene possano trovare), questo è davvero un punto muto.


2
I punti che non parlano tendono ad essere discutibili . (Mi piace solo il gioco di parole lì - la mia ortografia è spesso corretta).

1

Ho sempre scoperto che la copertura del codice è facilmente suscettibile all'effetto Hawthorne . Questo mi ha fatto chiedere "perché abbiamo delle metriche del software?" e la risposta di solito è fornire una comprensione di alto livello dello stato attuale del progetto, cose come:

"quanto siamo vicini?"

"come è la qualità di questo sistema?"

"quanto sono complicati questi moduli?"

Purtroppo, non ci sarà mai una sola metrica in grado di dirti quanto sia buono o cattivo il progetto e qualsiasi tentativo di ricavare quel significato da un singolo numero sarà necessariamente semplificato. Sebbene le metriche riguardino tutti i dati, interpretare ciò che significano è un compito molto più emotivo / psicologico e come tale probabilmente non può essere applicato genericamente tra team di composizione diversa o problemi di domini diversi.

Nel caso della copertura penso che sia spesso usato come proxy per la qualità del codice, anche se rozzo. E il vero problema è che si riduce un argomento terribilmente complicato a un singolo numero intero compreso tra 0 e 100, che ovviamente verrà utilizzato per condurre un lavoro potenzialmente inutile in una ricerca senza fine per ottenere una copertura del 100%. Gente come Bob Martin dirà che la copertura del 100% è l'unico obiettivo serio e posso capire perché sia ​​così, perché qualsiasi altra cosa sembra arbitraria.

Naturalmente ci sono molti modi per ottenere una copertura che in realtà non mi aiuta a capire la base di codice - ad esempio, è utile testare su String ()? che dire di getter e setter per oggetti immutabili? Una squadra ha solo così tanti sforzi da applicare in un tempo fisso e quel tempo sembra sempre essere inferiore al tempo necessario per fare un lavoro perfetto, quindi in assenza di un programma perfetto dobbiamo accontentarci di approssimazioni.

Una metrica che ho trovato utile nel fare buone approssimazioni è Crap4J . Ora è defunto, ma puoi portarlo / implementarlo facilmente da solo. Crap4J ai tentativi di mettere in relazione la copertura del codice con la complessità ciclomatica implicando che il codice più complicato (ifs, whiles, fors ecc.) Dovrebbe avere una copertura del test più elevata. Per me questa semplice idea suonava davvero vera. Voglio capire dove c'è rischio nella mia base di codice e un rischio davvero importante è la complessità. Quindi, usando questo strumento, posso valutare rapidamente quanto sia rischiosa la mia base di codice. Se è complicato, è meglio che la copertura aumenti. In caso contrario, non ho bisogno di perdere tempo a cercare di coprire ogni riga di codice.

Naturalmente questo è solo una metrica e YMMV. Devi passare del tempo con esso per capire se avrà senso per te e se darà al tuo team una sensazione ragionevolmente seria di dove si trova il progetto.


Grazie per il grande suggerimento di usare la complessità ciclomatica per scegliere il codice che merita copertura e il link Crap4J. Ho anche trovato un ottimo articolo che parla della compressione della bellezza di crap4j in cobertura - schneide.wordpress.com/2010/09/27/…
MickJ

0

Non direi che tornare indietro e coprire il codice esistente sia la migliore strada da percorrere. Direi che ha senso scrivere test di copertura per ogni nuovo codice che scrivi e per qualsiasi codice che modifichi.

Quando vengono rilevati dei bug, scrivi un test che fallisce a causa di quel bug e correggi il bug in modo che il test diventi verde. Inserisci nei commenti del test per quale bug è scritto.

L'obiettivo è avere abbastanza fiducia nei test da poter apportare modifiche senza preoccuparsi di effetti collaterali imprevisti. Prova a lavorare in modo efficace con il codice legacy per un buon riepilogo degli approcci per domare il codice non testato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.