Pensieri sul TDD (IMHO)

Ho letto con interesse il lungo dibattito ancora in corso al post di Alessandro "My life with TDD". Purtroppo però  mi sembra che ci sia tanta confusione su cosa è e cosa non è il TDD e i molti dubbi arrivano da chi non l'ha mai provato.

La prima volta che ho sentito parlare di TDD lavoravo con Claudio e fu proprio lui a girarmi il link ad un articolo che parlava di questa pratica: liquidai la cosa con un "non credo che funzionerebbe" (o forse con una frase più colorita).
Dopo qualche anno ho iniziato a scrivere UnitTest e scoraggiato dal fatto che non sempre riuscivo a scrivere i test che volevo ho voluto dare una possibilità al TDD e dopo alcuni mesi di pratica ho inziato a prenderci gusto e a trarne enormi benefici.

Riporto quindi un elenco "fiume" in ordine sparso di mie opinioni su cosa è e cosa non è il TDD per provare dare una risposta a tutti i "commentatori" di Alessandro e magari sollevare altre discussioni.

- Il TDD non è una pratica di Test (anche se il nome lo fa presupporre) è prima di tutto una pratica di design
- Il TDD ha come gradito effetto collaterale il fatto di far nascere una suite di test
- I test ottenuti con il TDD non coprono tutti i casi, ma si possono sempre aggiungere altri test man mano che identifico altri casi o che trovo bug nel codice
- Il codice ottenuto in TDD è in quantità minore e si focalizza solo su ciò che serve
- Il codice ottenuto in TDD è più ortogonale e più semplice da mantenere
- La prima barra rossa (del ciclo Test->Rosso->implemento->Verde->Refactoring) è il segnale che il test sta testando qualcosa (e vi garantisco che è importantissimo)
- I test non possono contenere if, switch ecc...quindi vuol dire che sono semplici metodi di 5-6 righe di codice
- Imparare il TDD è difficile: secondo me il passaggio al TDD ha lo stesso impatto del passaggio dalla programmazione funzionale strutturata a quella ad oggetti
- Imparare il TDD richiede tempo e costanza
- Il TDD non si impara leggendo articoli o libri ma praticandolo
- Ogni unita del nostro codice è testabile (è matematica)
- Testare che la sfumatura di rosso del pulsante sia quella che piace al cliente non è compito del TDD
- Con un opportuno uso dei Mock Object posso testare che il gradiente sia applicato in modo corretto
- I test case nascono dalle user story raccolte con il cliente e quindi rispondono ai requisiti del cliente
- Il team che applica il TDD deve essere opportunamente skillato se non tutti lo sono c'è sempre il pair programming
- Il codice di Test è in quantità maggiore di quello testato
- Il TDD ti obbliga a ragionare prima di scrivere del codice
- Il TDD ti obbliga a dichiarare quello che vuoi ottenere prima di scrivere del codice
- Il TDD ti mette dalla parte dell'utente del tuo stesso codice e quindi ti obbliga a scrivere interfacce facilmente usabili
- Il TDD ti spinge a scrivere codice semplice e chiaro con piccoli metodi e classi ben disaccoppiate
- I test di integrazione ti permettono di capire come la tua classe interagisce con le altre
- Quando devo apportare modifiche al codice posso partire dai test e capire quindi cosa devo modificare nel codice esistente e dove lo devo fare
- I test hanno anche il compito di documentare il codice: leggere un test per capire come usare una classe è molto efficace
- Il TDD non garantisce che il programma non contenga bug
- Il TDD garantisce che vecchi bug corretti tramite test non si ripresentino
- Il TDD è un costo iniziale che viene ammortizzato sulla vita del progetto
- Il TDD abbatte notevolmente il tempo richiesto per il test manuale
- Con il TDD il debugger è usato molto meno e solo per operazioni chirurgiche
- Il TDD permette di spezzare il problema in piccoli passi e risolvere ogni passo andando sempre verso la soluzione
- Ogni test case rappresenta una singola funzionalità o una parte di essa: quindi quando un test fallisce ho un solo problema
- Se ho due test rossi ho due problemi distinti
- Ogni nuovo test aggiunge una nuova funzionalità al codice esistente
- E' difficile testare applicazioni multithread per il loro aspetto non deterministico
- E' costoso testare le UI, ma esistono dei pattern che riducono la "superficie" non testata (MVP/MVC)
- I test di integrazione con il database vanno scritti e permettono di testare le query e lo schema del database
- Il TDD ti costringe a scrivere codice meno incapsulato per poter essere testato
- Il TDD ti constringe a scrivere oggetti indipendenti e ad iniettare le dipendenze
- Scrivere i test dopo non è sempre possibile
- Il TDD non è il "silver bullet" (ma sicuramente aiuta il successo del progetto)

NOTE:
1) L'elenco sopra è stato scritto di getto basandomi su ciò che ho imparato in questi anni di TDD ed è personale

2) Se volete posso argomentare su ognuno di questi punti, mi piace discutere perchè dalle discussioni nasce il miglioramento. Vi invito però a non usare il blog ma ad usare un forum o una mailing list, magari quella di UgiALT.Net o quella di ExtremeProgramming.

UPDATE: ho aperto un thread sulla mailing list: http://tech.groups.yahoo.com/group/ugialtnet/message/1393

 


Print | posted on Monday, December 15, 2008 10:12 AM