Come mantenere il tronco stabile quando i test richiedono molto tempo?

8

Abbiamo tre set di suite di test:

  • Una "piccola" suite, impiegando solo un paio d'ore per eseguire
  • Una suite "media" che richiede più ore, in genere viene eseguita ogni notte (ogni notte)
  • Una suite "grande" che richiede una settimana + per eseguire

Abbiamo anche una serie di suite di test più brevi, ma qui non mi sto concentrando su di esse.

L'attuale metodologia consiste nell'eseguire la piccola suite prima di ogni commit al trunk. Quindi, la suite media viene eseguita tutte le sere, e se al mattino si è scoperto che non è andata a buon fine, proviamo a isolare quale dei commit di ieri era da biasimare, rollback che commettono e riprovano i test. Un processo simile, solo a frequenze settimanali anziché notturne, viene eseguito per la suite di grandi dimensioni.

Sfortunatamente, la suite media fallisce abbastanza frequentemente. Ciò significa che il trunk è spesso instabile, il che è estremamente fastidioso quando si desidera apportare modifiche e testarle. È fastidioso perché quando esco dal bagagliaio, non posso sapere per certo che sia stabile, e se un test fallisce non posso sapere con certezza se è colpa mia o meno.

La mia domanda è, esiste una metodologia nota per gestire questo tipo di situazioni in un modo che lascerà il tronco sempre in ottima forma? ad es. "Effettua il commit in uno speciale ramo di precommit che aggiornerà periodicamente il trunk ogni volta che passa la notte".

E importa se si tratta di un sistema di controllo del codice centralizzato come SVN o uno distribuito come git?

Per come sono uno sviluppatore junior con una capacità limitata di cambiare le cose, sto solo cercando di capire se c'è un modo per gestire questo dolore che sto vivendo.

    
posta Oak 20.11.2012 - 09:40
fonte

7 risposte

1

L'unico modo per correggere la causa principale dell'instabilità è disaccoppiare il codice in modo che le modifiche siano più isolate, come suggerito da altre risposte.

Tuttavia, come singolo sviluppatore, se vuoi una build più stabile su cui tu possa lavorare personalmente, è relativamente facile da risolvere. Invece di lavorare fuori dalla punta, tiri solo l'ultima build che ha passato la suite di test durante la notte nel tuo albero di lavoro. Se riesci a creare rami di funzionalità per ogni modifica, esci dall'ultima build stabile.

Sì, il tuo albero sarà qualche giorno indietro, ma la maggior parte delle volte non importa. Fai il tuo lavoro contro la build stabile, così sai che i tuoi cambiamenti sono quelli che hanno rotto tutti i test, poi prima di fare il check-in, aggiornare al più tardi e fare la tua normale integrazione. Quindi, dopo aver effettuato il check-in, torna nuovamente all'ultima build stabile.

Devi ancora fare il lavoro di integrazione disordinato, ma ciò che mi piace di questo metodo è che isola il lavoro di integrazione in un momento più conveniente per me e mi fornisce una base di codice stabile per lo sviluppo quando non è conveniente. Ho un'idea molto migliore quando è il mio cambiamento che probabilmente ha rotto la build rispetto a quella di qualcun altro.

    
risposta data 20.11.2012 - 16:39
fonte
12

So che stai cercando di evitarlo, ma la vera intuizione qui è rendersi conto che qualcosa è seriamente sbagliato nella tua base di codice: devi eseguire una serie completa di test che richiede una settimana per essere sicuri che il tuo codice sia stabile!

Il modo più vantaggioso per risolvere questo problema è iniziare a separare il codice base e i test in sottounità (indipendenti).
Ci sono enormi vantaggi a questo:

  • I test per ciascuna di queste unità verranno eseguiti più velocemente (ce ne sono semplicemente di meno) e non si interromperanno se qualcosa va storto in una delle unità indipendenti o a valle.
  • Un test fallito verrà localizzato su una particolare unità che renderà molto più facile trovare la fonte del problema.
  • Puoi separare le posizioni VCS delle diverse unità in modo che il tuo ramo "stabile" possa essere una combinazione dell'ultima build collaudata con successo di ogni unità, in modo che un'unità o due rotte non destabilizzino il tuo " stabile "versione.

La gestione inaspettata della tua struttura VCS diventerà più complicata, ma a una settimana intera per il tuo test completo, penso che tu possa sopportare il dolore!

Consiglio comunque di utilizzare una strategia di filiali "stabile" e "di sviluppo" in qualche modo, ma ci sono molti modi per farlo e puoi scegliere quello che funziona meglio per la tua organizzazione (meta-repository con fixed revisioni che puntano a repository separati per ogni unità, un ramo stabile e un ramo dev, feature branch ....)

    
risposta data 20.11.2012 - 11:17
fonte
1

Per SVN, non so nulla del tipo "pre-commit". Penso che sia probabile produrre commit e rollback quando il test fallisce. Come dice doc-brown, l'unico modo per impegnarsi su un ramo temporaneo e unirlo con il tronco più tardi.

Usando uno distribuito come git o mercurial, penso che sarebbe possibile. Utilizzando un repository "testing" e un repository "stable". Spingi sul test, testalo ogni notte e, se tutto va a buon fine, passi da test a stabile. Altrimenti, si esegue il rollback della ripetizione del test. Sono un po 'insicuro su come sarebbe la cronologia delle versioni quando passerai da testing a stable, ma penso che sia possibile escludere il rookack di rollback quando lo fai. Un po 'di sperimentazione prima sarebbe la più sicura.

Un'alternativa sarebbe anche quella di testare il tronco locale di ogni persona ogni notte. Quindi, le persone con test passati possono inviarlo al server centrale al mattino.

    
risposta data 20.11.2012 - 10:55
fonte
1

IMHO questo non ha niente a che fare con il VCS che stai usando. L'utilizzo di un ramo "sotto test" può essere una soluzione, che può essere realizzata anche con VCS centralizzato o distribuito. Ma sinceramente, penso che la cosa migliore della tua situazione sia cercare di ottimizzare la suite di test media (sembra che contenga i test più importanti) in modo che funzioni molto più velocemente, quindi puoi usarla per pre-commit-to-trunk test, proprio come lo fai ora con la tua "piccola suite".

    
risposta data 20.11.2012 - 10:46
fonte
1

I test del mezzo fallito: è vero che la maggior parte delle volte falliscono gli stessi test?

Se c'è un errore ci sono sempre gli stessi test correlati che falliscono?

Se true: può essere che tu possa selezionare selettivamente alcuni test medi che spesso falliscono (un test per ogni classe di errore) ed eseguirli all'interno del piccolo insieme.

La maggior parte dei test di integrazione dei test utilizza un database reale? Se è così è possibile sostituirli con un unittest che ha un database fittizio?

    
risposta data 20.11.2012 - 13:21
fonte
1

Devi eseguire i test più velocemente, non c'è altro modo per quadrare questa cerchia.

Considera il problema: vuoi essere sicuro che quando effettui il check-out hai un codice funzionante. Certo, puoi ritardare i commit e fare branching fino a prima del rilascio, ma questo ritarderà solo l'inizio del problema fino all'integrazione. Come in poi, dovrai eseguire la suite di una settimana dopo ogni unione? La metodologia non è la soluzione, la soluzione è puramente tecnica.

Ecco cosa suggerisco:

1) Effettua i test quanto più atmomic possibile e massimizza il riutilizzo dell'ambiente

2) Ottieni una farm della suite di test per eseguirli. Se invece di 8 grandi moduli finisci con 50, puoi creare una serie di istanze spot Amazon EC2 ed eseguire l'intera suite in parallelo. Sono sicuro che questo costerà un po 'di soldi, ma risparmierà enormi quantità di tempo per gli sviluppatori.

    
risposta data 20.11.2012 - 17:09
fonte
0

L'elemento chiave che dai per scontato nella tua domanda è che tutti i commit devono superare i test. Mentre questa è una buona regola da seguire e sembra avere un senso, a volte non è pratico. Il tuo caso è un esempio (anche se MadKeithV fa un punto), e posso immaginare di mantenere un ramo VCS così incontaminato potrebbe essere difficile se non c'è una cooperazione sufficiente tra i devlopers.

In realtà ciò che vuoi è sapere in qualche modo quale commit passa o fallisce. Un "ramo di pre-commit" come suggerito potrebbe funzionare, ma potrebbe richiedere uno sforzo maggiore da parte degli sviluppatori quando eseguono commit, il che potrebbe essere difficile da vendere.

Un approccio simile che potrebbe essere più semplice è lasciare che il bagagliaio si rompa a loro piacimento e avere un ramo per i commit che non sono interrotti. Uno script automatizzato può passare attraverso i commit mentre vengono fatti al trunk, eseguire i test su di essi e aggiungerli al ramo se passano.

Oppure potresti essere assurdamente semplicistico e avere uno script che elenca i commit che passano in un file di testo (che può essere o meno la versione controllata).

O hanno un sistema batch che accetta richieste di branch / revisioni da testare (da qualsiasi punto dell'albero), le verifica e le impegna nel trunk (o in un altro ramo) se passano.

    
risposta data 20.11.2012 - 16:47
fonte