È una buona idea scrivere tutti i possibili casi di test dopo aver trasformato la squadra in TDD per ottenere una copertura completa?

16

Supponiamo di avere una grande applicazione di livello enterprise senza test di unità / funzionali. Durante lo sviluppo non ci sono stati processi di sviluppo basati sui test a causa di scadenze molto ravvicinate (so che non dovremmo mai promettere scadenze ravvicinate quando non siamo sicuri, ma ciò che è fatto è fatto!)

Ora che tutte le scadenze sono passate e le cose sono calme, tutti hanno accettato di trasformarci in un gruppo di lavoro basato sul TDD / BDD ... Yay!

Ora la domanda riguarda il codice che abbiamo già: (1) Va ancora bene o buona idea interrompere la maggior parte dello sviluppo e iniziare a scrivere tutti i possibili casi di test dall'inizio, anche se tutto funziona perfettamente OKAY ( ancora!)? Oppure (2) è meglio aspettare che accada qualcosa di brutto e poi durante la correzione scrivere nuovi test unitari o (3) dimenticarsi anche dei codici precedenti e solo scrivere test unitari solo per i nuovi codici e posticipare il tutto al prossimo refactor principale.

Ci sono alcuni articoli validi e correlati come questo . Non sono ancora sicuro se valga la pena investire su questo considerando che abbiamo un tempo molto limitato e molti altri progetti / lavori ci stanno aspettando.

Nota : questa domanda sta spiegando / immaginando una situazione totalmente imbarazzante in un team di sviluppo. Non si tratta di me o dei miei colleghi; è solo una situazione immaginaria. Potresti pensare che questo non dovrebbe mai accadere o il responsabile dello sviluppo è responsabile di tale disordine! Ma comunque, ciò che è fatto è fatto. Se possibile, ti preghiamo di non discendere solo perché pensi che questo non dovrebbe mai accadere.

    
posta Michel Gokan 25.11.2018 - 20:16
fonte

7 risposte

36

There was no test-driven development process during the development due to very tight deadlines

Questa affermazione è molto preoccupante. Non perché significa che hai sviluppato senza TDD o perché non stai testando tutto. Questo è preoccupante, perché ti fa pensare che TDD ti rallenti e ti faccia perdere una scadenza.

Finché la vedi in questo modo non sei pronto per TDD. Il TDD non è qualcosa a cui puoi gradualmente adattarti. O sai come farlo o non lo fai. Se provi a farlo a metà strada, ce la farai e te ne starai male.

Il TDD è qualcosa che dovresti prima praticare a casa. Impara a farlo, perché aiuta tu codice ora . Non perché qualcuno ti ha detto di farlo. Non perché ti aiuterà quando cambierai più tardi. Quando diventa qualcosa che fai perché sei di fretta, allora sei pronto per farlo professionalmente.

TDD è qualcosa che puoi fare in qualsiasi negozio. Non è nemmeno necessario convertire il codice di test. Puoi tenerlo per te se gli altri disdegnano i test. Quando lo fai bene, i test velocizzano il tuo sviluppo anche se nessun altro li esegue.

D'altra parte, se gli altri amano e eseguono i test, dovresti tenere a mente che, anche in un negozio TDD, non è compito tuo verificare i test. Significa creare un codice di produzione funzionante. Se capita di essere testabile, pulito.

Se pensi che il management debba credere nel TDD o che i tuoi colleghi programmatori debbano supportare i tuoi test, allora stai ignorando la cosa migliore che TDD fa per te. Ti mostra rapidamente la differenza tra ciò che pensi che faccia il tuo codice e ciò che effettivamente fa.

Se non riesci a vedere come questo, da solo, può aiutarti a rispettare una scadenza più veloce, allora non sei pronto per il TDD al lavoro. Hai bisogno di esercitarti a casa.

Detto questo, è bello quando il team può utilizzare i test per aiutarli a leggere il codice di produzione e quando la direzione acquisterà nuovi strumenti TDD spigolosi.

Is it a good idea to write all possible test cases after transforming the team to TDD?

Indipendentemente da ciò che sta facendo il team, non è sempre una buona idea scrivere tutti i possibili casi di test. Scrivi i casi di test più utili. La copertura del codice al 100% ha un costo. Non ignorare la legge dei rendimenti decrescenti solo perché fare una sentenza è difficile.

Salva la tua energia di test per l'interessante logica di business. La roba che prende le decisioni e applica la politica. Metti alla prova questo. Un codice di colla strutturale ovvio e di facile lettura che collega solo i materiali non ha bisogno di test quasi altrettanto male.

(1) Is it still okay or good idea to stop most of the development and start writing whole possible test cases from the beginning, even though everything is working completely OKAY (yet!)? Or

No. Questo è "facciamo una riscrittura completa" pensando. Questo distrugge la conoscenza vincente. Non chiedere alla direzione per tempo di scrivere test. Basta scrivere test. Una volta che sai cosa stai facendo, i test non ti rallenteranno.

(2) it's better to wait for something bad happen and then during the fix write new unit tests, or

(3) even forget about previous codes and just write unit tests for the new codes only and postpone everything to the next major refactor.

Risponderò alle domande 2 e 3 allo stesso modo. Quando cambi il codice, per qualsiasi motivo, è davvero bello se riesci a inserire un test. Se il codice è legacy, attualmente non accetta un test. Il che significa che è difficile testarlo prima di cambiarlo. Bene, dal momento che lo stai modificando in ogni caso puoi cambiarlo in qualcosa di verificabile e testarlo.

Questa è l'opzione nucleare. È rischioso Stai apportando modifiche senza test. Ci sono alcuni trucchi creativi per mettere il codice legacy sotto test prima di cambiarlo. Si cercano quelle che vengono chiamate cuciture che consentono di modificare il comportamento del codice senza modificare il codice. Puoi cambiare i file di configurazione, creare file, qualunque cosa sia necessaria.

Michael Feathers ci ha dato un libro a riguardo: Lavorare efficacemente con il codice legacy . Dagli una lettura e vedrai che non devi masterizzare tutto ciò che è vecchio per creare qualcosa di nuovo.

    
risposta data 26.11.2018 - 02:27
fonte
21

Is it still okay or good idea to stop most of the development and start writing whole possible test cases from the beginning [...] ?

Dato il codice legacy 1 , scrivi i test unitari in queste situazioni:

  • durante la correzione dei bug
  • durante il refactoring
  • quando aggiungi nuove funzionalità al codice esistente

Per quanto utili siano i test unitari, creare una suite di test di unità completa per una base di codice 1 esistente probabilmente non è un'idea realistica. I poteri che ti hanno spinto a consegnare in un termine stretto. Non ti hanno lasciato il tempo di creare test unitari adeguati mentre stavi sviluppando. Pensi che ti daranno tempo sufficiente per creare test per il "programma che funziona"?

1 Il codice legacy è il codice senza test unitari. Questa è la definizione TDD del codice legacy. Si applica anche se il codice precedente è stato appena consegnato [anche se l'inchiostro non si è ancora asciugato].

    
risposta data 25.11.2018 - 20:44
fonte
12

Nella mia esperienza, i test non hanno bisogno di copertura totale per essere utili. Invece, inizi a raccogliere diversi tipi di vantaggi con l'aumento della copertura:

  • oltre il 30% di copertura (ovvero un paio di test di integrazione): se i test falliscono, qualcosa è estremamente rotto (oppure i test sono instabili). Per fortuna i test ti hanno avvisato rapidamente! Tuttavia, i rilasci necessiteranno ancora di estesi test manuali.
  • oltre il 90% di copertura (ovvero la maggior parte dei componenti hanno test di unità superficiali): se i test superano, è probabile che il software vada per lo più bene. Le parti non testate sono edge case, che vanno bene per software non critico. Ma i rilasci richiedono ancora alcuni test manuali.
  • altissima copertura di funzioni / dichiarazioni / rami / requisiti: stai vivendo il sogno TDD / BDD e i tuoi test sono un riflesso preciso della funzionalità del tuo software. Puoi refactoring con alta sicurezza, compresi i cambiamenti architettonici su larga scala. Se i test passano, il tuo software è quasi pronto per il rilascio; sono richiesti solo alcuni test del fumo manuali.

La verità è che se non inizi con BDD non arriverai mai lì, perché il lavoro richiesto per testare dopo la codifica è semplicemente eccessivo. Il problema non è scrivere i test, ma più che altro sapere dei requisiti effettivi (piuttosto che dettagli di implementazione incidentale) e poter progettare il software in modo funzionale e facile da testare. Quando scrivi i test per primi o insieme al codice, questo è praticamente gratuito.

Poiché le nuove funzionalità richiedono test, ma i test richiedono modifiche di progettazione, ma il refactoring richiede anche test, si ha un po 'di problemi con uova e galline. Poiché il tuo software si avvicina alla copertura decente, dovrai eseguire un attento refactoring in quelle parti del codice in cui si verificano nuove funzionalità, solo per rendere testabili le nuove funzionalità. Questo ti rallenterà molto - inizialmente. Ma solo rifattorizzando e testando quelle parti in cui è necessario un nuovo sviluppo, i test si concentrano anche su quella zona dove sono più necessari. Il codice stabile può continuare senza test: se fosse bacato, dovresti comunque cambiarlo.

Mentre provi ad adattarti al TDD, una metrica migliore della copertura totale del progetto sarebbe la copertura del test in parti che vengono cambiate. Questa copertura dovrebbe essere molto alta fin dall'inizio, anche se non è fattibile testare tutte le parti del codice che sono influenzate da un refactoring. Inoltre, ottieni i maggiori benefici dall'elevata copertura dei test all'interno dei componenti testati. Non è perfetto, ma comunque abbastanza buono.

Si noti che mentre i test unitari sembrano essere comuni, iniziare con i pezzi più piccoli non è una strategia adatta per ottenere un software legacy in prova. Ti consigliamo di iniziare con test di integrazione che eseguono contemporaneamente una grande parte del software.

es. Ho trovato utile estrarre casi di test di integrazione da file di log del mondo reale. Naturalmente, l'esecuzione di tali test può richiedere molto tempo, motivo per cui potrebbe essere necessario impostare un server automatizzato che esegua regolarmente i test (ad esempio un Jenkins server attivato da commit). Il costo di installazione e manutenzione di un server di questo tipo è molto ridotto rispetto a quello di non eseguire regolarmente i test, a condizione che eventuali errori di test vengano effettivamente risolti rapidamente.

    
risposta data 25.11.2018 - 22:01
fonte
5

Non scrivere test per codice esistente. Non ne vale la pena.

Ciò che hai realizzato è già un po 'testato in modo completamente informale: lo hai provato costantemente a mano, le persone hanno fatto alcuni test non automatizzati, ora vengono utilizzati. Ciò significa che non troverai molti bug .

Ciò che rimane sono gli errori a cui non hai pensato. Ma quelli sono esattamente quelli che non penserai di scrivere test unitari per entrambi, quindi probabilmente non li troverai.

Inoltre, un motivo per TDD è quello di farti pensare a quali sono i requisiti esatti di un po 'di codice prima di scriverlo. In qualsiasi altro modo, l'hai già fatto.

Nel frattempo, è ancora tanto lavoro per scrivere questi test come sarebbe stato prima di scriverli. Ti costerà molto tempo, per poco beneficio.

Ed è estremamente noioso a scrivere un sacco di test senza codifica e senza trovare quasi nessun bug. Se inizi a farlo, le persone nuove a TDD lo odiano .

In breve, gli sviluppatori lo odieranno e i manager lo vedranno come costoso, mentre non sono stati trovati molti bug. Non otterrai mai la parte TDD effettiva.

Usalo sulle cose che vuoi cambiare, come una parte normale del processo.

    
risposta data 26.11.2018 - 15:53
fonte
2

Un test è un mezzo per comunicare la comprensione.

Pertanto, solo i test di scrittura per ciò che hai capito dovrebbero essere veri.

Puoi solo capire cosa dovrebbe essere vero quando lavori con esso.

Quindi scrivi solo test per il codice con cui stai lavorando.

Quando lavori con il codice che impari.

Quindi scrivi e riscrivi i test per catturare ciò che hai imparato.

Risciacqua e ripeti.

Avere uno strumento di copertura del codice eseguito con i test e accettare solo i commit alla linea principale che non riducono la copertura. Alla fine raggiungerai un alto livello di copertura.

Se non hai lavorato con il codice per un po 'di tempo, è necessario prendere una decisione aziendale. Ora è molto probabile che nessun membro del tuo team sappia come lavorarci. Probabilmente ha librerie / compilatori / documentazione scaduti che è una responsabilità enorme in quasi ogni modo.

Due opzioni:

  1. Investi il tempo per leggerlo, imparare da esso, scrivere test per esso e refactoring. Piccoli set di modifiche con versioni frequenti.
  2. Trova un modo per abbandonare quel software. Non è possibile apportare modifiche ad esso quando richiesto in ogni caso.
risposta data 26.11.2018 - 08:51
fonte
0

(1) Is it still okay or good idea to stop most of the development and start writing whole possible test cases from the beginning, even though everything is working completely OKAY (yet!)?
(2) it's better to wait for something bad happen and then during the fix write new unit tests

Uno degli scopi principali dei test è garantire che un cambiamento non abbia infranto nulla. Questo è un processo in tre fasi:

  1. Conferma che i test hanno avuto esito positivo
  2. Apporta modifiche
  3. Conferma che i test hanno ancora esito positivo

Ciò significa che è necessario avere test di lavoro prima in cui si modifica effettivamente qualcosa. Se scegli il secondo percorso, significa che dovrai costringere i tuoi sviluppatori a scrivere test prima ancora che tocchino il codice. E sospetto strongmente che quando si trovano già di fronte a un cambiamento nel mondo reale, gli sviluppatori non daranno ai test unitari l'attenzione che meritano.

Quindi suggerisco di suddividere le attività di scrittura dei test e di cambiamento per evitare che gli sviluppatori sacrificino la qualità di uno per l'altro.

even though everything is working completely OKAY (yet!)?

Tanto per farvi notare in modo specifico, è un errore comune pensare che siano necessari solo test quando il codice non funziona. Hai bisogno di test anche quando il codice funziona, ad esempio per dimostrare a qualcuno che [il bug che si verifica di recente] non è dovuto alla tua parte perché i test stanno ancora superando.
Conferma che tutto funziona come prima è un importante vantaggio del test che stai omettendo quando implichi che non hai bisogno di test quando il codice funziona.

(3) even forget about previous codes and just write unit tests for the new codes only and postpone everything to the next major refactor

Idealmente, tutto il codice sorgente esistente dovrebbe ora ottenere i test unitari. Tuttavia, vi è una ragionevole argomentazione sul fatto che il tempo e gli sforzi (e il costo) necessari per farlo sono semplicemente non rilevanti per determinati progetti.
Ad esempio, un'applicazione che non è più in fase di sviluppo e che non si prevede cambierà più (ad esempio il client non la usa più, o il client non è più un client), si può sostenere che non è più rilevante testare questo codice .

Tuttavia, non è così chiaro dove si disegna la linea. Questo è qualcosa che un'azienda deve analizzare in un'analisi costi-benefici. I test di scrittura costano tempo e fatica, ma si aspettano qualsiasi sviluppo futuro su quella applicazione? I guadagni derivanti dall'avere test unitari superano il costo di scriverli?

Questa non è una decisione che tu (come sviluppatore) puoi prendere. Nella migliore delle ipotesi, puoi offrire una stima del tempo necessario per implementare i test su un determinato progetto, e spetta al management decidere se c'è un'aspettativa sufficiente per il fatto di dover effettivamente mantenere / sviluppare il progetto.

and postpone everything to the next major refactor

Se il prossimo refactor principale è un dato, allora hai davvero bisogno di scrivere i test.

Ma non rimandare fino a quando non ci si trova di fronte a cambiamenti importanti. Il mio punto di partenza (non combinando la scrittura di test e l'aggiornamento del codice) è ancora valido, ma voglio aggiungere un secondo punto qui: i vostri sviluppatori attualmente conoscono meglio il progetto rispetto a mesi se passano quel tempo a lavorare su altri progetti. Approfitta dei periodi in cui gli sviluppatori sono già in fase di riscaldamento e non è necessario capire come funzioneranno di nuovo in futuro.

    
risposta data 26.11.2018 - 10:28
fonte
0

I miei due centesimi:

Aspetta un importante aggiornamento tecnico al sistema e scrivi i test poi ... ufficialmente con il supporto del business.

In alternativa, supponiamo che tu sia un negozio SCRUM, il tuo carico di lavoro è rappresentato dalla capacità e puoi assegnare una percentuale di questo al test dell'unità, ma ...

Dire che stai per tornare indietro e scrivere i test è ingenuo, quello che stai per fare è scrivere test, refactoring e scrivere altri test dopo che il refactor ha reso il codice più testabile, motivo per cui è è meglio iniziare con i test come già sai e ...

È meglio che l'autore originale scriva i test e rifattori il codice che hanno scritto in precedenza, non è l'ideale, ma per esperienza vuoi che il refattore renda il codice non peggiore.

    
risposta data 26.11.2018 - 22:01
fonte

Leggi altre domande sui tag