Quali sono i vantaggi del TDD?

Sono sicuro che molti di voi, si staranno chiedendo che cosa significa la sigla TDD. Bhe, la sigla TDD, sta per Test Driven Development, che tradotto in italiano è esattamente “Sviluppo guidato da test” [approfondimento su Wikipedia allo Unit Testing].

Sono andato a “sbattere” contro il TDD durante il mio corso di ingegneria del software avanzata all’università, e da allora il TDD l’ho sempre apprezzato come modello di sviluppo.

Ci ho realizzato Summbot l’anno scorso, e devo ammettere che mi ci son trovato abbastanza a mio agio, anche se, essendo stata la prima volta, lo sviluppo è stato più lento del solito.

Usare il TDD mi ha insegnato molto, e anche se non è il modello di sviluppo che adotto oggi (in quanto i tempi di sviluppo spesso sono cortissimi, si parla di qualche settimana), ognuno di noi dovrebbe provarlo almeno una volta. Magari scopri che ti ritrovi a tuo agio.

Mi piace definire il TDD come me lo ha illustrato tempo fa il mio professore di ingegneria del software: è come un martello ed una vite. In qualche modo potresti riuscire ad avvitare la vite utilizzando il martello, ma non stai utilizzando lo strumento per quello per cui è nato. Il TDD è esattamente così.

Mi spiego meglio.

Il TDD aiuta a prevenire un bug? Questo è più un effetto collaterale che un obiettivo diretto. Si tratta di costruire un ambiente per i test? Si, ma non proprio.

Chi usa il TDD per la prima volta, senza alcuna linee guida, è difficile che riesca ad ottenere il massimo da esso. Ad ogni modo, cercherò di spiegare il TDD in 3 fasi principali:

Fase 1

Il TDD opera in un ciclo di 3 fasi. La prima fase, consiste nello scrivere un test volto a validare una certa funzionalità (il cui codice non è stato ancora scritto).

Farlo per la prima volta su ogni caratteristica che dovrà avere il vostro software è la parte più difficile del TDD. Siamo abituati a pensare a come codificare qualcosa senza TDD, chiedendoci come facciamo a scrivere un test per un determinato pezzo di codice già esistente. Ma il codice qui ancora non esiste.

Nel TDD bisogna pensare strettamente al test, senza preoccuparsi di come poi andremo a scrivere il metodo che fa tot cosa. Mark Seemann in un suo tweet ha detto:

Se un test è difficile da scrivere, renderà il sistema più facile da usare.

Fase 2:

Il secondo passo del TDD è quello di rendere la fase di test, il più semplice possibile. Se una variazione del codice di produzione influisce sul risultato di un test, possiamo essere sicuri che quel test è strettamente collegato al nostro codice. E’ un po’ come premere on-off su un interruttore, e vedere come reagisce la lampadina.

Questo passaggio fornisce un feedback veloce per la comunicazione tra il codice di produzione ed il codice dei test. Il codice in questa fase deve essere solo finalizzato a passare il test, scrivendone il meno possibile.

Fase 3:

Sul terzo gradino del TDD troviamo il refactoring, che riguarda il codice di produzione. Difficilmente andrete a modificare i test, a meno di un cambio di specifiche.

La regola cardine del refactoring è di rimanere il più vicino possibile a dei test che non falliscono mai. In questo modo possiamo fare dei piccoli cambiamenti n volte, che spingono ad avere un design del codice abbastanza pulito.

Il codice può inizialmente subire dei refactoring semplici, come il rinominare una variabile o un metodo, dopodiché si può passare ad un refactoring più complesso, nel quale a piccoli step, man mano che si avanza, si può verificare in real time attraverso i risultati del test se stiamo andando nella direzione giusta o no.

Ciclo TDD

Questi tre passaggi lavorano in un ciclo molto stretto: fai un test che fallisce, fai funzionare il codice (risultato del test verde), rifallo meglio. Ecco la magia: ogni iterazione è una piccola meta, quindi stiamo già riducendo il problema in problemi più piccoli. Ma ogni iterazione ha tre fasi, ciascuna con un diverso focus. Quindi a sua volta stiamo rompendo il problema, già piccolo, in problemi ancora più piccoli.

Ad ogni passo, otteniamo un feedback (il fallimento del test, oppure semaforo verde). Se si commette un passo falso, basta annullare e tornare al punto precedente.

La chiave è ottenere dei feedback spesso, ed il più velocemente possibile. Bisogna valutare tutto come micro-passi, per ottenere un feedback veloce, che impedisce di tornare troppo indietro nel caso ci siano degli errori. Invece di cercare di risolvere problemi che hai appena creato, basta ripristinare all’ultimo stato che ti dava l’ok.

Trovo il TDD molto intelligente come modello di sviluppo, ma abbastanza complesso ad un primo approccio. Consiglio infatti di leggere molto sull’argomento, e se ne avete la possibilità, di farvi aiutare da qualcuno che lo usa da un po’ di tempo.

Come ogni cosa, ha i suoi pro ed i suoi contro.

Contro: non è proprio semplice come approccio iniziale, e può rallentare di molto lo sviluppo. Sottolineo che quest’affermazione è vera solo all’inizio, infatti ho dei colleghi che non solo mi confermano che si trovano bene, ma che sono addirittura più produttivi usando il TDD.

Pro: avrete una riduzione drastica degli errori, dovuto al fatto che vi è un numero di test di molto superiore rispetto al classico approccio del “scrivo codice, poi scrivo i test”. Di conseguenza, meno attività di debugging. L’ultima fase, ovvero il refactoring, permette un codice molto pulito, che funzionerà sempre, grazie alla possibilità di testare “on the go” se ciò che abbiamo scritto è ok oppure no. L’introduzione di nuove funzionalità è abbastanza semplice (basta scrivere dei nuovi test, e poi passare allo sviluppo del codice), e permette di tenere sotto controllo l’avanzamento sullo sviluppo.

 

Questo articolo è ispirato al post di Jon Reid: Benefit of tdd.

2 thoughts on “Quali sono i vantaggi del TDD?

Leave a Reply

Your email address will not be published. Required fields are marked *