Come può funzionare nella pratica la consegna continua?


22

La consegna continua suona bene, ma i miei anni di esperienza nello sviluppo di software suggeriscono che in pratica non può funzionare.

(Modifica: per chiarire, ho sempre molti test eseguiti automaticamente. La mia domanda è su come ottenere la fiducia da consegnare su ogni check-in, che comprendo è la forma completa di CD. L'alternativa non è cicli di un anno Si tratta di iterazioni ogni settimana (che alcuni potrebbero considerare ancora CD se eseguito correttamente), due settimane o mese; incluso un QA vecchio stile alla fine di ciascuno, che integra i test automatizzati.)

  • La copertura completa del test è impossibile. Devi dedicare molto tempo - e il tempo è denaro - per ogni piccola cosa. Questo è prezioso, ma il tempo potrebbe essere speso per contribuire alla qualità in altri modi.
  • Alcune cose sono difficili da testare automaticamente. Ad esempio la GUI. Anche il selenio non ti dirà se la tua GUI è traballante. L'accesso al database è difficile da testare senza dispositivi ingombranti e anche questo non copre strani casi angolari nella memoria dei dati. Allo stesso modo la sicurezza e molte altre cose. Solo il codice di livello aziendale è effettivamente testabile in unità.
  • Anche nel livello aziendale, la maggior parte del codice non ha funzioni semplici i cui argomenti e valori di ritorno possono essere facilmente isolati a scopo di test. Puoi dedicare molto tempo alla costruzione di oggetti finti, che potrebbero non corrispondere alle implementazioni reali.
  • I test di integrazione / funzionali integrano i test unitari, ma richiedono molto tempo per essere eseguiti poiché di solito comportano la reinizializzazione dell'intero sistema su ciascun test. (Se non si reinizializza, l'ambiente di test è incoerente.)
  • Il refactoring o qualsiasi altra modifica interrompe molti test. Passi molto tempo a ripararli. Se si tratta di convalidare modifiche significative delle specifiche, va bene, ma spesso i test si interrompono a causa di dettagli di implementazione di basso livello senza significato, non cose che forniscono davvero informazioni importanti. Spesso la messa a punto è focalizzata sulla rielaborazione degli interni del test, non sul vero controllo della funzionalità che viene testata.
  • I rapporti sul campo relativi ai bug non possono essere facilmente abbinati alla precisa micro versione del codice.

Funziona molto bene con Etsy slideshare.net/OReillyOSCON/… !
YoTsumi,

4
La consegna continua non richiede test (ma aiuta). Si riferisce al fatto che le cose che costruisci su base regolare POTREBBERO essere spedite al cliente, se necessario.

È interessante notare che le tue obiezioni alla consegna continua si concentrano in modo schiacciante sui test come elemento del CD. Tuttavia, questa è solo una parte del puzzle: sono necessari strumenti interni competenti, sviluppatori impegnati in rigorosi controlli di qualità, un approccio di priorità ampiamente approfondito nei test automatici, per non parlare del forte supporto organizzativo. Si può fare, ma ci vogliono molte persone per impegnarsi nella causa.
Stephen Gross,

1
@Stephen Sì, mi sto concentrando sui test, perché sono d'accordo su tutti gli altri aspetti. Sono anche a favore dei test. Non vedo come puoi avere abbastanza fiducia per distribuire ogni check-in.
Joshua Fox,

@ Thorbjørn Ravn Andersen. Certamente, il CD sembra richiedere dei test. Come puoi avere la sicurezza di spedire automaticamente ogni check-in senza di esso.
Joshua Fox,

Risposte:


29

i miei anni di esperienza nello sviluppo di software suggeriscono che in pratica non può funzionare.

L'hai provato? Dave e io abbiamo scritto il libro sulla base di molti anni di esperienza collettiva, sia di noi stessi che di altre persone anziane in ThoughtWorks, facendo effettivamente le cose di cui discutiamo. Nulla nel libro è speculativo. Tutto ciò di cui discutiamo è stato provato e testato anche su grandi progetti distribuiti. Ma non ti suggeriamo di prenderlo per fede. Ovviamente dovresti provarlo tu stesso e scrivere ciò che trovi funziona e cosa no, incluso il contesto rilevante, in modo che gli altri possano imparare dalle tue esperienze.

La consegna continua si concentra principalmente sui test automatizzati. Spendiamo circa 1/3 del libro a parlarne. Lo facciamo perché l'alternativa, il test manuale, è costosa e soggetta a errori, e in realtà non è un ottimo modo per costruire software di alta qualità (come diceva Deming, "Smettere di dipendere dall'ispezione di massa per raggiungere la qualità. Migliorare il processo e costruire la qualità in il prodotto in primo luogo ")

La copertura completa del test è impossibile. Devi dedicare molto tempo - e il tempo è denaro - per ogni piccola cosa. Questo è prezioso, ma il tempo potrebbe essere speso per contribuire alla qualità in altri modi.

Naturalmente la copertura completa dei test è impossibile, ma qual è l'alternativa: copertura zero test? C'è un compromesso. Nel mezzo c'è la risposta corretta per il tuo progetto. Troviamo che in generale dovresti aspettarti di dedicare circa il 50% del tuo tempo alla creazione o alla manutenzione di test automatici. Ciò può sembrare costoso fino a quando non si considerano i costi di test manuali completi e di correzione dei bug che emergono dagli utenti.

Alcune cose sono difficili da testare automaticamente. Ad esempio la GUI. Anche il selenio non ti dirà se la tua GUI è traballante.

Ovviamente. Dai un'occhiata al quadrante di prova di Brian Marick. È ancora necessario eseguire manualmente test esplorativi e test di usabilità. Ma è per questo che dovresti usare i tuoi costosi e preziosi esseri umani, non i test di regressione. La chiave è che è necessario implementare una pipeline di distribuzione in modo da preoccuparsi solo di eseguire costose convalide manuali contro build che hanno superato una suite completa di test automatizzati. In questo modo riduci sia la quantità di denaro che spendi per i test manuali, sia il numero di bug che sono mai passati a test o produzione manuali (a quel punto sono molto costosi da risolvere). I test automatizzati eseguiti correttamente sono molto più economici nel ciclo di vita del prodotto, ma ovviamente si tratta di una spesa in conto capitale che si ammortizza nel tempo.

L'accesso al database è difficile da testare senza dispositivi ingombranti e anche questo non copre strani casi angolari nella memoria dei dati. Allo stesso modo la sicurezza e molte altre cose. Solo il codice di livello aziendale è effettivamente testabile in unità.

L'accesso al database viene testato implicitamente dai test di accettazione funzionale basati sullo scenario end-to-end. La sicurezza richiederà una combinazione di test automatici e manuali - test di penetrazione automatizzati e analisi statiche per trovare (ad esempio) sovraccarichi del buffer.

Anche nel livello aziendale, la maggior parte del codice non ha funzioni semplici i cui argomenti e valori di ritorno possono essere facilmente isolati a scopo di test. Puoi dedicare molto tempo alla costruzione di oggetti finti, che potrebbero non corrispondere alle implementazioni reali.

Ovviamente i test automatizzati sono costosi se si costruiscono male il software e i test. Consiglio vivamente di dare un'occhiata al libro "software orientato agli oggetti in crescita, guidato da test" per capire come farlo nel modo giusto affinché i test e il codice siano mantenibili nel tempo.

I test di integrazione / funzionali integrano i test unitari, ma richiedono molto tempo per essere eseguiti poiché di solito comportano la reinizializzazione dell'intero sistema su ciascun test. (Se non si reinizializza, l'ambiente di test è incoerente.)

Uno dei prodotti su cui lavoravo ha una serie di 3.500 test di accettazione end-to-end che richiedono 18 ore per l'esecuzione. Lo eseguiamo in parallelo su una griglia di 70 scatole e riceviamo feedback in 45m. Ancora più a lungo dell'ideale, ecco perché lo eseguiamo come seconda fase della pipeline dopo che i test unitari sono stati eseguiti in pochi minuti, quindi non sprechiamo le nostre risorse in un build che non ha un livello base di fiducia in.

Il refactoring o qualsiasi altra modifica interrompe molti test. Passi molto tempo a ripararli. Se si tratta di convalidare modifiche significative delle specifiche, va bene, ma spesso i test si interrompono a causa di dettagli di implementazione di basso livello senza significato, non cose che forniscono davvero informazioni importanti. Spesso la messa a punto è focalizzata sulla rielaborazione degli interni del test, non sul vero controllo della funzionalità che viene testata.

Se il codice e i test sono ben incapsulati e liberamente accoppiati, il refactoring non interromperà molti test. Descriviamo nel nostro libro come fare la stessa cosa anche per i test funzionali. Se i tuoi test di accettazione si interrompono, questo è un segno che stai perdendo uno o più test unitari, quindi parte del CD comporta un costante miglioramento della copertura dei test per cercare di trovare bug in precedenza nel processo di consegna in cui i test sono più accurati e il i bug sono più economici da correggere.

I rapporti sul campo relativi ai bug non possono essere facilmente abbinati alla precisa micro versione del codice.

Se stai testando e rilasciando più frequentemente (parte del punto del CD), è relativamente semplice identificare la modifica che ha causato il bug. L'intero punto del CD è ottimizzare il ciclo di feedback in modo da poter identificare i bug il prima possibile dopo che sono stati registrati per il controllo della versione - e in effetti, preferibilmente prima che vengano archiviati (motivo per cui eseguiamo i test di build e unità prima del check-in).


Grazie per la tua risposta. Sì, credo nei test. I miei progetti hanno avuto una buona copertura del codice da test automatici eseguiti con la build giornaliera. Sto solo dicendo che hai bisogno di una sorta di iterazione prima di rilasciare. "Devi ancora eseguire test esplorativi ... manualmente." Non capisco. Un sistema CD completo viene distribuito su ogni check-in. Come puoi farlo se includi test manuali?
Joshua Fox,

3
Mi piace distinguere tra consegna continua e distribuzione continua. Ecco la differenza La consegna continua significa che il sistema è sempre pronto per la produzione e può essere rilasciato su richiesta semplicemente premendo un pulsante. Il rilascio è una decisione commerciale. La distribuzione continua è un caso limitante in cui si rilascia ogni build valida (notare non tutti i check-in - alcuni check-in non danno luogo a una build rilasciabile). In entrambi i casi è possibile includere convalide manuali: la chiave è il concetto della pipeline di distribuzione .
Jez Humble,

Riguardo a "L'accesso al database è testato implicitamente dai test di accettazione funzionale basati sullo scenario end-to-end". Il problema chiave è che questo è implicito . Le persone sembrano felici, ma questo è un approccio che richiede molto tempo; invece di dire il problema "Questo è quello che mi aspettavo dal DB e invece ho ottenuto questo", dice "Qualcosa si è rotto in uno dei 100 strati".
Atoth

11

Innanzitutto, il CD richiede un grande adattamento mentale: bisogna ammettere che a volte le cose si rompono, qualunque cosa tu faccia. Alla fine della giornata, non puoi provare un aspetto negativo.

Una volta superato questo, ti rendi conto che hai bisogno di strumenti e procedure per a) rilevare questi errori molto rapidamente eb) ripristinare o distribuire l'aggiornamento in modo molto efficiente. Inoltre, se stai davvero bevendo il cocktail CD, stai davvero offrendo un sacco di piccoli cambiamenti puntati che sono facili da ripristinare e non dovrebbero essere in grado di introdurre importanti bug a livello di applicazione. Anche i ragazzi che praticano veramente i CD gestiscono i principali cambi in modo più tradizionale.


"piccoli ... cambiamenti ... non dovrebbero essere in grado di introdurre bug a livello di applicazione". Anche in un codice ben fatto, questo può succedere. Ad esempio, aggiungi un div che spinge un altro div fuori dalla vista in un particolare browser. Ad esempio, un valore null viene visualizzato in un caso angolare imprevisto, generando un'eccezione e impedendo il rendering della GUI. Sì, dovresti testare tutto il possibile, come faccio io, ma inevitabilmente, si verificano bug e piccoli bug possono interrompere l'intera app.
Joshua Fox,

Ma sono ancora facili da trovare e risolvere quale è il maggiore punto di enfasi.
Wyatt Barnett,

2

Ogni sistema presenta rischi e ogni rischio ha costi potenziali. Se il costo di qualche piccolo rischio, del tipo che può richiedere mesi o anni per essere trovato in test approfonditi e QA, è abbastanza alto (il software nel tuo pacemaker cardiaco), non spedisci senza un lungo periodo di test di un rilascio congelato. Se il costo del fallimento è abbastanza piccolo, forse spedisci continuamente con zero test (la pagina Facebook del tuo gatto).


Sì. Per la maggior parte delle applicazioni di produzione, il rischio è nel mezzo. E mi sembra che il rischio sia tale che non vorremmo implementare su ogni check-in, anche con test automatizzati. Sembra che sia sempre necessario un round di QA. Ma le versioni più o meno settimanali mi sembrano fattibili.
Joshua Fox,

1

La copertura completa del test è impossibile. Devi dedicare molto tempo - e il tempo è denaro - per ogni piccola cosa. Questo è prezioso, ma il tempo potrebbe essere speso per contribuire alla qualità in altri modi.

Non hai bisogno di una copertura del 100%, hai bisogno di essere abbastanza fiducioso nel tuo sistema, che le modifiche a un posto non spezzeranno le cose che hai precedentemente dimostrato di funzionare.

Alcune cose sono difficili da testare automaticamente. Ad esempio la GUI. Anche il selenio non
ti dirà se la tua GUI è traballante. L'accesso al database è difficile da testare senza dispositivi ingombranti e anche questo non copre strani casi angolari nella memoria dei dati.

L'accesso al database è comunque banale da scrivere. Non dovresti aver bisogno di molti test sul tuo livello dati in quanto sta solo ottenendo e impostando i dati. La cosa più importante è assicurarsi che quando fallisce, ripristina e registra il problema in modo da poterlo risolvere.

Allo stesso modo la sicurezza e molte altre cose. Solo il codice di livello aziendale è effettivamente testabile in unità. Anche nel livello aziendale, la maggior parte del codice non ha funzioni semplici i cui argomenti e valori di ritorno possono essere facilmente isolati a scopo di test.

Quindi molte delle tue funzioni / classi sono troppo grandi. Dovrebbero essere scritti per essere testabili.

Puoi dedicare molto tempo alla costruzione di oggetti finti, che potrebbero non corrispondere alle implementazioni reali.

L'I / O dell'oggetto finto dovrebbe corrispondere a quanto previsto, tuttavia. Ciò che accade al suo interno non è importante.

I test di integrazione / funzionali integrano i test unitari, ma richiedono molto tempo per essere eseguiti poiché di solito comportano la reinizializzazione dell'intero sistema su ciascun test. (Se non si reinizializza, l'ambiente di test è incoerente.)

Questi non dovrebbero essere eseguiti continuamente. Proprio come necessario.

Il refactoring o qualsiasi altra modifica interrompe molti test. Passi molto tempo a ripararli. Se si tratta di convalidare modifiche significative delle specifiche, va bene, ma spesso i test si interrompono a causa di dettagli di implementazione di basso livello senza significato, non cose che forniscono davvero informazioni importanti. Spesso la messa a punto è focalizzata sulla rielaborazione degli interni del test, non sul vero controllo della funzionalità che viene testata.

Quindi il tuo codice è troppo stretto e i tuoi test sono scritti male.

I rapporti sul campo relativi ai bug non possono essere facilmente abbinati alla precisa micro versione del codice.

Non sei sicuro di cosa stai arrivando qui? Se c'è un bug, scrivi un test per mostrare la sua esistenza, quindi correggilo.


"L'I / O dell'oggetto simulato dovrebbe corrispondere a quanto previsto". "La creazione di MO che implementano completamente una specifica di interfaccia richiede tempo. Peggio ancora, è necessario aggiornarli continuamente, in modo da scrivere effettivamente tutto il codice due volte (una volta per la produzione e una volta per MO).
Joshua Fox,

1

Funziona bene per noi, ma i nostri clienti sono principalmente interni. Build multipli eseguiti durante il giorno, build non funzionanti non sono tollerate, meccanismo di avvio Web utilizzato in modo che gli utenti ottengano la versione più recente ad ogni avvio. Una cosa è che il CD risolve molti problemi. Sì, hai sempre problemi di compatibilità, tuttavia, dal momento che stai implementando solo piccole modifiche ogni volta, le preoccupazioni sono davvero facili da gestire. Il livello di stress del CD è MOLTO inferiore rispetto a quando abbiamo fatto grandi aggiornamenti e abbiamo dovuto sperare che tutto fosse giusto, dato che ci sarebbe stato così tanto codice da rivedere in caso di rottura.


-4

Ad essere onesti, TUTTO il software è in continua consegna! La cosa più importante è uscire dalla porta! Fai in modo che i tuoi utenti lo utilizzino e dai la priorità alle richieste di funzionalità e alla risoluzione dei bug.

"Nave dei veri artisti"
- Steve Jobs.


l'alternativa al CD non è cicli di un anno. Sono iterazioni ogni settimana, due settimane o mese.
Joshua Fox,
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.