Niente crea (o distrugge) l'agilità come l'impegno di un team per la continuous integration (CI). Questo concetto potrebbe sembrare minaccioso (specialmente se il tuo team deve ancora implementare la CI), ma ci sono buone notizie: indipendentemente dalle tecnologie utilizzate da un team, è probabile che ci sia un framework di continuous integration e di test automatizzati che si adatta alla sua base di codice.
Che cos'è la continuous integration?
La continuous integration è una best practice Agile e DevOps che consente di integrare con regolarità le modifiche al codice nel branch principale di un repository e testare le modifiche il prima e il più spesso possibile. Idealmente, gli sviluppatori integrano il codice ogni giorno, se non più volte al giorno.
Vantaggi della continuous integration
L'investimento in CI si traduce in feedback rapidi sulle modifiche al codice. Per "rapido" intendiamo pochi minuti. Un team che si affida principalmente ai test manuali può ricevere i feedback in un paio d'ore, ma in realtà, i feedback completi sui test arrivano un giorno o diversi giorni dopo che il codice viene modificato. E a quel punto sono già state apportate altre modifiche e la correzione dei bug diventa una spedizione archeologica con gli sviluppatori che scavano nei diversi livelli di codice per arrivare alla radice del problema.
Decisamente, questo processo non è veloce.
Proteggi la qualità con build continue e automazione dei test
Quanti di noi hanno scaricato il codice sorgente più recente e hanno riscontrato problemi di compilazione o un bug significativo? Proprio il contrario della produttività!
Per restare lontani da questa situazione, occorre seguire due pratiche:
Build continue: crea una build del progetto non appena viene apportata una modifica. Idealmente, la differenza tra ogni build è un singolo set di modifiche.
Automazione dei test: convalida programmatica del software per garantire la qualità. I test possono avviare azioni nel software dall'interfaccia utente (ne parleremo tra pochissimo) o dal livello dei servizi di back-end.
Pensa a queste due pratiche come al burro e la marmellata: hanno un buon sapore separatamente, ma sono fantastici insieme! La continuous integration accoppia le build continue con l'automazione dei test per garantire che in ogni build sia valutata anche la qualità della base di codice.
E ricorda: per realizzare appieno i vantaggi, un team deve anche avere la disciplina per mettere in pausa lo sviluppo e affrontare subito le interruzioni. L'energia che un team investe nella scrittura di test e nella configurazione dell'automazione (fai attenzione: si tratta proprio di un investimento) è inutile se le build vengono lasciate a languire nello stato di interruzione. Proteggere l'investimento in CI e proteggere la qualità della base di codice sono la stessa cosa.
Esecuzione dei test in CI: test unitari, dell'API e funzionali
Le esecuzioni di CI precedono due fasi principali. La prima fase garantisce che il codice venga compilato (oppure, nel caso dei linguaggi interpretati, mette semplicemente insieme tutti i pezzi). La seconda fase garantisce che il codice funzioni come previsto. Il modo più sicuro per procedere è utilizzare una serie di test automatizzati che convalidano tutti i livelli del prodotto.
Test unitari
I test unitari vengono eseguiti molto vicino ai componenti principali del codice. Sono la prima linea di difesa per garantire la qualità.
Vantaggi: sono facili da scrivere, è possibile eseguirli velocemente e modellano da vicino l'architettura della base di codice.
Svantaggi: i test unitari convalidano solo i componenti principali del software; non riflettono i flussi di lavoro degli utenti che spesso coinvolgono più componenti che lavorano insieme.
Poiché i test unitari spiegano come dovrebbe funzionare il codice, gli sviluppatori possono rivedere tali test per aggiornarsi su un'area di codice specifica.
Test dell'API
Un software valido è modulare, il che consente una più chiara separazione del lavoro tra diverse applicazioni. Le API sono gli endpoint in cui diversi moduli comunicano tra loro e i test dell'API li convalidano effettuando chiamate da un modulo all'altro.
Vantaggi: generalmente sono facili da scrivere, è possibile eseguirli velocemente e sono in grado di modellare con facilità il modo in cui le applicazioni interagiranno tra loro.
Svantaggi: in aree semplici del codice, i test dell'API possono copiare alcuni test unitari.
Poiché le API sono le interfacce tra le parti dell'applicazione, sono particolarmente utili durante la preparazione per un rilascio. Una volta che una build candidata al rilascio ha superato tutti i test dell'API, il team può rilasciarla ai clienti con molta più sicurezza.
Test funzionali
I test funzionali funzionano su aree più ampie della base di codice e modellano i flussi di lavoro degli utenti. Nelle applicazioni web, ad esempio, HTTPUnit e Selenium interagiscono direttamente con l'interfaccia utente per testare il prodotto.
Vantaggi: maggiori probabilità di trovare i bug perché imitano le azioni dell'utente e testano l'interoperabilità di più componenti.
Svantaggi: sono più lenti dei test unitari e talvolta riportano falsi negativi a causa della latenza di rete o di un'interruzione momentanea in qualche parte nello stack tecnologico.
I team spesso notano che man mano che si avvicinano al flusso di lavoro effettivo dell'utente, la velocità con cui vengono eseguiti i test automatizzati diminuisce. HTTPUnit è più veloce perché non è un browser web completo. Selenium può funzionare solo alla stessa velocità del browser web, ma ha il vantaggio di poter essere eseguito su più browser web in parallelo. Nonostante questi avvertimenti, i test funzionali sono estremamente preziosi e forniscono feedback molto più velocemente di quanto potrebbero mai fare i tester umani.
A proposito...
Alcuni tester considerano i test automatizzati come una minaccia esistenziale. Questo pensiero è miope e non potrebbe essere più lontano dalla verità. Liberati dalla fatica di attività di test ripetitive, i tester possono dedicare tempo all'analisi del rischio, alla pianificazione dei test e allo sviluppo di altre competenze, come imparare a programmare!
Velocizza la continuous integration
In Atlassian, ci impegniamo a mantenere gli sviluppatori impegnati in attività innovative e le nostre basi di codice sane. Poniamo grande enfasi sul rafforzamento del "ciclo di feedback interno" degli sviluppatori, ovvero il tempo necessario per creare modifiche e ottenere i risultati dei test.
A ciò si aggiunge l'esecuzione dei test automatizzati che consente di ridurre la durata della build. Una strategia consiste nel parallelizzare i test automatizzati su più server o "agenti della build", per fare in modo che il server di CI esegua effettivamente 2, 20 o anche 200 test in contemporanea. Con le tecnologie cloud, la CPU può facilmente adattarsi per soddisfare le esigenze del team di sviluppo di pari passo con la crescita delle suite di test. Ma la CPU non è illimitata. Testa ogni area del codice nel suo complesso, ma non in modo ridondante. I test ridondanti aumentano la durata della build (e sprecano CPU). Più velocemente gli ingegneri ricevono il via libera, più velocemente possono passare all'elemento successivo nel backlog.
Creazione di branch e CI: l'accoppiata perfetta!
Molti team evitano la creazione di branch a causa di merge complicati. Con le nuove tecnologie di controllo delle versioni come Git, sia la creazione di branch che il merge diventano operazioni facili. Per assicurarti che la riga di codice primaria ("main" nel gergo Git) rimanga integra, esegui lo stesso livello di continuous integration anche su tutti i branch di sviluppo e versione stabile. Quando la build passa su un branch, il team ha la sicurezza di eseguire il merge di tale codice a monte.
Con la creazione di branch, la continuous integration e l'automazione dei test, i team possono essere produttivi e innovativi e proteggere al contempo la qualità del codice. Se sei pronto per i passaggi successivi, dai un'occhiata alla nostra guida dettagliata per iniziare con la CI.
Questa è la descrizione migliore dello sviluppo Agile: fornire software funzionante regolarmente, con un debito tecnico minimo e senza compromettere l'ingegnosità.