Ho un aneddoto rilevante da qualcosa che sta accadendo proprio ora per me. Sono su un progetto che non utilizza TDD. I nostri addetti al controllo qualità ci stanno spingendo in quella direzione, ma siamo un piccolo vestito ed è stato un processo lungo e complesso.
Comunque , di recente stavo usando una libreria di terze parti per svolgere un'attività specifica. Si è verificato un problema relativo all'uso di quella libreria, quindi mi è stato chiesto di scrivere essenzialmente una versione della stessa libreria per conto mio. In totale, alla fine sono state circa 5.000 righe di codice eseguibile e circa 2 mesi del mio tempo. So che le righe di codice sono una metrica scadente, ma per questa risposta ritengo che sia un discreto indicatore di grandezza.
C'era una particolare struttura di dati di cui avevo bisogno che mi avrebbe permesso di tenere traccia di un numero arbitrario di bit. Dato che il progetto è in Java, ho scelto Java BitSet
e l'ho modificato un po '(avevo bisogno della capacità di tracciare anche i primi 0
, cosa che BitSet di Java non fa per qualche motivo .....). Dopo aver raggiunto una copertura del 93% circa, ho iniziato a scrivere alcuni test che avrebbero effettivamente sottolineato il sistema che avevo scritto. Avevo bisogno di confrontare alcuni aspetti della funzionalità per assicurarmi che fossero abbastanza veloci per i miei requisiti finali. Non sorprende che una delle funzioni che avevo ignorato BitSet
dall'interfaccia fosse assurdamente lenta quando si trattava di set di bit di grandi dimensioni (in questo caso centinaia di milioni di bit). Altre funzioni sostituite si basavano su questa funzione, quindi era un enorme collo di bottiglia.
Quello che ho finito per andare è stato andare al tavolo da disegno e capire un modo per manipolare la struttura sottostante di BitSet
, che è un long[]
. Ho progettato l'algoritmo, chiesto ai colleghi il loro contributo e poi ho iniziato a scrivere il codice. Quindi, ho eseguito i test unitari. Alcuni si sono rotti e quelli che mi hanno indicato esattamente dove dovevo cercare nel mio algoritmo per risolverlo. Dopo aver corretto tutti gli errori dai test unitari, sono stato in grado di dire che la funzione funziona come dovrebbe. Per lo meno, potrei essere altrettanto sicuro che questo nuovo algoritmo ha funzionato così come l'algoritmo precedente.
Naturalmente, questo non è a prova di proiettile. Se c'è un bug nel mio codice che i test unitari non stanno verificando, allora non lo saprò. Ma, naturalmente, quello stesso esatto bug avrebbe potuto essere presente anche nel mio algoritmo più lento. Tuttavia , posso dire con un certo grado di fiducia che non devo preoccuparmi dell'output errato di quella particolare funzione. I test unitari preesistenti mi hanno risparmiato ore, forse giorni, di provare a testare il nuovo algoritmo per assicurarmi che fosse corretto.
Questo è il punto di avere test unitari indipendentemente dal TDD - vale a dire, i test unitari lo faranno per te in TDD e al di fuori di TDD, quando finirai per refactoring / mantenimento del codice. Naturalmente, questo dovrebbe essere accoppiato con test di regressione regolari, test del fumo, test fuzzy, ecc., Ma i test unitari , come dice il nome, testano le cose sul livello atomico più piccolo possibile, che ti dà la direzione su dove sono comparsi gli errori.
Nel mio caso, senza i test unitari esistenti, dovrei in qualche modo trovare un metodo per garantire che l'algoritmo funzioni sempre. Che, alla fine ... sembra molto simile ai test unitari , non è vero?