-
Leggi lavorare efficacemente con il codice legacy. link
Anche se è il tuo progetto, e non è un mistero per te, è ancora una sorta di eredità. Ti aiuta a fare un passo indietro dal codice per un momento e pensa a cosa farai.
-
Riconoscere TDD non significa letteralmente "tutti i test prima di tutto il codice". Avere un mucchio di codice senza test non spezza completamente il modello TDD. Rende le cose un po 'più difficili, ma può ancora essere TDD anche con test di unità zero disponibili al momento attuale.
-
Inizia a progettare pensando ai test. Questo è in realtà più difficile di quanto sembri. Ma puoi fare progetti test-driven e non scrivere ancora tutti i test. Richiede una certa esperienza per progettare un'API testabile.
-
Scrivi un test per una cosa in fase di sviluppo.
-
Fai funzionare quel test.
Fai scorrere i passaggi 3, 4 e 5 per ogni deliverable che hai. Stai facendo TDD solo per nuovi sviluppi. L'eredità rimane com'era.
A volte, stai riscrivendo, modificando o espandendo il codice legacy.
Inoltre, quando fai manutenzione e risoluzione dei bug, farai una cosa leggermente diversa.
-
Per il codice legacy che deve essere toccato, prova a scrivere un test. A volte questo è difficile perché il codice non è progettato per la testabilità. In tal caso, devi rifattorizzare il codice legacy in modo da poterlo testare in primo luogo.
-
Ora che il codice che stai per cambiare è strutturato in modo che possa essere testato. È ora possibile (a) eseguire test sull'eredità, (b) rivedere i test, (c) rivedere il codice, (d) eseguire test sulla versione rivista.
Non provi a testare tutto. Solo il minimo indispensabile per continuare ad andare avanti con i risultati finali.
Quando stai diagnosticando un problema con il codice legacy, puoi anche utilizzare i test per aiutare con la diagnostica.
-
Riscrivi la segnalazione di bug in un caso di test.
-
Se necessario, refactoring i probabili moduli colpevoli per i test. Non possono essere progettati per il test dell'unità, rendendo difficile l'uso di TDD.
-
Dopo il refactoring, hai un test unitario che dimostra il bug. Eseguirlo. Dovrebbe fallire. Ora stai facendo TDD. Hai un test e un codice che non ha superato il test.
Nei casi di manutenzione e diagnostica, sei spesso costretto a rifattorizzare il codice legacy. Questo a volte è difficile perché il codice legacy potrebbe non essere progettato pensando alle unit test.
L'obiettivo è isolare la funzionalità attraverso "Iniezione delle dipendenze" (modelli di progettazione di delegazioni o strategie) e Mock Objects.
-
Per ottenere un'iniezione di dipendenza, spesso decomporrete il codice legacy in metodi o classi più piccoli che fanno meno e che si uniscono durante l'inizializzazione del programma principale. Il tuo test unitario li unirà insieme per il test, il tuo programma principale li riunirà per il lavoro di produzione. L'importante è che tu debba spesso decomporsi.
Alcuni programmatori si oppongono a questo perché un'API testabile spesso "espone troppo" o richiede "troppe righe di codice dal client" o qualche altro lamento. Quelli non erano misure di qualità. I test hanno più valore del codice golf. Alcune righe aggiuntive di inizializzazione nell'applicazione di produzione non uccideranno nessuno. Alcune linee aggiuntive di inizializzazione per aiutare i test possono salvare montagne di sforzi diagnostici e di manutenzione a lungo termine.
-
Costruire simulazioni - in alcune lingue - è una forma d'arte. Ci sono librerie e quadri per questo. Le lingue con dichiarazioni di tipo statico (Java, C #, C ++, ecc.) Richiedono simulazioni sofisticate. Le lingue con digitazione anatra (Python, Ruby, ecc.) Non richiedono librerie fittizie di fantasia.