La mischia e uno sviluppo stabile creano una contraddizione?

11

Faccio parte di un gruppo di sviluppo con 5 team, per un totale di circa 40 sviluppatori. Stiamo seguendo la metodologia Scrum, con sprint di 3 settimane. Abbiamo una configurazione di integrazione continua (Jenkins), con una pipeline di costruzione che richiede diverse ore (a causa di numerosi test automatizzati). Fondamentalmente, il processo di sviluppo funziona bene.

Tuttavia, osserviamo che dopo alcuni giorni in un nuovo sprint, la nostra build diventa spesso instabile e rimane traballante finché la fine dello "sprint" non finisce. L'effetto negativo di questo è che i passi di costruzione in fondo alla pipeline, in particolare UI / Webtest, sono non eseguiti per diversi giorni (perché attivati solo su una build "verde"). Di conseguenza, i bug introdotti di recente vengono rilevati solo molto tardi nello sprint.

  • Ogni commit viene verificato rispetto a un set di test di base. Una volta verificato, il cambiamento viene inviato al master dopo una revisione del codice (Gerrit)
  • Test di unità di base eseguiti ogni 30 minuti, durata inferiore a 10 minuti
  • Test di integrazione eseguiti ogni 2 ore, durata 1 ora
  • UI- / Webtest vengono eseguiti su test di integrazione riusciti, durata diverse ore

A seconda di chi è responsabile della stabilità della build durante lo sprint (tale responsabilità viene passata per sprint), potrebbero esserci "fermate di commit" intermedie e ad-hoc per riportare la build stabile.

Quindi, vogliamo:

  1. I nostri team di sviluppo per lo sviluppo e il commit delle modifiche durante lo sprint senza impedimenti
  2. Il nostro processo di build da abbandonare se un passo di costruzione fallisce, poiché i risultati di costruzione successivi hanno poco significato
  3. Il nostro processo di compilazione per fornire agli sviluppatori feedback di qualità in modo tempestivo

Dato (2), i punti (1) e (3) sembrano contraddirsi l'un l'altro. Qualcuno ha una buona pratica come affrontare questo?

( Al momento stiamo allentando il punto (2) e stiamo consentendo la continuazione della build anche in caso di mancati passaggi di costruzione. Non ho ancora ricevuto alcun feedback su come ciò influenza la nostra qualità )

Grazie, Simon

    
posta Simon 11.03.2017 - 08:46
fonte

6 risposte

7

Prima un paio di principi di base:  - Le modifiche principali dovrebbero sempre essere su un ramo di funzionalità nel tuo VCS  - I rami delle caratteristiche devono superare i test tutti prima di unirli nel trunk. Aggiunto  - I commit dovrebbero sempre build  - Una build distrutta richiede l'azione immediata dal committer e / o dal resto del team.  - Un test fallito deve solo interrompere i test rimanenti se si tratta di un test critico .

Se tu, come una squadra, segui queste pratiche e le imponi, ad es .: "nome e vergogna" quando la build è rotta, dovresti essere bravo a fare come qualsiasi commit che potrebbe distruggere la build su una caratteristica ramo. Altri commit che interrompono la build dovranno essere risolti immediatamente e quindi otterrete i risultati dei test downstream.

Puoi anche aggiungere un test automatico dell'ultima build "riuscita", (non necessariamente quella che supera i test di integrazione), per i test dell'interfaccia utente / Web come una corsa notturna che riporta la prima cosa in la mattina.

    
risposta data 11.03.2017 - 09:02
fonte
8

Non ha nulla a che fare con Scrum. La tua build dovrebbe essere costantemente stabile, a prescindere.

Nessuno dovrebbe controllare nulla a meno che non abbia eseguito una build locale ed eseguito i test unitari localmente (ed entrambi sono passati, ovviamente). Il tuo processo di compilazione e test locale dovrebbe essere sensibile alle modifiche e saltare i test per il codice che non è stato modificato.

Chiunque presenti qualcosa che fa fallire la build o che un test unitario fallisca dovrebbe essere pubblicamente vergognoso . Se la build è danneggiata, deve essere risolta immediatamente.

    
risposta data 11.03.2017 - 09:02
fonte
6

Il tuo problema sembra essere che i test impiegano troppo tempo per essere eseguiti. Fortunatamente, la legge di Moore ci ha fornito una soluzione a questo problema. Oggi, le CPU dei server di fascia alta possono facilmente avere più di 10 core (e oltre 10 HyperThreads). Potrebbero esserci più CPU in un singolo computer.

Se avessi test che richiedessero molto tempo, risolverei il problema con più hardware. Vorrei acquistare un server di fascia alta e quindi parallelizzare i test in modo che i test sfruttino pienamente tutti i core della CPU. Se i test sono oggi a thread singolo, l'utilizzo di 10 core e 10 HyperThred rende probabilmente i test eseguiti 15 volte più velocemente. Ovviamente, questo significa che usano anche 15 volte la memoria, quindi il computer deve avere abbastanza RAM.

Quindi, le diverse ore si trasformeranno in 10-30 minuti.

Non hai detto quanto tempo impiega la build, ma gli strumenti di build standard come make consentono di parallelizzare anche la build. Se parallelizzi i tuoi test unitari e il tipico computer sviluppatore ha 4 core e 4 HyperThreads, meno di 10 minuti di test unitari si trasformeranno in meno di 2 minuti. Quindi, forse potresti applicare una politica che tutti dovrebbero eseguire i test unitari prima di impegnarsi?

Informazioni sul fallimento del test durante l'arresto di ulteriori test: non farlo sul server di build! Volete quante più informazioni possibili sull'errore, e ulteriori test potrebbero rivelare qualcosa di importante. Naturalmente, se la build stessa fallisce, non è possibile eseguire i test unitari. Se lo sviluppatore esegue test unitari sul proprio computer, potrebbe essere necessario interrompere il primo tentativo.

Non vedo alcuna connessione tra Scrum e i tuoi problemi. I problemi potrebbero davvero verificarsi con qualsiasi processo di sviluppo.

    
risposta data 11.03.2017 - 09:51
fonte
2

Non è possibile avere più installazioni di Jenkins e fare in modo che gli sviluppatori controllino un'istanza di Jenkins separata?

Penserei che la soluzione migliore qui è che il codice passi tutti i test prima che venga controllato nel ramo principale e compilato / testato dall'istanza principale di Jenkins. Non permettere alle persone di verificare il codice che interrompe la compilazione.

Controllo il mio codice nel ramo di sviluppo, controlla se supera i test e crea una richiesta di pull. Ma potresti ovviamente avere Jenkins estrarre un ramo di funzionalità e testarlo.

    
risposta data 13.06.2017 - 00:05
fonte
1

Il punto (2) sembra essere il punto più doloroso, quindi mi concentrerò su quello.

Potrebbe essere il momento di rompere il progetto in più moduli.

link

A. High-level modules should not depend on low-level modules. Both should depend on abstractions.

B. Abstractions should not depend on details. Details should depend on abstractions.

Se un modulo non riesce a costruire, la build per gli altri moduli sarà in grado di continuare, purché gli altri moduli possano dipendere da un'interfaccia e il codice che compone tale interfaccia sia stato realizzato correttamente.

Questo ti darà un feedback su quali altri errori di compilazione potrebbero verificarsi, così avrai il tempo di correggere più di un modulo rotto prima che avvenga la prossima build.

In generale, i principi SOLID sono concepiti per gestire le librerie e creare problemi. In altre parole, questo insieme di principi è concepito per risolvere il tipo esatto di problemi che stai affrontando.

Come nota a margine (vedi la risposta di juhist), non è possibile eseguire la build più velocemente (mediante parallelizzazione) se non si partiziona la compilazione in moduli separati.

    
risposta data 11.03.2017 - 17:06
fonte
0

Penso che alla tua squadra manchi uno dei principi chiave della mischia: fatto, software funzionante. Un PBI non dovrebbe essere contrassegnato come fatto fino a quando non viene superata la Definizione di Fine stabilita dalla tua squadra. La definizione di Fatto è diversa per ogni squadra, ma probabilmente include cose come:

  • Il codice ha test unitari
  • Test di verifica delle unità come parte di una build automatizzata
  • Il codice è stato fuso in main (e i conflitti sono stati risolti)
  • ecc.

Quindi, in sostanza, quello che sta succedendo è che la tua squadra sta marcando cose fatte che in effetti non sono state fatte. Questo è un problema in sé stesso.

Oltre a ciò, si riduce alla corretta gestione del controllo della versione. Se si utilizza Git, tutto il lavoro viene eseguito nel repository locale dello sviluppatore e non si deve spingere nulla al telecomando a meno che non sia "fatto" e potenzialmente rilasciabile. Il lavoro incompleto non dovrebbe mai essere trasferito nel tuo repository principale. Se l'addetto deve lavorare su un ramo di funzionalità più duraturo e desidera eseguire il push su remoto per assicurarsi che non perda il lavoro, allora dovrebbe lavorare su un fork e quindi si unirà quella fork in main quando il la funzione è "fatta" e potenzialmente rilasciabile - non prima.

Per TFVC, è leggermente più complicato perché tutto avviene su "remoto". Ciò significa che gli sviluppatori dovrebbero quindi sempre lavorare fuori dalle filiali, a meno che non si tratti di una soluzione rapida. Le stesse regole si applicano qui come con Git, però: il software incompleto non viene commesso. Periodo. Nel controllo della versione correttamente gestito, "main" dovrebbe essere sempre rilasciabile. Se è stato effettuato un commit che borks "main", allora non lo stai facendo bene.

    
risposta data 06.06.2017 - 18:00
fonte

Leggi altre domande sui tag