L'approccio "write test + refactor till pass" sembra incredibilmente anti-ingegneria.
Sembra che tu abbia un'idea sbagliata sia del refactoring che del TDD.
Il refactoring del codice è il processo di modifica del codice sorgente di un programma per computer senza modificarne il comportamento funzionale esterno al fine di migliorare alcuni degli attributi non funzionali del software.
Quindi non puoi refactificare il codice fino a quando non passa.
E TDD, in particolare i test unitari (che considero il miglioramento di base, dal momento che altri test mi sembrano piuttosto plausibili), non si tratta di ridisegnare un componente fino a quando non funziona. Si tratta di progettare un componente e lavorare sull'implementazione fino a quando il componente funziona come previsto.
Inoltre è importante capire davvero che l' unità di prova riguarda le unità di prova . A causa della tendenza a scrivere sempre molte cose da zero, è importante testare tali unità. Un ingegnere civile conosce già le specifiche delle unità che utilizza (i diversi materiali) e può aspettarsi che funzionino. Queste sono due cose che spesso non si applicano agli ingegneri del software ed è molto pro-ingegneria testare le unità prima di usarle, perché significa utilizzare componenti testati di alta qualità.
Se un ingegnere civile avesse avuto l'idea di utilizzare un nuovo tessuto in fibra per realizzare un tetto per coprire uno stadio, ci si aspetterebbe che lo testasse come un'unità, cioè definire le specifiche necessarie (ad esempio peso, permeabilità, stabilità, ecc.) E successivamente testare e perfezionarlo fino a quando non li incontra.
Ecco perché TDD funziona. Perché se costruisci software di unità testate, è molto meglio che funzioni, collegandole e in caso contrario puoi aspettarti che il problema sia nel tuo codice colla, supponendo che i tuoi test abbiano una buona copertura.
modifica:
refactoring significa: nessun cambiamento nella funzionalità. Un punto di scrittura del test unitario è garantire che il refactoring non rompa il codice. Quindi TDD ha lo scopo di assicurare che il refactoring non ha effetti collaterali.
La granularità non è un argomento di prospettiva, perché come ho detto, l'unità testa le unità di test e non i sistemi, per cui la granularità è definita esattamente.
TDD incoraggia la buona architettura. Richiede di definire e implementare le specifiche per tutte le unità, costringendoti a progettarle prima dell'implementazione, il che è piuttosto il contrario di quello che sembra pensare. TDD determina la creazione di unità, che possono essere testate singolarmente e sono quindi completamente disaccoppiate.
TDD non significa che lancio un test del software al codice spaghetti e mescolo la pasta fino a quando non passa.
In contraddizione con l'ingegneria civile, nell'ingegneria del software un progetto di solito si evolve costantemente. Nell'ingegneria civile, hai il requisito di costruire un ponte in posizione A, che può trasportare x tonnellate ed è abbastanza largo per n veicoli all'ora.
Nell'ingegneria del software, il cliente può praticamente decidere in qualsiasi momento (possibilmente dopo il completamento), desidera un ponte a due piani e che lo desidera collegato con l'autostrada più vicina e che vorrebbe che fosse un ponte di sollevamento, perché la sua azienda recentemente ha iniziato a utilizzare le navi a vela.
Gli ingegneri del software hanno il compito di modificare i progetti. Non perché i loro disegni siano imperfetti, ma perché è il modus operandi. Se il software è ben progettato, può essere riprogettato ad alto livello, senza dover riscrivere tutti i componenti di basso livello.
TDD riguarda la creazione di software con componenti testati individualmente e altamente disaccoppiati. Ben eseguito, ti aiuterà a rispondere ai cambiamenti nei requisiti in modo significativamente più rapido e sicuro, che senza.
TDD aggiunge requisiti al processo di sviluppo, ma non proibisce altri metodi di garanzia della qualità. Certo, TDD non fornisce la stessa sicurezza della verifica formale, ma ancora una volta, la verifica formale è estremamente costosa e impossibile da utilizzare a livello di sistema. Eppure, se lo volessi, potresti combinare entrambi.
TDD comprende anche test diversi dai test unitari, eseguiti a livello di sistema. Trovo che siano facili da spiegare ma difficili da eseguire e difficili da misurare. Inoltre, sono abbastanza plausibili. Mentre vedo assolutamente la loro necessità, non li apprezzo davvero come idee.
Alla fine, nessuno strumento risolve effettivamente un problema. Gli strumenti semplificano solo la risoluzione di un problema. Puoi chiedere: come può uno scalpello aiutarmi con una grande architettura? Bene, se hai intenzione di fare pareti dritte, i mattoni dritti sono di aiuto. E sì, garantito, se dai questo strumento a un idiota, probabilmente alla fine lo sbatterà attraverso il piede, ma non è colpa dello scalpello, tanto che non è un difetto del TDD che dà falsa sicurezza ai principianti, chi non scrive buoni test.
Quindi, in sostanza, si può dire che TDD funziona molto meglio di nessun TDD.