Test di unità vecchi / legacy rotti


13

Lavoro per una grande azienda e sono responsabile di una grande applicazione java con migliaia di test junit. Da quando sono passato a questo ruolo, ci sono stati 200-300 test interrotti (probabilmente interrotti per anni). I test sono vecchi e fragili e sono un casino di dipendenze di spaghetti che in genere finiscono con dati sandbox live.

Il mio obiettivo è superare i test al 100% in modo da poter rompere la build sugli errori dei test unitari, ma non posso farlo fino a quando non affronterò i test interrotti. Ho pochissimo budget perché il budget di manutenzione è principalmente di supporto, ma il mio team ha identificato e risolto i test di frutta a basso carico (principalmente problemi di configurazione / risorse locali) e siamo scesi a 30-40 test davvero brutti.

Quali sono alcune opinioni sulle migliori pratiche? Non penso che i test siano preziosi, ma non so nemmeno cosa stanno testando o perché non funzionano senza scavare, il che richiede tempo e denaro che probabilmente non abbiamo.

Sto pensando che dovremmo documentare gli stati dei test non funzionanti con tutto ciò che sappiamo, quindi eliminare o ignorare completamente i test non funzionanti e inserire un bug / oggetto di lavoro con priorità inferiore per indagare e risolverli. Saremo quindi al 100% e inizieremo a ottenere un valore reale dagli altri test e se avremo una manna di manutenzione / refactoring saremo in grado di riprenderli.

Quale sarebbe l'approccio migliore?

Modifica: Penso che questa sia una domanda diversa rispetto a questa domanda perché ho una chiara direzione per i test che dovremmo scrivere in futuro, ma ho ereditato i test falliti legacy da affrontare prima che la vasta serie corrente di test diventasse significativa.


1
Sicuramente d'accordo che dovresti sbarazzarti di 30-40 brutti test. Tuttavia, "se abbiamo una manna di manutenzione / refactoring saremo in grado di raccoglierli di nuovo" suona come un pio desiderio. Non sono sicuro che ci sia un vero vantaggio nel documentarli come oggetti a bassa priorità in quanto tali oggetti hanno l'abitudine di non essere mai utilizzati.
David Arno,

1
Consiglio di leggere questo libro: lavorare in modo efficace con il codice legacy . Una raccomandazione del libro non è una risposta alla tua domanda, ma troverai molti buoni consigli in merito al test unitario.

4
Questo può essere un duplicato di una cosa, ma è non è a questa domanda. Questo non sta chiedendo come evitare di scrivere fragili unit test, ma come gestire una base di codice ereditata con unit test già scritti che falliscono.

1
Sembra che tu abbia già trovato la tua soluzione.
Doc Brown,

2
@gnat Non sono d'accordo. Per esperienza personale, c'è una grande differenza tra "qualcosa ha rotto molti dei miei test unitari ieri sera" e "Ho ereditato un sacco di vecchio codice con test unitari falliti abbastanza a lungo che nessuno sa perché". Uno è un problema con lo sviluppo attuale, uno è un problema con il software legacy. Sono necessari due approcci diversi qui. La risposta migliore alla domanda collegata non affronta gli aspetti legacy.

Risposte:


17

Quello che vorrei fare è prima disabilitare i test che falliscono e hanno sempre fallito.

Fallo in modo che un test fallisca.

Mentre indaghi potresti essere in grado di chiedere a persone che sono state con la tua compagnia più a lungo su di loro, potrebbero esserci molte conoscenze tribali su di loro che puoi documentare / catturare. Forse dai tuoi registri VCS. "Oh, quel test è sempre fallito da quando siamo passati a X" o altre informazioni possono essere utili.

Una volta che sai quale era la funzionalità testata puoi determinare:

  • Ci preoccupiamo per questo test
  • Quanto è importante testarlo

E quindi fare un elenco di priorità.

Probabilmente nulla in questo elenco è abbastanza importante per avere più tempo dopo poiché è stato ignorato già da anni. Quindi non spenderei troppo tempo / risorse a documentare e analizzare tutti questi test falliti.


1
Mi piace l'idea di disabilitare i test in anticipo, ma un ambiente conservativo potrebbe preferire mosse incrementali più piccole. Suppongo che dipenda dalla tua azienda?
Aaron Hall,

1
@AaronHall - Penso che se guardi alle tue esigenze di modifica immediata del codice (correzioni e miglioramenti) e identifichi eventuali test non funzionanti associati ad essi, puoi accenderli tutti, valutare e correggere i test, apportare le modifiche alla codifica con la comprensione che i test passano, vengono corretti o vengono eliminati.
JeffO,

6

Vorrei fare quanto segue:

  1. Tentare di determinare esattamente quali test falliti stanno tentando di convalidare.

  2. Triage: se alcuni test stanno provando a testare cose non importanti come (un vecchio) stato del mondo, eliminali. Se ti rendi conto che alcuni di loro stanno cercando di convalidare qualcosa di importante, prova a determinare se quei test lo stanno facendo correttamente. Se i test non sono corretti, falli testare correttamente.

  3. Correggi qualsiasi cosa non vada nel tuo codice di produzione ora che hai buoni test.

Ricorda la contabilità, ogni riga di codice è una passività, ma può essere erroneamente valutata come un'attività. La deletechiave può creare molto valore per la tua azienda.


Un'idea di triage in stile team è molto bella!

Buone idee, ma OP ha già detto che non ha risorse per eseguire analisi pesanti, quindi sfortunatamente non sarà in grado di usarle.
TMN,

Il triage riguarda il razionamento di risorse limitate in cui creeranno il massimo valore. Ecco un post di blog rilevante sul tema del triage e del software: softwaretestingclub.com/profiles/blogs/…
Aaron Hall

5

200-300 test rotti (probabilmente rotti per anni).

Ahia! Una volta ho affrontato una situazione simile ma con 7 test non riusciti in cui il team ha iniziato a ignorare il fatto che hanno fallito per mesi a causa della mentalità "sempre crunch".

Il mio obiettivo è superare i test al 100% in modo da poter rompere la build sugli errori dei test unitari, ma non posso farlo fino a quando non affronterò i test interrotti.

Ero ossessionato da un obiettivo simile anche se ero solo uno sviluppatore junior nel team perché stavo notando un accumulo in cui più test fallivano nel corso dei mesi. Volevo che trasformassimo quelli da "avvertimenti" in errori di costruzione (forse in qualche modo odiosi per il resto della squadra).

Sto pensando che dovremmo documentare gli stati dei test non funzionanti con tutto ciò che sappiamo, quindi eliminare o ignorare completamente i test non funzionanti e inserire un bug / oggetto di lavoro con priorità inferiore per indagare e risolverli. Saremo quindi al 100% e inizieremo a ottenere un valore reale dagli altri test e se avremo una manna di manutenzione / refactoring saremo in grado di riprenderli.

Anche questi sono i miei pensieri. È possibile disabilitare temporaneamente tutti questi test difettosi e visitarli lentamente e risolverli nel tempo. È importante pianificare tali correzioni se le consideri davvero importanti, anche se hanno una priorità bassa, poiché è facile che tali elementi non vengano risolti. La priorità per me è assicurarsi che non vengano introdotti nuovi test che falliscono.

Come ogni tipo di avvertimento, se non rompono la build, tendono ad accumularsi rapidamente. Questo presuppone che quel tipo di dinamica di gruppo in cui l'abitudine di ignorare gli avvisi (test falliti in questo caso) possa portare rapidamente all'introduzione di più avvisi e ridurre la tentazione di mantenere tali avvisi a zero.

Un team molto coscienzioso potrebbe non soffrire di questi problemi ed evitare di introdurre nuovi avvisi (nuovi fallimenti nei test), ma è sicuramente più sicuro andare un po 'più pesante ed esercitare una strategia di prevenzione trasformandoli in errori che devono essere corretti prima di un processo di unione.

Quindi il mio suggerimento è lo stesso del tuo (anche se solo un'opinione forte - forse in qualche modo può sostenerlo con metriche e una risposta più scientifica). Disabilita quei vecchi test e inseriscili nel programma per risolverli. La prima priorità è assicurarsi che questo problema non si accumuli e inizi a peggiorare, assicurandosi che i test attualmente riusciti non finiscano per essere ignorati se iniziano a fallire.


4

In un certo senso sei fortunato. È meglio avere test che falliscono e non dovrebbero (ti danno almeno un avvertimento che qualcosa non va) che avere test che passano e non dovrebbero (che ti danno un falso senso di sicurezza).
Naturalmente se hai il primo è molto probabile che tu abbia anche il secondo (quindi i test che superano ma dovrebbero fallire).

Come già detto, per ora disabilita quei test non riusciti ma li fai stampare un messaggio nel tuo registro dei test come costante promemoria su di essi.
Ma dovresti sicuramente trovare le risorse per andare su tutta la tua suite di test al fine di trovare ed eliminare i test che passano e non dovrebbero, perché ognuno di essi significa che c'è un bug nel tuo codice che attualmente non stai rilevando nel tuo cicli di prova.

Usando quella nuvola scura che pende sulla base di codice potresti essere in grado di ottenere un po 'di budget per una revisione completa dei tuoi test, se lo giochi bene e non dici semplicemente che pensi che alcuni test dovrebbero essere esaminati perché sembrano falliscono quando non dovrebbero, ma che non ti fidi che i tuoi test rilevino correttamente gli errori nel tuo codice, che il set di test non può essere considerato attendibile per fare il suo lavoro.
Quando l'ho fatto in un'azienda precedente, stavo lavorando per una recensione del genere e ho scoperto che centinaia di test sono stati scritti con ipotesi errate su ciò che il codice DOVREBBE fare, portando al codice (che è stato scritto utilizzando le stesse ipotesi errate) ha superato i test quando davvero non avrebbe dovuto. Risolto questo problema risolto molti brutti bug di caso angolare che (sebbene la maggior parte non fossero critici) avrebbero potuto far cadere alcuni sistemi importanti.


3

Qualsiasi test unitario fallito dovrebbe causare la rottura della build. Buono a te per averlo realizzato e fissato quell'obiettivo. La mente umana difficilmente può ignorare qualcosa di più completo della fonte di un falso allarme persistente .

Butta via questi test e non guardare indietro. Se hanno fallito per anni e non sono ancora stati affrontati, allora non sono una priorità.

Per quanto riguarda la conoscenza tribale, se le persone con conoscenza tribale sono ancora in giro, dovrebbero aver risolto i test falliti ormai. In caso contrario, di nuovo, queste non sono una priorità.

Se non esiste alcuna conoscenza tribale, tu e il tuo team dovete assumere la proprietà della logica. I test falliti possono essere più fuorvianti che utili - il mondo potrebbe essere andato avanti.

Crea nuovi test pertinenti e procedi scrivendo un ottimo codice.

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.