Esperienza negativa TDD [chiuso]


95

Qual è il lato negativo della tua esperienza TDD? Trovi fastidiosi e inutili i piccoli passi (la soluzione più semplice per rendere il test verde)? Trovi che i test privi di valore (quando inizialmente il test ha senso ma nell'implementazione finale controlla la stessa logica degli altri test) sono fondamentali per la manutenzione? eccetera.

Le domande precedenti riguardano cose di cui non mi sento a mio agio durante la mia esperienza di TDD. Quindi sono interessato se altri sviluppatori hanno sentimenti simili e cosa ne pensano.

Sarebbe grato per i collegamenti ad articoli che descrivono i lati negativi del TDD (Google è pieno di articoli positivi e spesso fanatici).


10
La mia ipotesi è che non ascolterai molte risposte oneste sulle esperienze negative delle persone, perché TDD è ancora in uno stato di "adozione precoce" e la maggior parte delle persone che sono interessate e impegnate abbastanza per provarlo non sono abbastanza obiettive per valutarlo in base ai suoi meriti relativi. Di solito ci vogliono diversi anni perché l'industria stabilisca realmente gli effetti a lungo termine di nuovi processi e tecniche, e anche allora è difficile ottenere risposte dirette a causa della mancanza di controlli. Buona domanda comunque, e buona fortuna per ottenere risposte utili!
Aaronaught il

20
Hai problemi a trovare la negatività su Internet ?!
Eric Wilson,

4
@Job (e possibilmente altro): non dimenticare che ha chiesto informazioni su TDD, non sui test unitari. TDD! = Test unitario.
n1ckp,

2
Sono tentato di rispondere a questa domanda, ma non voglio davvero iniziare perché ci vorrà metà della mia giornata.
Rei Miyasaka,

2
Quando mi ritrovo a passare abbastanza tempo sui bug, sembra che potrei dedicare meno tempo a scrivere test per ogni singola cosa che scrivo prima di scriverlo, non adotterò TDD test-first-all-things-things. Invece, chino la testa per la vergogna e inizierò a cercare una nuova carriera. Non riguardo ai bug che dici? Design? Sì. Questo è tutto. Esatto. E non hai imparato nulla di dannato sul design robusto dandoti una rete di sicurezza e una licenza per continuare a lavorare stupido. Metti via l'IDE e prova a leggere il tuo codice se vuoi scoprire il vero problema.
Erik Reppen,

Risposte:


95

Come tutto ciò che rientra nel banner "Agile", TDD è qualcosa che suona bene in teoria, ma in pratica non è così chiaro quanto sia buono (e anche come la maggior parte delle cose "Agili", ti viene detto che se non lo fai piace, lo stai facendo male).

La definizione di TDD non è impressa nella pietra: ragazzi come Kent Beck richiedono che un test di non compilazione debba essere scritto prima di una singola riga di codice e che ogni singola riga di codice debba essere scritta per superare un test fallito. Il design frontale è minimo e tutto è guidatodai test. Semplicemente non funziona. Ho visto un'app per grandi aziende sviluppata utilizzando quella metodologia e spero che sia il codice peggiore che vedo nella mia carriera (non sarà molto lontano; e questo è stato nonostante alcuni sviluppatori di talento ci lavorassero). Da quello che ho visto risulta un numero enorme di test scarsamente ponderati che confermano principalmente che si verificano chiamate di funzione, che vengono generate eccezioni quando le variabili sono nulle e il framework beffardo ottiene un allenamento completo (whoop-de-whoop); il tuo codice di produzione viene fortemente associato a questi test e il sogno di un refactoring semplice e costante non appare - in effetti le persone hanno ancora meno probabilità di correggere un codice errato a causa di tutti i test che si rompono.

Al contrario, ho sentito che le persone sostengono che TDD significa progettare i test ad alto livello come parte della fase di pianificazione, insieme alla progettazione architettonica. Questi test possono cambiare durante lo sviluppo man mano che diventano disponibili ulteriori informazioni, ma sono stati attentamente considerati e offrono una buona guida su ciò che il codice dovrebbe effettivamente fare. Per me ha perfettamente senso.


7
+1 "progettare i test ad alto livello come parte della fase di pianificazione - a fianco del progetto architettonico" Suona molto più ragionevole anche per me.
Steven Jeuris,

11
@Aaronaught Agile non significa nessuna pianificazione, ma solo una pianificazione tempestiva .
Adam Jaskiewicz,

25
@Adam Jaskiewicz: Adoro la cosa "nessuna pianificazione anticipata". Dai, la pianificazione è anticipata per definizione . Se non pianifichi in anticipo ma durante l'evento non stai pianificando affatto; stai improvvisando. ;-)
CesarGon

34
@Adam - "Le persone passano davvero direttamente alla programmazione il primo giorno di un'iterazione?" erm sì Questo è un uomo "Agile". Nell'ultimo posto in cui ho lavorato (e sono stato licenziato per non essere "Agile") hanno fatto un intero ciclo di rilascio di 3 mesi senza mai pianificare una singola riga di codice o fare un'unica pagina di documentazione. E sì, il codice era terribile e sì, il software era lento, goffo e pieno di bug. Il giorno in cui mi sono unito mi è stato detto con orgoglio dal direttore che erano "Il negozio più agile di Londra". Lo erano sicuramente.

7
Può aggiungere un altro problema: fintanto che supera il test, può essere buono. Non importa che il test stesso possa essere imperfetto e quindi causare falsi negativi e / o falsi positivi. E ovviamente richiede "copertura del test al 100%" e tutto ciò che ha tale è per definizione perfetto, causando test inutili che in realtà non testano nulla ma sono scritti esclusivamente per ottenere quella copertura al 100%, codice non documentato perché il contatore della copertura conta i commenti come codice scoperto, ecc. ecc.
jwenting

67

Questa intervista di Rich Hickey ( autore Clojure ) contiene quanto segue. Mi sento al 100% simpatico:

La vita è breve e ci sono solo un numero finito di ore al giorno. Quindi, dobbiamo fare delle scelte su come trascorriamo il nostro tempo. Se lo passiamo a scrivere test, è tempo che non stiamo spendendo per fare qualcos'altro. Ognuno di noi deve valutare il modo migliore di trascorrere il proprio tempo al fine di massimizzare i risultati, sia in termini di quantità che di qualità. Se le persone pensano che passare il cinquanta percento del loro tempo a scrivere test massimizzi i loro risultati, va bene per loro. Sono sicuro che non è vero per me — Preferirei passare quel tempo a pensare al mio problema. Sono certo che, per me, questo produce soluzioni migliori, con meno difetti, rispetto a qualsiasi altro uso del mio tempo. Un cattivo design con una suite di test completa è ancora un cattivo design.

Un'altra dichiarazione simile di Donald Knuth nell'intervista del libro Coders at Work , copiata da qui :

Seibel: Parlando di lavoro pratico, nel mezzo del lavoro su The Art of Computer Programming hai preso quello che si è trasformato in una pausa di dieci anni per scrivere il tuo sistema di composizione TeX. Capisco che tu abbia scritto la prima versione di TeX completamente lontano dal computer.

Knuth: Quando ho scritto TeX originariamente nel 1977 e nel '78, ovviamente non avevo una programmazione alfabetica ma avevo una programmazione strutturata. L'ho scritto su un grande taccuino a mano, a matita. Sei mesi dopo, dopo aver completato l'intero progetto, ho iniziato a digitare sul computer. E ho fatto il debug nel marzo del '78 mentre avevo iniziato a scrivere il programma nell'ottobre del '77. Il codice per questo si trova negli archivi di Stanford - è tutto a matita - e ovviamente tornerei e cambierei una subroutine mentre imparavo come doveva essere. Si trattava di un sistema di prima generazione, quindi erano possibili molte architetture diverse e dovevano essere scartate fino a quando non ci avevo vissuto per un po 'e sapevo cosa c'era lì. Ed era un problema a base di galline e uova: non si poteva comporre fino a quando non si disponevano di caratteri, ma non si potevano avere caratteri fino a quando non si poteva comporre. Ma la programmazione strutturata mi ha dato l'idea di invarianti e di sapere come creare scatole nere che potevo capire. Quindi avevo la certezza che il codice avrebbe funzionato quando avrei finalmente eseguito il debug. Sentivo che avrei risparmiato molto tempo se avessi aspettato sei mesi prima di provare qualcosa. Avevo abbastanza fiducia che il codice fosse approssimativamente corretto.

Seibel: E il risparmio di tempo sarebbe dovuto al fatto che non passeresti tempo a costruire impalcature e tronchesi per testare il codice incompleto?

Knuth: Giusto.


24
Penso che tu debba guardare al tipo di lavoro che stai facendo. Knuth e Hickey parlano del design di nuove applicazioni (innovative). Se osservi dove è popolare TDD (ampia sovra-generalizzazione), ti rendi conto che la maggior parte delle applicazioni scritte in modo TDD ha già un'architettura ben nota.
sebastiangeiger,

4
Posso vedere cosa significa Rich Hickey, ma vorrei aggiungere questo: la mia esperienza è che quando scrivi i test, devi davvero pensare al tuo design e pensare a come rendere il tuo codice testabile, che, nel mio esperienza, si traduce in un design migliore.
Niklas H,

3
Visto che l'OP richiede esperienze negative con TDD, nessuno dei tuoi esempi sembra pertinente a questa domanda in quanto nessuno dei due mostra un esempio di TDD in azione.
Winston Ewert,

5
@Michael Borgwardt: È relativamente facile aggiungere test a un design esistente e buono, per eliminare i bug nell'implementazione. Ma liberarsi del cattivo design spesso significa una riscrittura completa. Quindi l'obiettivo primario dovrebbe essere quello di ottenere il design giusto; l'esecuzione è più facile da correggere in seguito.
Joonas Pulakka,

4
La maggior parte delle applicazioni aziendali non ha il vantaggio di essere scritta e / o gestita da Donald Knuth. La durata di un'applicazione è generalmente MOLTO più lunga del suo sviluppo principale. Vorrei che le persone avessero scritto più test in anticipo sul mio progetto attuale. Ora la manutenzione è come un campo minato di infinite regressioni.
Matt H

58

La mia esperienza negativa con TDD è stata la mia prima. TDD suonava alla grande per me, avevo fatto il controllo qualità per anni e avevo ancora gli orrori nella mia mente. Volevo eliminare ogni bug prima che diventasse una build. Sfortunatamente, l'uso di TDD non garantisce che tu scriva buoni test. In effetti, la mia predisposizione iniziale era quella di scrivere semplici test che generassero un semplice codice. Codice davvero semplice che conteneva poche astrazioni. Test davvero semplici che si intrecciavano con gli interni della classe. E una volta che hai messo in atto alcune migliaia di test bitty, non ti senti certo di muoverti più velocemente quando devi cambiarne un centinaio per riformattare il tuo codice in modo da utilizzare il concetto di dominio X molto importante.

La luce si è accesa per me - TDD non è un'abilità di test. È un'abilità di progettazione. Può solo condurre a un codice buono, semplice e praticabile con la pratica e una costante consapevolezza delle direzioni di progettazione in cui ti conduce. Se stai scrivendo test per motivi di copertura del codice, creerai dei test fragili. Se stai scrivendo test per aiutarti a progettare le tue astrazioni, è solo un modo più rigoroso di scrivere il codice top-down. Puoi vedere prima il codice dal punto di vista del chiamante, il che ti incoraggia a semplificare la sua vita, piuttosto che rispecchiare gli interni di una classe sul suo bordo esterno.

Penso che TDD sia utile, ma non sono dogmatico al riguardo. Se questi "test senza valore" rendono difficile la manutenzione, eliminali! Tratto i test allo stesso modo del resto del codice. Se può essere rifattorizzato via e semplificare le cose, allora fallo!

Non l'ho visto personalmente, ma ho sentito che alcuni posti tengono traccia della copertura del codice e dei conteggi dei test. Quindi, se la raccolta delle metriche è un effetto collaterale del TDD, allora potrei vederlo anche come negativo. Eliminerò con entusiasmo 1000 righe di codice, e se ciò oscura 20 test e diminuisce la copertura del mio codice%, vabbè.


7
L'hai inchiodato al paragrafo 2.
Sheldon Warkentin,

4
"Non l'ho visto personalmente, ma ho sentito che alcuni posti tengono traccia della copertura del codice e dei conteggi dei test" Ho vissuto in un ambiente simile e in effetti nessun codice è mai stato espulso perché farlo causerebbe il fallimento di un test. Fino a quando ho iniziato a eseguire il debug dei test effettivi, e ho scoperto che molti di loro avevano difetti così gravi da costringere il codice a produrre risultati errati affinché i test potessero passare. In quel momento ho coniato la domanda: "chi sta testando i test" a cui finora non ho mai avuto una risposta soddisfacente dalla comunità TDD. Unit test per unit test, qualcuno?
jwenting

@jwenting - E questo aneddoto supporta piuttosto bene l'argomento di Rei. Ho trovato in pratica l'aspetto della protezione dalla regressione del TDD troppo esagerato, anche se in teoria è una solida idea. I test devono essere mantenuti allo stesso livello del codice di produzione perché funzioni, ed è un po 'innaturale trattare il codice non di produzione in questo modo - vedo lo stesso "marcire del codice" con simulatori hardware, generatori di codice, ecc. tutto il tempo.
Steve Jackson,

"Test davvero semplici che si sono intrecciati con gli interni della classe" <- c'è il tuo problema proprio lì. Test solo su interfacce pubbliche. TDD! = UT
Steven A. Lowe,

2
@ StevenA.Lowe - Lo so adesso, ma 9 anni fa non era così chiaro :) "TDD non è un'abilità di prova"
Steve Jackson,

41

Ho intenzione di uscire su un arto qui e dichiarare con brutale onestà che è letteralmente una perdita di tempo rituale. (Nella maggior parte delle situazioni.)

Ho comprato un libro su Unit Testing che parlava anche di TDD, e mentre sono d'accordo con i benefici di UT, dopo circa cento ore di prova di TDD, ho rinunciato a questo per una miriade di ragioni. Sto scrivendo qui, ma TDD:

  1. Non è una documentazione migliore della vera documentazione.
  2. Non rileva bug o regressioni .
  3. In realtà non rende i miei progetti migliori di quanto non siano se applico alcuni concetti di programmazione e componibilità funzionali .
  4. È il tempo che potrebbe essere speso meglio facendo revisioni del codice o lucidando la documentazione e le specifiche.
  5. Fornisce ai gestori un falso senso di sicurezza quando visualizzano un elenco di centinaia di icone verdi.
  6. Migliora la produttività nell'implementazione di algoritmi con mappature input-output limitate.
  7. È goffo nel fatto che potresti sapere cosa stai facendo a causa di TDD, ma non stai guadagnando alcuna comprensione del perché funzioni così bene, perché i tuoi progetti escono nel modo in cui funzionano.

Un'altra preoccupazione è il grado discusso di perfezione a cui si deve fare TDD per farlo con successo. Alcuni insistono sul fatto che se il TDD non viene svolto in modo persistente da tutti i membri del team dall'inizio del progetto, ne soffrirai solo. Altri insistono sul fatto che nessuno fa mai TDD dal libro. Se entrambi sono veri, ne consegue che i professionisti della TDD soffrono, che se ne rendano conto o meno.

Naturalmente, se si sostiene che facendo le cose in modo simile al TDD, si arriva a progetti che possono funzionare facilmente con TDD, beh, ci sono modi molto più rapidi per raggiungerlo - vale a dire, studiando effettivamente i concetti di componibilità. Ci sono molte risorse là fuori, anche molta rigorosa teoria matematica (soprattutto nella programmazione funzionale ma anche in altri campi). Perché non dedicare tutto il tempo all'apprendimento del TDD ?

Culturalmente, TDD mostra i sintomi di essere una pratica rituale. Cavalca la colpa; incoraggia la procedura sulla comprensione; ha un sacco di dottrine e slogan ("fingere finché non lo fai" è davvero abbastanza allarmante se lo guardi in modo obiettivo). La definizione di Wikipedia del termine "rituale" è in effetti abbastanza appropriata:

In psicologia, il termine rituale è talvolta usato in senso tecnico per un comportamento ripetitivo usato sistematicamente da una persona per neutralizzare o prevenire l'ansia; è un sintomo del disturbo ossessivo-compulsivo.


Prospettiva molto interessante riguardo al rituale. Hai anche la sensazione, in alcuni ambienti, che l'impegno di un programmatore per il suo mestiere sia giudicato esclusivamente proporzionale alla sua aderenza al TDD.
Yalestar,

Direi che in alcune situazioni può migliorare un design, ma principalmente è quando il design deve essere altamente modulare con un'interfaccia pubblica molto ben definita e facile da usare. Scrivere i test per esso prima di implementare la libreria stessa in quei casi può aiutare a appianare i bug nell'interfaccia pubblica e forzare quella modularità.
jwenting

8
@jwenting Le persone fanno TDD perché non sanno cosa rende modulare un design, quindi non possono mai togliere le loro ruote da allenamento da 35 "dalle loro bici da 40". Fare un design modulare è sempre un compito gestibile se capisci i concetti, perché ogni dilemma nel tuo design avrà dimensioni gestibili a causa del fatto che è, nella sua concezione, in procinto di diventare modulare. Non sono d'accordo sul fatto che TDD sia efficace nel forzare la modularità, ma non sono d'accordo sul fatto che si debba essere costretti a creare progetti modulari. Il design modulare è un'abilità perfettamente insegnabile e apprendibile.
Rei Miyasaka,

@jwenting Per quanto riguarda l'usabilità delle interfacce pubbliche, ci sono due scuole di pensiero tra i professionisti del TDD su quella materia, entrambe indesiderabili: rendere tutto pubblico in modo che possa essere testato o lasciare cose private se non dovrebbero essere testate comunque . Il primo impone che i dettagli di implementazione non necessari siano esposti agli utenti finali (che possono essere potenzialmente utilizzati in modo improprio o sfruttati) e il secondo impone che i test unitari siano più vicini ai test di sistema. Certo, potresti usare strumenti di unit test per accedere a privati, ma non ha molto senso fare in TDD.
Rei Miyasaka,

1
@Kall In quell'intervista, dice "circa il 15-35% in più di tempo" - non solo il 15% come lo hai citato. Lo studio coinvolge anche solo Java / C ++ / C # (probabilmente C # 2, data la data) - tutti i linguaggi dello stesso paradigma OOP imperativo. Sono certamente più del 15% e probabilmente più del 35% più produttivo in un linguaggio funzionale (e anche in C # 3), e produco molti meno bug scrivendo codice stateless e compostabile - gli stessi tipi di bug che il test migliora, perché entrambe le cose risolvono esattamente gli stessi tipi di problemi. In altre parole, certo, riduzione del 60-90% degli errori, ma rispetto a cosa ?
Rei Miyasaka,

18

Per aggiungere, un'altra preoccupazione con TDD che ho notato è:

TDD provoca uno spostamento involontario dell'attenzione del team di sviluppo dal codice di qualità a test e copertura del codice! Personalmente non mi è piaciuto TDD in quanto mi rende meno creativo e rende lo sviluppo del software un noioso processo meccanico ! I test di unità sono utili se usati con giudizio, ma diventano un peso quando vengono trattati l'obiettivo dello sviluppo del software.

Conosco un ragazzo che è un manager ed è tecnicamente noioso una volta ossessionato dal TDD. Era una cosa così magica per lui che credeva avrebbe portato soluzioni magiche a tutti i problemi del suo software mal progettato con un codice meno gestibile. Per non dire cosa è successo a quel progetto, è fallito miseramente nelle sue mani, mentre tutti i suoi test erano verdi. Immagino che TDD lo abbia aiutato a ottenere qualche tipo di informazione statistica come "99/100 dei miei casi sono verdi" ecc. Ed è stato questo il motivo della sua ossessione in quanto non sarebbe mai stato in grado di valutare la qualità o suggerire miglioramenti nella progettazione.


2
Sembra un inferno di PHB! Mi ricorda le aziende che introducono schemi di bonus - ciò che accade ovviamente è che gli sviluppatori, invece di concentrarsi sul codice di qualità, si concentrano sul soddisfare qualsiasi requisito di bonus. Inevitabilmente ottieni un codice più scadente. (C'è anche un'analogia qui con l'attuale crisi bancaria :-))
TrojanName

Beh, TDD non è una tecnica di Project Management, quindi non c'è da meravigliarsi che il tuo aspirante manager abbia fallito. D'altra parte non mi sento meno creativo, mi sento anche più creativo perché lo sviluppo di test mi dà automaticamente un'altra visione del mio codice. Tuttavia, sono d'accordo sul fatto che l'obiettivo deve essere il codice di produzione e che i test non dovrebbero incasinare una buona architettura software.
Alex,

La copertura del codice è una questione di Unit Testing, non di TDD. TDD si preoccupa solo di funzionalità e test attraverso interfacce pubbliche.
Steven A. Lowe,

14

La mia esperienza negativa principale sta provando a utilizzare TDD per modificare il codice di un altro programmatore che non ha test o test di integrazione molto, molto basilari. Quando vado per aggiungere una funzione o risolvere un problema con detto codice; Preferirei prima scrivere un test (il modo TDD). Sfortunatamente, il codice è strettamente accoppiato e non posso testare nulla senza molto refactoring.

Il refactoring è comunque un ottimo esercizio, ma è necessario per portare il codice in uno stato verificabile. E dopo questo passaggio, non ho controlli e contrappesi per vedere se le mie modifiche hanno rotto qualcosa; a corto di eseguire l'applicazione e di esaminare ogni caso d'uso.

D'altra parte, l'aggiunta di funzionalità / correzione di bug a un progetto TDD diventa molto semplice. Per natura, il codice scritto con TDD è di solito abbastanza disaccoppiato con piccoli pezzi con cui lavorare.

In ogni caso, TDD è una linea guida. Seguilo fino al punto in cui trovi la massima efficacia. Copertura test decente e codice disaccoppiato, codice ben scritto.


1
Se è difficile scrivere test unitari, in genere vi è una scarsa separazione delle preoccupazioni. Non lo vedo come un errore di TDD, se non altro rende rapidamente evidenti questi problemi.
Tom Kerr,

7
Non è un'esperienza negativa con TDD, è un'esperienza negativa con codice scadente.
Rei Miyasaka,

13

Ho fatto l'esperienza che a volte faccio troppo affidamento sui miei test per quanto riguarda la progettazione del sistema. Sono praticamente troppo in basso nei dettagli dell'implementazione nitida per fare un passo indietro per guardare il quadro più ampio. Ciò si traduce spesso in un design inutilmente complesso. Lo so, dovrei riformattare il codice, ma a volte ho l'impressione di poter risparmiare molto tempo facendo un passo indietro più spesso.

Detto questo, se hai una struttura come le rotaie in cui le tue decisioni sull'architettura sono molto limitate, questi problemi sono sostanzialmente inesistenti.

Un altro problema è quando ti fidi ciecamente dei tuoi test. La verità è - come qualsiasi altro codice - anche i tuoi test possono avere dei bug. Quindi sii critico nei confronti dei tuoi test quanto lo sei nei confronti della tua implementazione.


2
Forse dovresti scrivere alcuni test per i tuoi test! : p ...... I Kid, I Kid
Aren

+1 +1 +1 +1 (se avessi 3 account fittizi). La frase n. 2 è molto perspicace e priva del pregiudizio di conferma del TDD che è decisamente troppo diffuso.
tgm1024

11

Come un grande fan di TDD a volte vedo questi inconvenienti

  • Tentazione di scrivere troppi test per una copertura del codice quasi del 100%. Secondo me non è necessario scrivere test
    • per getter / setter di proprietà semplici
    • per ogni caso in cui viene generata un'eccezione
    • che controlla la stessa funzionalità attraverso diversi livelli. (Esempio: se hai unittest per verificare la convalida dell'input per ogni parametro, non è necessario ripetere tutti questi test anche attraverso un test di integrazione)
  • Costi di manutenzione del codice di test per test simili, che variano solo leggermente (creati tramite duplicazione di codice (aka ereditarietà copia-incolla)). Se ne hai già uno, è facile crearne uno simile. Ma se non si esegue il refactoring del codice di test, eliminando la duplicazione del codice in metodi di supporto, potrebbe essere necessario del tempo per correggere i test se i dettagli di implementazione del proprio codice di business cambiano.

  • Se sei sotto pressione del tempo, potresti essere tentato di eliminare i test rotti (o commentarli) invece di risolverli . In questo modo si perde l'investimento nei test


2
+1: "Tentazione di scrivere troppi test per circa il 100% di recupero del codice.": Sono caduto in questa trappola una volta, e dopo aver trascorso così tante ore a scrivere tutti quei test unitari, gli unici tre bug che ho trovato nel mio codice erano non coperto dai test unitari e può essere facilmente trovato eseguendo il debug del codice passo dopo passo.
Giorgio,

9

Devo ancora imbattermi in più di uno scenario come sviluppatore di giochi in cui TDD valeva la pena. E l'istanza in cui si trovava, era un pezzo di codice che era di natura puramente matematica e aveva bisogno di un approccio solido per testare contemporaneamente un numero enorme di casi limite - una necessità rara.

Forse qualcosa, un giorno mi cambierà idea, ma tra le pratiche di XP, l'idea di refactoring senza pietà e del codice che evolve la sua stessa forma sono molto più importanti e portano alla massima produttività per me, cfr. una citazione da un articolo di James Newkirk :

Semplicità: "Qual è la cosa più semplice che potrebbe funzionare?"
Il messaggio è molto chiaro Dati i requisiti di oggi, progetta e scrivi il tuo software. Non cercare di anticipare il futuro, lascia che il futuro si dispieghi. Lo farà spesso in modi molto imprevedibili, rendendo l'anticipazione un costo spesso troppo costoso da permettersi ".

I concetti di coraggio e di inasprimento dei circuiti di feedback che egli menziona sono anche, a mio avviso, fondamentali per la produttività.


9
Il problema è che senza test unitari come fai a sapere che il tuo refactoring spietato si traduce in codice che fa la stessa cosa? Nella mia esperienza, ho scoperto che, a seconda del problema, potrei impiegare meno tempo a scrivere test + codice che a scrivere il codice da solo! Il motivo si riduce principalmente al fatto che per alcuni problemi posso provare un nuovo fattore e ripetere il test automaticamente molto più velocemente di quanto potessi testarlo manualmente, il che può aumentare la velocità delle iterazioni in modo abbastanza significativo.
Mark Booth,

6
Per i giochi, molto spesso si possono vedere i risultati. Se possono essere visti e appaiono abbastanza buoni, saranno accettati, dal momento che un gioco vuole essere comunque un'esperienza soggettiva. D'altra parte, prendendo ad es. Diablo 2, ad esempio, il numero di errori nelle formule di combattimento ha mostrato dove TDD avrebbe apportato un valore enorme e risparmiato enormi quantità di lavoro sulle patch. Per problemi molto ben definiti come la risoluzione di equazioni e dove questi non possono essere giudicati dagli output visivi in ​​fase di esecuzione, TDD è un must per garantire la correttezza. Ma questa è una piccola parte del codice nella maggior parte dei giochi.
Ingegnere

Vale anche la pena ricordare che, a causa della velocità con cui vengono eseguite le simulazioni, è meglio guardare le variabili in tempo reale, sullo schermo, mentre la sim viene eseguita, piuttosto che sedersi con file di log di milioni di righe per esaminare il post.
Ingegnere

3
I test unitari rendono molto più semplice il refactoring , secondo la mia esperienza.
Tom Kerr,

1
@Nick Il grande problema nel settore dei giochi sono le scadenze, che sono sempre - "abbiamo dovuto consegnare un anno e mezzo fa". Penso che il tempo giochi contro i test unitari in ambienti a tempo limitato. In alcuni casi non è una decisione corretta, ma nella maggior parte dei casi la spedizione senza la scrittura di prova è più veloce. Dipende, dipende davvero ...
Coder

7

La mia esperienza negativa di TDD, per quanto limitata, è semplicemente sapere da dove cominciare! Per esempio, cercherò di fare qualcosa TDD eo non hanno idea di dove cominciare il blocco di test cose banali (posso nuove fino un Foooggetto, posso passare in un Quuxal Baz, e simili. I test che non si accertano niente ), o se sto cercando di implementarlo in un progetto esistente, allora scopro che dovrei riscrivere varie classi per poterle usare in TDD. Il risultato finale è che abbandono rapidamente completamente l'idea.

Probabilmente non aiuta il fatto che spesso sono l'unica persona in tutta l'azienda che sa cosa sono i test unitari (TDD o altro) e perché è una buona cosa.


1
È qui che entrano in gioco i framework beffardi. Crea un'istanza Foocon oggetti Mock anziché Quuxe Bazdirettamente, quindi puoi chiamare la funzione che vuoi testare e poi controllare che i mock siano stati chiamati con le funzioni che ti aspetti. Gli oggetti simulati sono la tecnologia abilitante che aiuta a disaccoppiare le unità e a renderle testabili. Questo è il motivo per cui i singoli sono cattivi, dal momento che spesso non puoi semplicemente deriderli . * 8 ')
Mark Booth

7

Fanatici TDD.

Per me, sono solo una di una lunga serie di pazzi religiosi che bussano alla mia porta, cercando di dimostrare che il mio modo di fare le cose è irreparabilmente rotto e l'unica strada per la salvezza è Gesù, Kent Back o Test unitari.

IMO, la loro più grande menzogna è che TDD ti porterà alla salvezza di un migliore design dell'algoritmo. Vedi il famoso solutore Soduku scritto in TDD: qui , qui , qui , qui e qui

E confrontalo con il risolutore di sudoku Peter Norvig fatto non usando TDD, ma usando ingegneria vecchio stile: http://norvig.com/sudoku.html


Senti, possiamo discutere a lungo su questo. Ma ho troppo lavoro da fare da quando mi sono laureato all'università Fullsail con la mia laurea in game design. Sulla base dei miei corsi e del mio lavoro molto impegnativo, posso affermare che TDD supera davvero il frenetico sviluppo line-by-line (mancanza di progettazione) di programmatori pigri. Guarda, non lo direi, ma è vero: la maggior parte degli sviluppatori che hanno frequentato un normale programma CS dell'università non si sono diplomati, i pochi che hanno fatto schiacciantemente non sono passati allo sviluppo del software, e per di più molti di questi riescono a malapena , linea per linea. L'università Fullsail ha un
Zombies il

corso completo di sviluppo guidato dai test da solo e che porta davvero gli sviluppatori sulla strada giusta (invece di implementare un elenco collegato in c ++).
Zombi,

I collegamenti sono rotti amico!
lmiguelvargasf,

Questo è successo molti anni dopo, ma @Zombies, guarda in "Bias di conferma". Molto di ciò che viene insegnato a tutti in CS al college rientra proprio in quella categoria. Dai un'occhiata al licenziamento
sfuggente

Lol amico stavo trollando ... Ho scritto che molto tempo fa mi ero dimenticato di quel piccolo gioiello.
Zombi

5

Se usi TDD da questi articoli "fanatici", avrai la sensazione errata di sicurezza che il tuo software non abbia errori.


1
Puoi avere qualche altra sensazione oltre a sapere che per un determinato set di input il tuo software restituisce un determinato set di output?

finché capisci che tdd è un processo di sviluppo e non una regola d'oro per risolvere qualsiasi tipo di problema, va bene. Ma la maggior parte delle persone che propongono di utilizzare questo processo hanno dimenticato che è un processo di sviluppo e come qualsiasi altro processo ha il lato positivo e il lato oscuro. Dicono per tutti che se userete tdd avrete software privo di bug, perché userete test per coprire tutte le funzionalità. E di solito non è giusto. Nel migliore dei modi ci saranno test per ogni caso (o almeno funzionalità), ma i test sono programmi (che hanno bug) ed è solo test in black box.
Dainius,

4

TDD ha alcuni vantaggi:

  • Ti concentri su come chiamare il tuo codice e cosa aspettarti prima (mentre scrivi prima il test) invece di concentrarti sulla risoluzione del problema e poi incolli in una chiamata dall'applicazione. La modularità rende più facile deridere e avvolgere.
  • I test assicurano che il tuo programma funzioni allo stesso modo prima e dopo un refactoring. Questo non significa che il tuo programma sia privo di errori, ma che continui a funzionare allo stesso modo.

TDD riguarda investimenti a lungo termine. Lo sforzo paga quando si raggiunge la modalità di manutenzione dell'applicazione e se l'applicazione non è pianificata per raggiungere quel punto, non è possibile recuperare l'investimento.

Considero il ciclo TDD rosso-verde con i piccoli passi simili a una lista di controllo per un aereo. È fastidioso e noioso controllare ogni cosa nell'aereo prima del decollo, specialmente se è banalmente semplice (i piccoli passi del TDD) ma è stato scoperto che aumenta la sicurezza. Oltre a verificare che tutto funzioni, essenzialmente ripristina il piano . In altre parole, un aereo viene riavviato prima di ogni decollo.


3
Il vantaggio 2 può essere ottenuto anche con semplici test unitari senza un approccio TDD. Beneficio 1 che dovresti fare comunque. (Concentrandosi sull'API) È ancora del tutto possibile creare un'API scadente usando TDD, ma sì, hai la garanzia che funzionerà (per le prove scritte).
Steven Jeuris,

2
La domanda non riguardava i benefici del TDD. Ci sono già molte altre domande al riguardo.
Aaronaught il

1
@aaronaught, sto affrontando i suoi punti dolenti.

Le risposte dovrebbero rispondere alla domanda .
Aaronaught il

1
@aaronaught, quindi scrivine alcuni.

3

La mia esperienza negativa sul TDD è qualcosa che provo con molte cose nuove e di tendenza. In effetti mi piace TDD perché garantisce la validità del mio codice, e ancora più importante: posso riconoscere i test falliti, dopo aver aggiunto un nuovo codice o qualsiasi tipo di refactoring.

Ciò che mi infastidisce di TDD è il fatto che ci sono molte regole o linee guida a riguardo. Dato che è ancora abbastanza nuovo, molti di noi sperimentano di essere principianti al TDD. Quindi, ciò che funziona bene per alcuni di noi, potrebbe non funzionare per altri. Quello che voglio dire è che non esiste un vero modo "sbagliato o giusto" per eseguire il TDD: esiste il modo in cui funziona per me - e il mio team se ne ho uno.

Quindi, fintanto che scrivi i test - prima o dopo il codice di produzione non importa davvero l'IMHO - non sono sicuro che il test driven significhi davvero che devi seguire tutte le linee guida che sono state dichiarate in questo momento, dal momento che non hanno ancora dimostrato di essere la soluzione ideale per il lavoro quotidiano. Se trovi un modo migliore per scrivere i test, dovresti pubblicarlo in un blog, discuterne qui o scrivere un articolo al riguardo. Quindi tra circa dieci anni avremmo potuto condividere abbastanza esperienza per essere in grado di dire quale regola del TDD può essere considerata buona o no in una determinata situazione.


+1 commento eccellente. In realtà non deve essere né l'unico vero modo o nessun modo affatto.
unpythonic il

3

Ho, in più di un'occasione, scritto un codice che ho scartato il giorno successivo da quando era goffo. Ho riavviato con TDD e la soluzione era migliore. Quindi non ho avuto troppo nella linea di esperienza TDD negativa. Tuttavia, detto ciò, ho trascorso del tempo a pensare a un problema e a trovare una soluzione migliore al di fuori dello spazio TDD.


1
Di solito un secondo tentativo ti darebbe più approfondimenti sul problema rispetto al primo tentativo, TDD o meno.
wobbily_col,

3

Ho scoperto che TDD funziona male quando si tratta di sistemi emergenti. Sono uno sviluppatore di videogiochi e recentemente ho usato TDD per creare un sistema che utilizza molteplici comportamenti semplici per creare movimenti dall'aspetto realistico per un'entità.

Ad esempio, ci sono comportamenti responsabili di allontanarti da aree pericolose di diversi tipi e quelli responsabili di spostarti verso aree interessanti di diversi tipi. Mescolare l'output di ogni comportamento crea un movimento finale.

Le viscere del sistema sono state implementate facilmente e TDD è stato utile qui per specificare di cosa dovrebbe essere responsabile ciascun sottosistema.

Tuttavia mi sono imbattuto in problemi quando si è trattato di specificare come interagiscono i comportamenti e, soprattutto, come interagiscono nel tempo. Spesso non c'era una risposta giusta e, sebbene i miei test iniziali fossero stati superati, il controllo qualità poteva continuare a trovare casi limite in cui il sistema non funzionava. Per trovare la soluzione corretta ho dovuto ripetere diversi comportamenti diversi e, se avessi aggiornato i test ogni volta per riflettere i nuovi comportamenti prima di verificare che funzionassero nel gioco, avrei potuto finire per lanciare i test più e più volte. Quindi ho eliminato quei test.

Avrei forse dovuto fare test più forti che catturassero i casi limite rilevati dal QA, ma quando hai un sistema come questo che si trova al di sopra di molti sistemi di fisica e di gioco, e hai a che fare con comportamenti nel tempo, diventa un po 'un incubo per specificare esattamente cosa sta succedendo.

Quasi certamente ho commesso errori nel mio approccio e, come ho detto per l'intestino del sistema, TDD ha funzionato alla perfezione e ha persino supportato alcuni refactor ottimizzati.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.