Sto studiando tecniche e strategie per ridimensionare il nostro numero crescente di test di integrazione sul nostro prodotto attuale, in modo che possano (umanamente) rimanere parte del nostro sviluppo e del processo di CI.
A circa 200+ test di integrazione stiamo già raggiungendo il segno 1 ora per completare una prova completa (su una macchina desktop dev), e questo sta influenzando negativamente la capacità di uno sviluppatore di tollerare l'esecuzione dell'intera suite come parte dei processi push di routine. Che sta influenzando la motivazione per essere disciplinati nel crearli bene. Test di integrazione eseguiamo solo scenari chiave dalla parte anteriore a quella posteriore e utilizziamo un ambiente che rispecchia la produzione, che viene creato da zero ogni test.
A causa del tempo necessario per l'esecuzione, sta creando un terribile ciclo di feedback e molti cicli sprecati in attesa che le macchine finiscano le prove, indipendentemente da quanto siano concentrate le prove. Non dimenticare l'impatto negativo più costoso su flusso e progresso, sanità mentale e sostenibilità.
Prevediamo di fare 10 volte più test di integrazione prima che questo prodotto inizi a rallentare (non ne ho idea, ma non sembra che stiamo ancora iniziando in termini di funzionalità). Dobbiamo aspettarci di riuscire a trovarci tra poche centinaia o un paio di migliaia di test di integrazione, credo a un certo punto.
Per essere chiari, cercare di evitare che ciò diventi una discussione sui test unitari e sui test di integrazione (che non dovrebbero mai essere scambiati). Stiamo eseguendo entrambi i test unitari con TDD E test di integrazione in questo prodotto. In effetti, eseguiamo test di integrazione ai vari livelli nell'architettura dei servizi di cui disponiamo, laddove ciò ha senso per noi, in quanto dobbiamo verificare dove introduciamo cambiamenti radicali quando cambiamo i modelli della nostra architettura nelle altre aree del sistema.
Un po 'del nostro stack tecnologico. Attualmente stiamo testando un ambiente di emulazione (CPU e memoria intensiva) per eseguire i nostri test da un capo all'altro. Che è composto da servizi Web REST di Azure per un backend noSql (ATS). Stiamo simulando il nostro ambiente di produzione eseguendo l'Emulatore desktop di Azure + IISExpress. Siamo limitati a un emulatore e un repository di backend locale per macchina di sviluppo.
Disponiamo anche di un elemento della configurazione basato su cloud, che esegue lo stesso test nello stesso ambiente emulato e le esecuzioni del test impiegano il doppio del tempo (2 ore +) nel cloud con il nostro attuale fornitore di elementi della configurazione. Abbiamo raggiunto i limiti dello SLA dei provider di servizi di cloud cloud in termini di prestazioni hardware e abbiamo superato la loro tolleranza sul tempo di esecuzione dei test. Per essere onesti con loro, le loro specifiche non sono male, ma la metà di una macchina desktop grintosa interna chiaramente.
Stiamo usando una strategia di test per ricostruire il nostro archivio dati per ogni gruppo logico di test e precaricare i dati dei test. Assicurando in modo completo l'integrità dei dati, ciò aggiunge un impatto del 5-15% su ogni test. Quindi pensiamo che ci sia poco da guadagnare per ottimizzare questa strategia di test a questo punto nello sviluppo del prodotto.
Il lungo e il breve è che: mentre potremmo ottimizzare il throughput di ogni test (anche se fino al 30% -50% ciascuno), non ridimensioneremo ancora efficacemente nel prossimo futuro con diverse centinaia di test. 1 ora ora è ancora molto al di là di umanamente tollerabile, abbiamo bisogno di un ordine di miglioramento di grandezza nel processo complessivo per renderlo sostenibile.
Quindi, sto studiando quali tecniche e strategie possiamo usare per ridurre drasticamente i tempi di test.
- Scrivere meno test non è un'opzione. Per favore, non discutiamo di quello in questo thread.
- L'uso di hardware più veloce è sicuramente un'opzione, sebbene molto costoso.
- Anche l'esecuzione di gruppi di test / scenari su hardware separato in parrallel è sicuramente un'opzione preferita.
- La creazione di un raggruppamento di test attorno a funzionalità e scenari in fase di sviluppo è plausibile, ma alla fine non è affidabile nel dimostrare la piena copertura o la sicurezza che il sistema non è interessato da un cambiamento.
- L'esecuzione in un ambiente di gestione temporanea su scala cloud invece dell'esecuzione nell'emulatore desktop è tecnicamente possibile, anche se iniziamo ad aggiungere tempi di distribuzione alle prove (~ 20 minuti ciascuna all'inizio della corsa di prova per distribuire il materiale).
- Dividere i componenti del sistema in parti logiche indipendenti è plausibile in una certa misura, ma su questo ci aspettiamo un chilometraggio limitato, poiché le interruzioni tra i componenti dovrebbero aumentare con il tempo. (vale a dire che un cambiamento è in grado di influenzare gli altri in modi inaspettati - come spesso accade quando un sistema viene sviluppato in modo incrementale)
Volevo vedere quali strategie (e strumenti) altri stanno usando in questo spazio.
(Devo credere che altri possano vedere questo tipo di difficoltà usando determinati set tecnologici.))
[Aggiornamento: 16/12/2016: Alla fine abbiamo investito di più nei test paralleli CI, per una discussione del risultato: http://www.mindkin.co.nz/blog/2015/12/16/16-jobs]