TDD e unit test [chiuso]


117

La mia azienda è abbastanza nuova nel testare l'unità del nostro codice. Leggo da tempo di TDD e unit test e sono convinto del loro valore. Ho tentato di convincere il nostro team che il TDD vale lo sforzo di imparare e cambiare la nostra mentalità su come programmiamo, ma è una lotta. Il che mi porta alla mia domanda.

Ci sono molti nella comunità TDD che sono molto religiosi nello scrivere il test e poi il codice (e io sono con loro), ma per un team che sta lottando con TDD un compromesso porta ancora vantaggi aggiuntivi?

Probabilmente posso riuscire a convincere il team a scrivere test unitari una volta che il codice è stato scritto (forse come requisito per il check-in del codice) e la mia ipotesi è che ci sia ancora valore nello scrivere tali test unitari.

Qual è il modo migliore per portare una squadra in difficoltà in TDD? E in caso contrario, vale comunque la pena scrivere unit test anche dopo che il codice è stato scritto?

MODIFICARE

Quello che ho portato via da questo è che è importante per noi iniziare i test unitari, da qualche parte nel processo di codifica. Per quelli nel team che raccolgono il concetto, inizia a spostarsi di più verso TDD e prima di testare. Grazie per il contributo di tutti.

AZIONE SUPPLEMENTARE

Di recente abbiamo avviato un nuovo piccolo progetto e una piccola parte del team ha utilizzato TDD, il resto ha scritto unit test dopo il codice. Dopo aver concluso la parte di codifica del progetto, coloro che hanno scritto unit test dopo il codice sono rimasti sorpresi nel vedere i codificatori TDD già fatti e con un codice più solido. È stato un buon modo per conquistare gli scettici. Abbiamo ancora molti problemi da affrontare, ma la battaglia delle volontà sembra essere finita. Grazie per tutti coloro che hanno offerto consigli!


1
Potresti trovare utile questo thread: stackoverflow.com/questions/917334/should-i-use-tdd
Randolpho

29
+1 per il FOLLOW UP. È una bella storia.
Carl Manaster

Risposte:


76

Se il team è in difficoltà nell'implementare TDD, ma prima non creava alcun test unitario ... quindi avviarli creando test unitari dopo la scrittura del codice. Anche i test unitari scritti dopo il codice sono meglio di nessun test unitario!

Una volta che sono esperti in Unit Testing (e in tutto ciò che ne deriva), puoi lavorare per convincerli a creare prima i test ... e poi il codice.


3
È corretto, il team non stava creando alcun test unitario prima. Sembra un bel trampolino di lancio per il TDD completo.
Walter

Non posso essere più d'accordo con questo. In effetti, penso di aver scritto qualcosa di simile per una domanda simile qualche mese fa. Dov'è ... Aah! stackoverflow.com/questions/917334/should-i-use-tdd/…
Randolpho

27

Vale assolutamente la pena scrivere gli unit test dopo che il codice è stato scritto. È solo che a volte è spesso più difficile perché il tuo codice non è stato progettato per essere testabile e potresti averlo complicato eccessivamente.

Penso che un buon modo pragmatico per portare una squadra in TDD sia fornire il metodo alternativo di "test durante lo sviluppo" nel periodo di transizione, o possibilmente a lungo termine. Dovrebbero essere incoraggiati a TDD sezioni di codice che sembrano loro naturali. Tuttavia, in sezioni di codice che sembrano difficili da affrontare prima del test o quando si utilizzano oggetti predeterminati da un processo A&D non agile, agli sviluppatori può essere data la possibilità di scrivere una piccola sezione del codice, quindi scrivere test per coprirlo codice e ripetendo questo processo. Scrivere unit test per un codice immediatamente dopo aver scritto quel codice è meglio che non scrivere alcun unit test.


16

A mio modesto parere è meglio avere una copertura del test del 50% con "prima il codice, prova dopo" e una libreria completata al 100%, che una copertura del test del 100% e una libreria completata al 50% con TDD. Dopo un po ', si spera che i tuoi colleghi sviluppatori trovino divertente ed educativo scrivere test per tutto il publiccodice che scrivono, quindi TDD si intrufolerà nella loro routine di sviluppo.


3
Capisco la tua deriva ma sono diffidente riguardo alla "libreria completata al 100%" con una copertura del test del 50% ... solo dalla mia esperienza che ogni pezzo di codice che non è coperto da alcuni test contiene almeno un bug. O per dirla in un altro modo: le persone tendono ad evitare di scrivere test per codice che trarrebbero davvero beneficio da ulteriori test :)
Aaron Digulla

2
Bene, un altro modo per dirlo è il codice difettoso che è stato rilasciato è meglio del codice perfetto che langue per sempre. Ovviamente ci sono delle eccezioni tosse NASA tosse , ma per la maggior parte, ottenere il codice là fuori. Puoi ancora aggiungere test dopo che è stato rilasciato.
jcdyer

3
Cosa intendi per "libreria completata al 100%". Lo consideri completo se buggy? Non includi il test nella definizione di fatto?
Pascal Thivent,

10
essere testati non è una condizione sufficiente per essere privi di bug
fa.

2
La copertura del test misurata dagli strumenti di copertura del test è un'arma a doppio taglio. Se viene ottenuto invocando tutti i metodi sull'IUT, ma i test non stanno realmente testando il comportamento che potrebbe non funzionare, gli sviluppatori e gli altri stakeholder avranno un falso senso di sicurezza. L'intero movimento verso il TDD all'interno della tua organizzazione può esplodere in faccia quando un comportamento critico non viene testato, ma hai una copertura del test del 100%. La cosa più importante non è la quantità, ma la qualità.
Doug Knesek

12

Ho appena letto questo su un calendario: "Ogni regola, eseguita al massimo, diventa ridicola o addirittura pericolosa". Quindi il mio suggerimento è di non essere religioso al riguardo. Ogni membro del tuo team deve trovare un equilibrio tra ciò che sente "giusto" quando si tratta di test. In questo modo, ogni membro del tuo team sarà più produttivo (invece di, diciamo, pensare "perché devo scrivere questo sti **** test ??").

Quindi alcuni test sono meglio di nessuno, i test dopo il codice sono migliori di pochi test e il test prima che il codice sia migliore che dopo. Ma ogni passaggio ha i suoi meriti e non dovresti disapprovare anche i piccoli passi.


"cosa provano" Come sviluppatore non ricordo di aver mai avuto alcun desiderio (corretto) di eseguire test di unità automatizzati attraverso i miei sentimenti, solo quelli manuali. Non credo di essere il solo a non avere entusiasmo per i test
Gennady Vanin Геннадий Ванин

@ vgv8: Ciò significa che i tuoi test non ti aiutano. Ci possono essere molte ragioni per cui questo è; Suggerisco di scavare più a fondo. Qualsiasi progetto beneficia di buoni test e soffre di cattivi test. Noterai quando inizierai a scrivere dei buoni test e da quel momento nulla potrà più impedirti di scrivere.
Aaron Digulla

ciò che mi sembra giusto, è un livello di test che copre ciò che le unità di programmazione dovrebbero fare, e da un livello funzionale: ciò che gli utenti stanno facendo normalmente, che include i cattivi risultati che alcuni chiamano "bug segnalati". Se un bug viene confermato, viene scritto almeno un test! più grande è il progetto e più grande è il team, più questo è importante.
DaFi4

12

TDD riguarda il design! Quindi, se lo usi, sarai sicuro di avere un design testabile del tuo codice, rendendo più facile scrivere i tuoi test. Se scrivi test dopo che il codice è stato scritto, sono ancora preziosi ma IMHO perderai tempo poiché probabilmente non avrai un design testabile.

Un suggerimento che posso darti per cercare di convincere il tuo team ad adottare TDD è usare alcune delle tecniche descritte in Fearless Change: Patterns for Introducing New Ideas, di Mary Lynn Manns e Linda Rising .


3
+1: Test Driven Development significa che il progetto è stato guidato da considerazioni di test.
S.Lott

+1. I test unitari successivi ovviamente ti aiuteranno, ma perderai i vantaggi di avere un "progetto verificabile" se non scrivi gli unit test in anticipo.
Noufal Ibrahim

9

Se sono nuovi ai test, IMO inizia a testare il codice che è già stato scritto e passa lentamente alla scrittura di test prima. Come qualcuno che cerca di imparare il TDD e che è nuovo ai test unitari, ho trovato un po 'difficile fare un 180 completo e cambiare la mia mentalità per scrivere i test prima del codice, quindi l'approccio che sto adottando è una specie di 50-50 mix ; quando so esattamente come sarà il codice, scriverò il codice e poi scriverò un test per verificarlo. Per le situazioni in cui non sono del tutto sicuro, inizierò con un test e lavorerò a ritroso.

Ricorda anche che non c'è niente di sbagliato nello scrivere test per verificare il codice, invece di scrivere codice per soddisfare i test. Se la tua squadra non vuole seguire la rotta TDD, non forzarla.


6

Probabilmente posso riuscire a convincere il team a scrivere test unitari una volta che il codice è stato scritto (forse come requisito per il check-in del codice) e la mia ipotesi è che ci sia ancora valore nello scrivere tali test unitari.

Non c'è assolutamente alcun dubbio sul fatto che ci sia valore nel codice unit testato (indipendentemente da quando sono stati scritti i test) e includo "il codice è testato unitariamente" nella "Definizione di Fatto". Le persone possono usare TDD o meno, purché testino.

Per quanto riguarda il controllo della versione, mi piace usare " rami di sviluppo " con una politica di test di unità (cioè il codice si compila e si compila, tutti i test di unità passano). Quando le funzionalità sono terminate, vengono pubblicate dai rami di sviluppo al trunk. In altre parole, il trunk branch è il " Done branch " (Nessuna spazzatura sul trunk!) E ha una politica di spedizione (può essere rilasciata in qualsiasi momento) che è più rigorosa e include più cose di "unit test".


4

Questo è qualcosa con cui il tuo team dovrà avere i propri successi prima di iniziare a crederci. Mi lamenterò della mia epifania nUnit per chiunque abbia a cuore:

Circa 5 anni fa ho scoperto nUnit lavorando a un progetto. Avevamo quasi completato la V1.0 e ho creato alcuni test solo per provare questo nuovo strumento. Avevamo molti bug (ovviamente!) Perché eravamo una nuova squadra, con una scadenza ravvicinata, grandi aspettative (suona familiare?) Ecc. Comunque abbiamo ottenuto 1.0 in e abbiamo iniziato con 1.1. Abbiamo riorganizzato un po 'il team e mi sono stati assegnati 2 sviluppatori. Ho fatto una demo di 1 ora per loro e ho detto loro che tutto ciò che abbiamo scritto doveva avere un test case con esso. Siamo stati costantemente "dietro" al resto del team durante il ciclo di sviluppo 1.1 perché stavamo scrivendo più codice, gli unit test. Abbiamo finito per lavorare di più, ma ecco il vantaggio: quando finalmente siamo entrati in test, avevamo esattamente 0 bug nel nostro codice. Abbiamo aiutato tutti gli altri a eseguire il debug e a riparare i loro bug. Nell'autopsia, quando si sono presentati i conteggi dei bug,

Non sono così stupido da pensare che tu possa mettere alla prova la tua strada verso il successo, ma sono un vero sostenitore quando si tratta di test unitari. Il progetto ha adottato nUnit e si è presto diffuso in azienda per tutti i progetti .Net come risultato di 1 successo. Il periodo di tempo totale per la nostra versione V1.1 è stato di 9 settimane di sviluppo, quindi NON è stato sicuramente un successo immediato. Ma a lungo termine, si è rivelato un successo per il nostro progetto e per l'azienda per cui abbiamo costruito soluzioni.


"Il progetto ha adottato nUnit e si è presto diffuso in azienda per tutti i progetti .Net" E cosa fare se un prodotto / progetto ha codice C #, Java, C ++, SQL Server?
Gennady Vanin Геннадий Ванин

Non so ... Trovate un modo per testare tutti i componenti prima di distribuirli in produzione? Il test unitario è solo un aspetto di un piano di test completo prima che venga pubblicato. Puoi fare buchi in qualsiasi scenario.
Nessun rimborso Nessun rimborso

4

Non c'è dubbio che il test (Primo, Mentre o anche Dopo) salverà la tua pancetta e migliorerà la tua produttività e sicurezza. Consiglio di adottarlo!

Mi trovavo in una situazione simile, perché ero uno sviluppatore "noob", spesso ero frustrato quando lavoravo al progetto di squadra dal fatto che un contributo aveva rotto la build. Non sapevo se dovevo incolpare o, in alcuni casi, anche chi incolpare. Ma ero più preoccupato di fare la stessa cosa ai miei colleghi sviluppatori. Questa consapevolezza ha poi motivato ad adottare alcune strategie TDD. Il nostro team ha iniziato con giochi stupidi e regole, come non puoi tornare a casa finché tutti i tuoi test non sono passati, o se invii qualcosa senza un test, allora devi comprare a tutti "birra / pranzo / ecc" e ha reso TDD più divertente.


3

Uno degli aspetti più utili del test unitario è garantire la continua correttezza del codice già funzionante. Quando puoi effettuare il refactoring a piacimento, lascia che un IDE ti ricordi gli errori in fase di compilazione, quindi fai clic su un pulsante per consentire ai tuoi test di individuare potenziali errori di runtime, a volte arrivando a blocchi di codice precedentemente banali, quindi penso che troverai il tuo team cominciando ad apprezzare TDD. Quindi iniziare con il test del codice esistente è sicuramente utile.

Inoltre, per essere sincero, ho imparato di più su come scrivere codice testabile provando a testare codice scritto piuttosto che iniziare con TDD. All'inizio può essere troppo astratto se stai cercando di pensare a contratti che raggiungeranno l'obiettivo finale e consentiranno il test. Ma quando guardi il codice e puoi dire "Questo singleton qui rovina completamente l'inserimento di dipendenze e rende impossibile il test", inizi a sviluppare un apprezzamento per quali modelli rendono più facile la tua vita di test.


3

Bene, se non scrivi prima i test non è "Test Driven", è solo un test. Ha vantaggi in sé e se si dispone già di una base di codice l'aggiunta di test è sicuramente utile anche se non è TDD ma semplicemente test.

Scrivere i test prima significa concentrarsi su ciò che il codice dovrebbe fare prima di scriverlo. Sì, hai anche un test che lo fa ed è buono, ma alcuni potrebbero obiettare che non è nemmeno il punto più importante.

Quello che farei è formare il team su progetti di giocattoli come questi (vedi Coding Dojo, Katas) usando TDD (se riesci a far partecipare programmatori TDD esperti a tale workshop sarebbe ancora meglio). Quando vedranno i vantaggi useranno TDD per il progetto reale. Ma nel frattempo non forzarli, se non vedono il vantaggio non lo faranno bene.


3

Se hai sessioni di progettazione prima di scrivere codice o devi produrre un documento di progettazione, puoi aggiungere Test unitari come risultato tangibile di una sessione.

Questo potrebbe quindi servire come specifica su come dovrebbe funzionare il codice. Incoraggia l'accoppiamento durante la sessione di progettazione, per convincere le persone a parlare di come dovrebbe funzionare qualcosa e cosa dovrebbe fare in determinati scenari. Quali sono i casi limite, con casi di test espliciti per loro in modo che tutti sappiano cosa farà se ad esempio viene fornito un argomento nullo.

A parte, ma anche BDD potrebbe essere di interesse


Non ero a conoscenza di BDD. Dovrò leggere di più a riguardo.
Walter

3

Potresti trovare un po 'di trazione mostrando uno o due esempi in cui TDD si traduce in meno codice scritto - poiché scrivi solo il codice richiesto per superare il test, è più facile resistere alla tentazione di placcare oro o impegnarsi in YAGNI. Il codice che non scrivi non ha bisogno di essere mantenuto, refactoring, ecc, quindi è un "vero risparmio" che può aiutare a vendere il concetto di TDD.

Se puoi dimostrare chiaramente il valore in termini di tempo, costo, codice e bug salvati, potresti scoprire che è una vendita più facile.


2

Iniziare a costruire classi di test JUnit è il modo per iniziare, per il codice esistente è l'unico modo per iniziare. Nella mia esperienza è molto utile creare classi di test per codice esistente. Se la direzione ritiene che questo investirà troppo tempo, si può proporre di scrivere classi di test solo quando si scopre che la classe corrispondente contiene un bug o ha bisogno di essere ripulita.

Per il processo di manutenzione l'approccio per ottenere il team oltre la linea sarebbe scrivere test JUnit per riprodurre i bug prima di risolverli, ad es.

  • viene segnalato un bug
  • creare la classe di test JUnit se necessario
  • aggiungi un test che riproduca il bug
  • aggiusta il tuo codice
  • eseguire il test per mostrare che il codice corrente non riproduce il bug

Puoi spiegare che "documentando" i bug in questo modo eviterai che questi bug si ripresentino in seguito. Questo è un vantaggio che il team può provare immediatamente.


2

L'ho fatto in molte organizzazioni e ho trovato il modo migliore per avviare e seguire TDD è impostare la programmazione in coppia. Se hai qualcun altro su cui puoi contare che conosce TDD, allora voi due potete dividervi e accoppiarvi con altri sviluppatori per fare effettivamente un po 'di programmazione accoppiata usando TDD. In caso contrario, addestrerei qualcuno che ti aiuterà a farlo prima di presentarlo al resto della squadra.

Uno dei principali ostacoli con i test unitari e in particolare con TDD è che gli sviluppatori non sanno come farlo, quindi non possono vedere come può valere il loro tempo. Inoltre, quando inizi per la prima volta, è molto più lento e non sembra fornire vantaggi. Ti offre davvero vantaggi solo quando sei bravo. Impostando sessioni di programmazione accoppiate puoi consentire agli sviluppatori di apprenderlo rapidamente e di diventare bravi più velocemente. Inoltre potranno vederne i benefici immediati mentre lavorate insieme.

Questo approccio ha funzionato molte volte per me in passato.


2

Un modo efficace per scoprire i vantaggi di TDD è eseguire una riscrittura significativa di alcune funzionalità esistenti, forse per motivi di prestazioni. Creando una suite di test che fanno un buon lavoro coprendo tutte le funzionalità del codice esistente, questo ti dà quindi la sicurezza di eseguire il refactoring al contenuto del tuo cuore con la piena fiducia che le tue modifiche siano sicure.

Si noti che in questo caso sto parlando di testare la progettazione o il contratto - unit test che i dettagli di implementazione del test non saranno adatti qui. Ma poi di nuovo, TDD non può testare l'implementazione per definizione, poiché dovrebbero essere scritti prima dell'implementazione.


1

TDD è uno strumento che gli sviluppatori possono utilizzare per produrre codice migliore. Mi è capitato di sentire che l'esercizio di scrivere codice testabile è tanto prezioso quanto i test stessi. L'isolamento dell'IUT (Implementation Under Test) a scopo di test ha l'effetto collaterale di disaccoppiare il codice.

Il TDD non è per tutti e non c'è magia che indurrà una squadra a scegliere di farlo. Il rischio è che gli autori di unit test che non sanno cosa vale la pena testare scriveranno molti test di basso valore, che saranno carne da cannone per gli scettici TDD nella tua organizzazione.

Di solito eseguo test di accettazione automatizzati non negoziabili, ma consento agli sviluppatori di adottare il TDD come preferiscono. Ho chiesto ai miei esperti TDD di addestrare / mentore il resto e "provare" l'utilità con l'esempio per un periodo di molti mesi.

Si tratta di un cambiamento tanto sociale / culturale quanto tecnico.

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.