Strategia di ramificazione Git integrata con processo di test / QA


131

Il nostro team di sviluppo ha utilizzato la strategia di branching GitFlow ed è stato fantastico!

Recentemente abbiamo reclutato un paio di tester per migliorare la qualità del nostro software. L'idea è che ogni funzionalità dovrebbe essere testata / QA da un tester.

In passato, gli sviluppatori lavoravano sulle funzionalità in rami di funzionalità separati e li ricollegavano al developramo quando fatto. Lo sviluppatore testerà il suo lavoro da solo su quel featureramo. Ora con i tester, iniziamo a porre questa domanda

Su quale ramo il tester dovrebbe provare nuove funzionalità?

Ovviamente, ci sono due opzioni:

  • sul ramo della singola funzione
  • sul developramo

Test su Branch Branch

Inizialmente, credevamo che questo fosse il modo sicuro di procedere perché:

  • La funzionalità è stata testata con tutte le altre funzionalità unite al developramo dall'inizio dello sviluppo.
  • Eventuali conflitti possono essere rilevati prima che dopo
  • Semplifica il lavoro del tester, ha a che fare con un solo ramo ( develop) per volta. Non ha bisogno di chiedere allo sviluppatore quale ramo è per quale funzione (i rami funzione sono rami personali gestiti esclusivamente e liberamente da sviluppatori pertinenti)

I maggiori problemi con questo è:

  • Il developramo è inquinato da bug.

    Quando il tester rileva bug o conflitti, li segnala allo sviluppatore, che risolve il problema sul ramo di sviluppo (il ramo di funzionalità è stato abbandonato una volta unito) e in seguito potrebbero essere necessarie altre correzioni. Il commit o l'unione di sottosequenze multiple (se un ramo viene ricreato developnuovamente fuori dal ramo per correggere i bug) rende il rollback della funzionalità dal developramo molto difficile, se possibile. Esistono più funzionalità che si uniscono e vengono riparate sul developramo in momenti diversi. Questo crea un grosso problema quando vogliamo creare una versione con solo alcune delle funzionalità del developramo

Test sul ramo delle caratteristiche

Quindi abbiamo pensato di nuovo e abbiamo deciso di testare le funzionalità sui rami delle funzionalità. Prima di testare, uniamo le modifiche dal developramo al ramo della funzione (raggiungi il developramo). Questo è buono:

  • Si verifica ancora la funzionalità con altre funzionalità nel mainstream
  • L'ulteriore sviluppo (ad es. Correzione di bug, risoluzione dei conflitti) non inquinerà il developramo;
  • Puoi facilmente decidere di non rilasciare la funzione fino a quando non sarà completamente testata e approvata;

Tuttavia, ci sono alcuni svantaggi

  • Il tester deve fare l'unione del codice e, in caso di conflitto (molto probabilmente), deve chiedere aiuto allo sviluppatore. I nostri tester sono specializzati in test e non sono in grado di codificare.
  • una funzionalità potrebbe essere testata senza l'esistenza di un'altra nuova funzionalità. ad esempio, le funzioni A e B sono entrambe sottoposte a test contemporaneamente, le due funzioni non sono consapevoli l'una dell'altra perché nessuna delle due è stata unita alla developfiliale. Ciò significa che dovrai testare developnuovamente contro il ramo quando entrambe le funzionalità vengono unite al ramo di sviluppo comunque. E devi ricordarti di testarlo in futuro.
  • Se le funzioni A e B sono entrambe testate e approvate, ma quando viene identificato un conflitto, entrambi gli sviluppatori per entrambe le funzionalità ritengono che non sia colpa sua / lavoro perché il suo ramo di funzionalità ha superato il test. Vi è un ulteriore sovraccarico nella comunicazione e, a volte, chiunque risolva il conflitto è frustrato.

Sopra è la nostra storia. Con risorse limitate, vorrei evitare di provare tutto ovunque. Stiamo ancora cercando un modo migliore per far fronte a questo. Mi piacerebbe sapere come le altre squadre gestiscono questo tipo di situazioni.


5
Questa domanda sembra adattarsi meglio ai programmatori , poiché non si occupa di un problema di programmazione, ma piuttosto di un processo di sviluppo. Qualcuno può migrarlo?


2
Il nostro modello è esattamente lo stesso. Sono interessato a sapere come il tuo team addetto al QA segnala i problemi relativi ai rami delle caratteristiche in modo diverso da quelli sul campo o durante il processo UAT (se ne hai uno). Usiamo Atlassian JIRA e abbiamo un flusso di lavoro diverso per i due.
void.pointer

2
Decidere la stessa cosa adesso. Inoltre, poiché il nostro ambiente è un'applicazione java spring, sono necessari circa 20 minuti per compilare e distribuire l'ambiente di test. Felice qualcuno ha posto gli stessi dubbi che avevo.
digao_mb,

Il primo svantaggio non è inerente al processo di test sui rami delle caratteristiche. Strumenti come Github Enterprise e Bitbucket hanno la capacità di richiedere l'approvazione per le richieste pull e la persona responsabile del QA può approvare segnalando allo sviluppatore che sono liberi di unirsi allo sviluppo.
Derek Greer,

Risposte:


102

Il modo in cui lo facciamo è il seguente:

Testiamo sui rami delle funzionalità dopo aver unito gli ultimi codici di sviluppo delle filiali su di essi. Il motivo principale è che non vogliamo "inquinare" il codice del ramo di sviluppo prima che una funzione venga accettata. Nel caso in cui una funzionalità non fosse accettata dopo il test, vorremmo rilasciare altre funzionalità già unite allo sviluppo che sarebbe un inferno. Develop è un ramo da cui viene rilasciata una versione e quindi dovrebbe essere in uno stato rilasciabile. La versione lunga è che testiamo in molte fasi. Più analiticamente:

  1. Lo sviluppatore crea un ramo di funzionalità per ogni nuova funzionalità.
  2. Il ramo delle funzionalità viene (automaticamente) distribuito nel nostro ambiente TEST con ogni commit che lo sviluppatore deve testare.
  3. Quando lo sviluppatore ha terminato la distribuzione e la funzionalità è pronta per essere testata, unisce il ramo di sviluppo sul ramo di funzionalità e distribuisce il ramo di funzionalità che contiene tutte le ultime modifiche di sviluppo su TEST.
  4. Il tester esegue il test su TEST. Quando ha finito, "accetta" la storia e fonde il ramo delle funzionalità in sviluppo. Dato che lo sviluppatore aveva precedentemente unito il ramo di sviluppo sulla funzionalità, normalmente non ci aspettiamo troppi conflitti. Tuttavia, in tal caso lo sviluppatore può aiutarti. Questo è un passo difficile, penso che il modo migliore per evitarlo sia mantenere le funzionalità più piccole / specifiche possibili. Diverse funzionalità devono essere eventualmente unite, in un modo o nell'altro. Naturalmente la dimensione del team ha un ruolo nella complessità di questo passaggio.
  5. Il ramo di sviluppo è anche (automaticamente) distribuito su TEST. Abbiamo una politica secondo cui anche se le funzioni di build del ramo possono fallire, il ramo di sviluppo non dovrebbe mai fallire.
  6. Una volta che abbiamo raggiunto un blocco delle funzioni, creiamo una versione dallo sviluppo. Questo viene distribuito automaticamente su STAGING. I test end-to-end completi si svolgono lì prima della distribuzione della produzione. (ok forse esagero un po 'che non sono molto estesi ma penso che dovrebbero essere). Idealmente beta tester / colleghi, ovvero utenti reali dovrebbero testare lì.

Cosa ne pensi di questo approccio?


2
Come possiamo assicurarci che funzionalità1 e feature2 che sono state testate in modo indipendente siano anche utili per andare insieme (come menzionato nella domanda)?
Kumar Deepak,

2
facciamo indirettamente, fondendo l'uno e poi l'altro per lo sviluppo. È il passaggio 4 del processo precedente e ha a che fare con l'ordine cronologico. Quindi, se la funzione 2 è pronta per essere unita ma la funzione 1 è già stata unita, lo sviluppatore e il tester della funzione 2 devono assicurarsi che la loro unione funzionerà.
Aspasia,

1
Penso comunque che secondo questo modello di ramificazione git non dovresti unire due rami di caratteristiche tra loro.
Aspasia,

1
Abbiamo riscontrato problemi nel passaggio 6, in particolare nei periodi di crisi con lo spostamento di più funzionalità da sviluppare, a causa di fusioni non banali che si verificano dopo che il QA si è concluso sul ramo delle funzionalità, nonostante la fusione di devlop con funzionalità il più tardi possibile. Ho commentato un po 'più in dettaglio qui: stackoverflow.com/a/25247382/411282
Joshua Goldberg

8
Hai un ambiente TEST completo (DB, Server, Client, ecc.) Per ogni ramo di funzionalità? Oppure condividono l'ambiente e hanno solo nomi diversi (ad es. App-name_feature1- app-name_feature2, ecc.)
hinneLinks

41

Prima del test, uniamo le modifiche dal ramo di sviluppo al ramo di funzionalità

No. Non farlo, soprattutto se "we" è il tester di qualità. La fusione implicherebbe la risoluzione di potenziali conflitti, cosa che viene meglio eseguita dagli sviluppatori (loro conoscono il loro codice) e non dal tester del QA (che dovrebbe procedere al test il più rapidamente possibile).

Fai in modo che lo sviluppatore faccia un rebase del suo featureramo sopradevel e spingi quel featureramo (che è stato convalidato dallo sviluppatore come compilatore e lavorando sullo develstato del ramo più recente ).
Ciò consente di:

  • un'integrazione molto semplice sul ramo delle caratteristiche (banale unione di avanzamento rapido).
  • oppure, come raccomandato da Aspasia di seguito nei commenti , una richiesta pull (GitHub) o richiesta di unione (GitLab) : il maintainer fa una fusione tra il ramo PR / MR della funzione e develop, ma solo se non vengono rilevati conflitti vengono rilevati da GitHub / GitLab.

Ogni volta che il tester rileva un bug, lo segnalerà allo sviluppatore ed eliminerà il ramo di funzionalità corrente.
Lo sviluppatore può:

  • correggi il bug
  • rebase su un ramo di sviluppo recuperato di recente (di nuovo, per essere sicuro che il suo codice funzioni in integrazione con altre funzionalità validate)
  • spingere il featureramo.

Idea generale: assicurarsi che la parte di unione / integrazione sia eseguita dallo sviluppatore, lasciando i test al QA.


Stai dicendo "non usare unisci, usa invece rebase"? In tal caso, sono confuso, date le FAQ di Git sulla differenza tra i due: git.wiki.kernel.org/index.php/…
Vicki Laidler,

1
@VickiLaidler sì, se il ramo funzione è rifiutata da QA, lo sviluppatore deve rebase, non merge ( stackoverflow.com/a/804178/6309 )
VonC

1
@VonC Sono completamente d'accordo ma ci sono alcuni problemi: 1) L'eliminazione del ramo influisce su altri strumenti, come le richieste di estrazione di stash (l'eliminazione del ramo chiude il PR). Preferisci spingere la forza. 2) Se si tratta di un grande ramo di funzionalità in cui durante la sua vita hanno collaborato due persone, le fusioni sarebbero state preferite rispetto alla riformulazione. Reimpostarlo alla fine crea un incubo di conflitto poiché i commit di unione verranno rimossi e se il codice dipendesse da tali modifiche di unione, non è banale riparare
void.pointer

1
Guardando indietro alla mia risposta, farei anche un rebase e non una fusione per una storia più pulita.
Aspasia,

1
@Aspasia Aspetti positivi. Ho incluso richieste pull nella risposta per una maggiore visibilità.
VonC,

12

L'approccio migliore è l' integrazione continua , in cui l'idea generale è quella di unire i rami delle funzionalità nel ramo degli sviluppatori il più frequentemente possibile. Ciò riduce il sovraccarico dei dolori di fusione.

Affidati il ​​più possibile ai test automatici e fai partire automaticamente le build con i test unitari di Jenkins. Chiedi agli sviluppatori di fare tutto il lavoro per fondere le loro modifiche nel ramo principale e fornire unit test per tutto il loro codice.

I tester / QA possono partecipare alle revisioni del codice, spuntare i test unitari e scrivere test di integrazione automatizzati da aggiungere alla suite di regressione al completamento delle funzionalità.

Per maggiori informazioni consulta questo link .


Puoi ancora fare CI con branch + rebasing in Git.
void.pointer

9

Usiamo ciò che chiamiamo "oro", "argento" e "bronzo". Questo potrebbe essere chiamato prod, stadiazione e qa.

Sono venuto per chiamare questo il modello del melting pot. Funziona bene per noi perché abbiamo un enorme bisogno di controllo qualità nel settore aziendale poiché i requisiti possono essere difficili da comprendere rispetto ai tecnici.

Quando un bug o una funzione è pronta per il test, diventa "bronzo". Questo innesca una build jenkins che spinge il codice in un ambiente pre-costruito. I nostri tester (non super-tecnici a proposito) hanno appena raggiunto un link e non si preoccupano del controllo del codice sorgente. Questa build esegue anche test ecc. Siamo andati avanti e indietro su questa build spingendo effettivamente il codice nell'ambiente testing \ qa se i test (unità, integrazione, selenio) falliscono. Se esegui il test su un sistema separato (lo chiamiamo lead) puoi impedire che le modifiche vengano inviate al tuo ambiente qa.

La paura iniziale era che avremmo avuto molti conflitti tra queste caratteristiche. Succede se la caratteristica X sembra far sì che la caratteristica Y si stia rompendo, ma è abbastanza rara e effettivamente aiuta. Aiuta a ottenere un'ampia gamma di test al di fuori di quello che sembra essere il contesto del cambiamento. Molte volte per fortuna scoprirai come il tuo cambiamento influisce sullo sviluppo parallelo.

Quando una funzione supera il QA, la spostiamo in "argento" o in scena. Viene eseguita una build e vengono nuovamente eseguiti i test. Ogni settimana spingiamo questi cambiamenti nel nostro "oro" o albero dei prodotti e poi li distribuiamo al nostro sistema di produzione.

Gli sviluppatori iniziano i loro cambiamenti dall'albero d'oro. Tecnicamente potresti iniziare dalla messa in scena poiché quelli saliranno presto.

Le correzioni di emergenza vengono gettate direttamente nell'albero d'oro. Se un cambiamento è semplice e difficile da QA, può andare direttamente in argento, che troverà la sua strada per l'albero dei test.

Dopo il nostro rilascio, spingiamo le modifiche da gold (prod) a bronze (testing) solo per mantenere tutto sincronizzato.

Potrebbe essere necessario effettuare il rebase prima di inserire la cartella di gestione temporanea. Abbiamo scoperto che di tanto in tanto lo spurgo dell'albero di prova lo mantiene pulito. Ci sono momenti in cui le funzionalità vengono abbandonate nella struttura di test, specialmente se uno sviluppatore lascia.

Per le grandi funzionalità multi-sviluppatore creiamo un repository condiviso separato, ma lo uniamo all'albero di test lo stesso quando siamo tutti pronti. Le cose tendono a rimbalzare dal QA, quindi è importante mantenere isolati i changeset in modo da poter aggiungere e quindi unire / schiacciare nel tuo albero di stadiazione.

"Baking" è anche un piacevole effetto collaterale. Se hai qualche cambiamento fondamentale vuoi lasciarti sedere per un po ', c'è un bel posto per farlo.

Inoltre, tieni presente che non manteniamo versioni precedenti. La versione corrente è sempre l'unica versione. Anche così probabilmente potresti avere un albero di cottura master in cui i tuoi tester o la tua comunità possono battere per vedere come interagiscono le varie cose dei contributori.


1

Non farei affidamento solo sui test manuali. Automatizzerei i test di ogni ramo di funzionalità con Jenkins. Ho installato un laboratorio VMWare per eseguire i test Jenkins su Linux e Windows per tutti i browser. È davvero una straordinaria soluzione di test cross-browser e multipiattaforma. Collaudo funzionale / integrazione con Selenium Webdriver. I miei test al selenio vengono eseguiti con Rspec. E li ho scritti appositamente per essere caricati da jRuby su Windows. Eseguo test unitari tradizionali sotto test Rspec e Javascript sotto Jasmine. Ho installato test senza testa con Phantom JS.


1

Nella nostra azienda non possiamo usare lo sviluppo agile e abbiamo bisogno dell'approvazione per ogni cambiamento da parte delle imprese, questo causa molti problemi.

Il nostro approccio per lavorare con GIT è questo;

Abbiamo implementato "Git Flow" nella nostra azienda. Usiamo JIRA e solo i biglietti JIRA approvati dovrebbero essere messi in produzione. Per l'approvazione del Test, l'abbiamo esteso con un Test-Branch separato creato.

I passaggi per l'elaborazione dei biglietti JIRA sono:

  1. Crea un nuovo Branch da Develop-Branch
  2. Apporta le modifiche al codice sul Ramo delle funzioni
  3. Estrai da Funzione le modifiche al ramo Test / QA
  4. Dopo l'approvazione aziendale, sviluppiamo il passaggio dal ramo delle funzionalità
  5. Lo sviluppo procede frequentemente in una versione e infine infine nel ramo principale

La suddivisione di ogni richiesta in una propria funzione garantisce che solo le modifiche approvate siano andate in produzione.

Il processo completo è simile al seguente: inserisci qui la descrizione dell'immagine

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.