Originariamente TDD proveniva dal movimento agile, in cui i test venivano scritti in anticipo per garantire che ciò che era stato codificato rimanesse corretto, date le specifiche che ora erano ben definite nel codice di test. Sembrava anche un aspetto molto importante del refactoring, in quanto quando si modificava il codice, si poteva fare affidamento sui test per dimostrare che non si era modificato il comportamento del codice.
Quindi gli strumenti che le persone hanno trovato e pensato di conoscere informazioni sul tuo codice e potrebbero quindi generare stub di test per aiutarti a scrivere i tuoi test unitari, e penso che sia qui che tutto è andato storto.
Gli stub di test sono generati da un computer che non ha idea di cosa stai facendo, produce semplicemente uno stub per ogni metodo perché è quello che gli viene detto di fare. Ciò significa che hai un caso di prova per ciascun metodo indipendentemente dalla complessità di quel metodo o se è adatto per il test in isolamento.
Questo sta arrivando ai test dall'estremità sbagliata della metodologia TDD. In TDD dovresti capire cosa deve fare il codice, e quindi produrre codice che raggiunga questo obiettivo. Questo si autoavvera nel fatto che finisci per scrivere test che dimostrano che il codice fa quello che fa il codice, non quello che dovrebbe fare. In combinazione con la generazione automatica di stub di test basati su metodi, praticamente perdi tempo a provare ogni piccolo aspetto del tuo codice che può facilmente rivelarsi sbagliato quando tutti i piccoli pezzi vengono messi insieme.
Quando Fowler descrisse i test nel suo libro, si riferì al test di ogni classe con il suo metodo principale. Ha migliorato questo, ma il concetto è sempre lo stesso: testate l'intera classe in modo che funzioni nel suo insieme, tutti i test sono raggruppati insieme per dimostrare l'interazione di tutti quei metodi in modo che la classe possa essere riutilizzata con aspettative definite.
Penso che i toolkit di test ci abbiano reso un disservizio, ci hanno portato lungo il percorso di pensare che il toolkit sia l'unico modo per fare le cose quando in realtà, devi pensare di più per te stesso per ottenere il miglior risultato dal tuo codice. Mettere ciecamente il codice di prova negli stub di test per piccoli pezzi significa solo che devi ripetere il tuo lavoro in un test di integrazione (e se hai intenzione di farlo, perché non saltare completamente la fase di test dell'unità ora ridondante). Significa anche che le persone sprecano molto tempo nel tentativo di ottenere una copertura del test al 100% e molto tempo nella creazione di grandi quantità di codice e dati beffardi che sarebbero stati meglio spesi per rendere il codice più semplice per il test di integrazione (cioè se hai così tanto dipendenze dei dati, unit test potrebbe non essere l'opzione migliore)
Infine, la fragilità dei test unitari basati su metodi mostra solo il problema. Il refactoring è progettato per essere utilizzato con i test unitari, se i test si interrompono continuamente perché stai effettuando il refactoring, allora qualcosa è andato storto in modo grave con l'intero approccio. Refactoring ama creare ed eliminare metodi, quindi ovviamente l'approccio test cieco per metodo non è quello che era originariamente previsto.
Non ho dubbi sul fatto che molti metodi avranno test scritti per loro, tutti i metodi pubblici di una classe dovrebbero essere testati, ma non puoi allontanarti dal concetto di testarli insieme come parte di un singolo caso di test. Ad esempio, se ho un set e un metodo get, posso scrivere dei test che inseriscono i dati e verificare che i membri interni siano impostati correttamente, oppure posso usare ciascuno di essi per inserire alcuni dati e quindi estrarli di nuovo per vedere se è sempre lo stesso e non confuso. Questo sta testando la classe, non ogni metodo in isolamento. Se il setter si basa su un metodo privato helper, allora va bene - non è necessario deridere il metodo privato per assicurarsi che il setter funzioni, non se si verifica l'intera classe.
Penso che la religione stia affrontando questo argomento, quindi si vede lo scisma in quello che ora è noto come sviluppo "guidato dal comportamento" e "guidato dai test" - il concetto originale di unit test era per lo sviluppo guidato dal comportamento.