Ho appena acquistato The Art of Unit Testing da Amazon. Sono piuttosto serio riguardo alla comprensione di TDD, quindi ti assicuro che questa è una domanda vera.Cercando di acquisire confidenza con i vantaggi del TDD
Ma mi sento come se fossi costantemente sul punto di trovare una giustificazione per rinunciarvi.
Ho intenzione di interpretare l'avvocato del diavolo qui e di tentare di abbattere i presunti benefici del TDD nella speranza che qualcuno possa dimostrarmi sbagliato e aiutarmi a essere più fiducioso nelle sue virtù. Penso che mi manchi qualcosa, ma non riesco a capire cosa.
1. TDD per ridurre i bug
Questo often-cited blog post dice che i test di unità sono strumenti di progettazione e non di bug cattura:
Nella mia esperienza, i test di unità non sono un modo efficace per trova bug o rileva regressioni.
...
TDD è un modo robusto di progettare componenti software (“unità”) interattivamente in modo che il loro comportamento è specificata attraverso test unitari. Questo è tutto!
Ha senso. I casi limite saranno sempre presenti, e troverai solo i bug superficiali, che sono quelli che troverai non appena esegui la tua app. È ancora necessario eseguire i test di integrazione corretti dopo aver completato una buona parte del software.
Abbastanza corretto, ridurre i bug non è l'unica cosa che TDD dovrebbe aiutare.
2. TDD come un paradigma di progettazione
Questo è probabilmente uno dei grandi. TDD è un paradigma di progettazione che ti aiuta (o ti costringe) a rendere il tuo codice più composable.
Ma la componibilità è una qualità moltiplicabile; lo stile di programmazione funzionale, ad esempio, rende anche il codice abbastanza componibile. Naturalmente, è difficile scrivere un'applicazione su larga scala interamente in stile funzionale, ma ci sono alcuni schemi di compromesso che è possibile seguire per mantenere la componibilità.
Se si inizia con un progetto funzionale altamente modulare e quindi si aggiungono attentamente lo stato e l'IO al proprio codice secondo necessità, si otterranno gli stessi motivi che TDD incoraggia.
Ad esempio, per eseguire la business logic su un database, il codice IO può essere isolato in una funzione che esegue le attività "monadiche" di accesso al database e lo inoltra come argomento alla funzione responsabile della logica di business . Quello sarebbe il modo funzionale per farlo.
Naturalmente, questo è un po 'goffo, così, invece, potremmo lanciare un sottoinsieme del codice IO del database in una classe e darlo a un oggetto contenente la logica aziendale pertinente. È la stessa identica cosa, un adattamento del modo funzionale di fare le cose, e si riferisce al modello di repository.
So che probabilmente questo mi farà guadagnare una pessima fustigazione, ma spesso, non posso fare a meno di pensare che TDD compensi solo alcune delle cattive abitudini che OOP può incoraggiare - quelle che possono essere evitato con un po 'di ispirazione dallo stile funzionale.
3. TDD come documentazione
TDD si dice per servire come documentazione, ma serve solo come documentazione per i coetanei; il consumatore richiede ancora la documentazione di testo.
Ovviamente, un metodo TDD potrebbe servire come base per il codice di esempio, ma i test generalmente contengono un certo grado di mock che non dovrebbero essere nel codice di esempio, e di solito sono abbastanza elaborati in modo che possano essere valutati per l'uguaglianza contro il risultato atteso.
Un buon test unitario descriverà nel suo metodo il comportamento esatto che si sta verificando e il test non verificherà né più né meno di tale comportamento.
Quindi, direi, il vostro tempo potrebbe essere meglio speso per lucidare la vostra documentazione. Diamine, perché non fare solo la documentazione prima di tutto e chiamarla Design guidato dalla documentazione?
4. TDD per i test di regressione
E 'citata in quel post sopra che TDD non è molto utile per rilevare regressioni. Questo è, naturalmente, perché i casi limite non ovvi sono quelli che rovinano sempre quando si modifica un codice.
Ciò che potrebbe essere anche da notare su questo argomento è che è probabile che la maggior parte del codice rimanga invariata per un tempo piuttosto lungo. Quindi, non avrebbe più senso scrivere test unitari in base alle necessità, ogni volta che il codice viene modificato, mantenendo il vecchio codice e confrontando i suoi risultati con quelli della nuova funzione?
"quelli che possono essere evitati con un po 'di ispirazione dallo stile funzionale." Quasi d'accordo ... TDD incoraggia uno stile di codifica più vicino al modello di attore, che è una specie di inverso dello stile funzionale (è un modello push rispetto al tiro della codifica funzionale) – kyoryu
Interessante ... dovrei esaminare il modello dell'attore . Questo potrebbe contenere la risposta che sto cercando! –
Vale la pena notare che Alan Kay è stato citato dicendo che si rammarica di usare il termine "orientato agli oggetti" e desidera che abbia usato "orientato ai messaggi". TDD ti spinge verso uno stile orientato ai messaggi (che è il cuore del modello di attore, o dei processi sequenziali comunicanti, o ...) – kyoryu