Parte 1: Web / Android
Nota: questo articolo è una traduzione in russo dell'articolo originale Tuttavia, tutte le illustrazioni, i link, le citazioni e i termini sono mantenuti nella lingua originale, per evitare distorsioni del significato nella traduzione in russo. Vi auguro una buona lettura!

Attualmente, la professione DevOps è una delle più richieste nel settore IT. Se aprite i siti di ricerca lavoro più popolari e impostate un filtro per gli stipendi, vedrete che le offerte di lavoro legate a DevOps si trovano all'inizio della lista. Tuttavia, è importante capire che questo si riferisce principalmente alla posizione ‘Senior’, il che implica che il candidato possiede un alto livello di competenze, conoscenza di tecnologie e strumenti. Ciò comporta anche un alto grado di responsabilità, legato al funzionamento continuo della produzione. Tuttavia, abbiamo cominciato a dimenticare cosa sia DevOps. Inizialmente non era una persona o un dipartimento specifico. Se cerchiamo definizioni di questo termine, troveremo molti sostantivi belli e corretti, come metodologia, pratiche, filosofia culturale, gruppo di concetti e così via.
La mia specializzazione è ingegnere per l'automazione dei test (QA automation engineer), ma credo che non debba essere legata solo alla scrittura di test automatici o allo sviluppo di architetture di test framework. Nel 2020, le conoscenze sull'infrastruttura di automazione sono altrettanto necessarie. Questo permette di organizzare autonomamente il processo di automazione, dalla esecuzione dei test fino alla presentazione dei risultati a tutte le parti interessate in base agli obiettivi prefissati. Di conseguenza, le competenze DevOps sono un fattore obbligatorio per svolgere questo lavoro. E va bene, ma, sfortunatamente, c'è un problema (spoiler: questo articolo cerca di semplificare questo problema). Si tratta del fatto che DevOps è complicato. E ciò è ovvio, poiché le aziende non pagheranno molto per qualcosa di facile da realizzare... Nel mondo di DevOps ci sono molti strumenti, termini e pratiche da padroneggiare. Questo è particolarmente difficile all'inizio della carriera e dipende dall'esperienza tecnica accumulata.

Fonte:
Qui, probabilmente, concluderemo la parte introduttiva e ci concentreremo sull'obiettivo di questo articolo.
Di cosa parla questo articolo
In questo articolo condividerò la mia esperienza nella costruzione di un'infrastruttura di automazione dei test. Su Internet si possono trovare molte fonti di informazioni su vari strumenti e su come utilizzarli, ma vorrei esaminarli esclusivamente nel contesto dell'automazione. Credo che molti ingegneri di automazione conoscano la situazione in cui i test sviluppati, oltre a voi stessi, non vengono eseguiti e non si presta attenzione alla loro manutenzione. Di conseguenza, i test diventano obsoleti e si perde tempo per aggiornarli. Ancora una volta, all'inizio della carriera, questo può essere un compito piuttosto complesso: risolvere in modo appropriato quali strumenti dovrebbero aiutare a risolvere questo problema, come sceglierli, configurarli e mantenerli. Alcuni testatori si rivolgono all'aiuto di DevOps (persone) e, diciamocelo, questo approccio funziona. In molti casi, questa può essere l'unica opzione, poiché non abbiamo visibilità su tutte le dipendenze. Ma, come sappiamo, i DevOps sono ragazzi molto impegnati, dato che devono occuparsi dell'infrastruttura dell'intera azienda, del deployment, del monitoraggio, dei microservizi e di altre attività simili a seconda dell'organizzazione/team. Come spesso accade, l'automazione non è una priorità. In questo caso, dobbiamo cercare di fare tutto il possibile da parte nostra dall'inizio alla fine. Questo ridurrà le dipendenze, accelererà il flusso di lavoro, migliorerà le nostre competenze e ci permetterà di vedere un quadro più ampio di ciò che sta accadendo.
L'articolo presenta gli strumenti più richiesti e popolari e mostra come utilizzarli per costruire passo dopo passo un'infrastruttura di automazione. Ogni gruppo è rappresentato da strumenti che sono stati testati sulla base dell'esperienza personale. Ma questo non significa che dobbiate utilizzare gli stessi. Gli strumenti stessi non sono importanti, vengono e vanno. Il nostro compito ingegneristico è comprendere i principi di base: perché abbiamo bisogno di questo gruppo di strumenti e quali compiti lavorativi possiamo risolvere con il loro aiuto. Pertanto, alla fine di ogni sezione lascio link a strumenti simili che potrebbero essere utilizzati nella vostra organizzazione.
Cosa non c'è in questo articolo
Ribadisco che l'articolo non riguarda strumenti specifici, quindi non ci saranno snippet di codice dalla documentazione e descrizione di comandi specifici. Ma alla fine di ogni sezione lascerò collegamenti per uno studio dettagliato.
Questo è stato fatto per il motivo che:
- questo materiale è molto facile da trovare in varie fonti (documentazione, libri, corsi video);
- se iniziamo a approfondire, dovremo scrivere 10, 20, 30 parti di questo articolo (mentre nei piani ci sono 2-3);
- non voglio semplicemente sprecare il tuo tempo, perché, probabilmente, vuoi utilizzare altri strumenti per raggiungere gli stessi obiettivi.
Pratica
Mi piacerebbe molto che questo materiale fosse utile a ogni lettore, e non fosse solo letto e dimenticato. In ogni studio, la pratica è una componente molto importante. A tale fine, ho preparato. Avrai anche dei compiti da fare, per assicurarti di non aver copiato senza pensare delle righe di comandi da eseguire.
Piano
Passo
Tecnologia
Strumenti
1
Esecuzione locale (preparare test demo web/android e farli girare localmente)
Node.js, Selenium, Appium
2
Sistemi di controllo versione
Git
3
Containerizzazione
Docker, Selenium grid, Selenoid (Web, Android)
4
CI / CD
Gitlab CI
5
Piattaforme cloud
Google Cloud Platform
6
Orchestrazione
Kubernetes
7
Infrastruttura come codice (IaC)
Terraform, Ansible
Struttura di ogni sezione
Per mantenere la narrazione in modo visivo, ogni sezione è descritta secondo il seguente piano:
- una breve descrizione della tecnologia,
- il valore per l'infrastruttura di automazione,
- un'illustrazione dello stato attuale dell'infrastruttura,
- collegamenti per ulteriori studi,
- strumenti analoghi.
1. Esecuzione locale dei test
Breve descrizione della tecnologia
Questo è solo un passo preparatorio per l'esecuzione di test dimostrativi localmente e per verificare che vengano superati con successo. Nella parte pratica si utilizza Node.js, ma il linguaggio di programmazione e la piattaforma non sono importanti e si possono usare quelli utilizzati nella tua azienda.
Tuttavia, come strumenti di automazione, consiglio di utilizzare Selenium WebDriver per le piattaforme web e Appium per la piattaforma Android, poiché nei passi successivi utilizzeremo immagini Docker progettate specificamente per lavorare con questi strumenti. Inoltre, in base ai requisiti delle offerte di lavoro, questi strumenti sono i più richiesti sul mercato.
Come avrete notato, stiamo considerando solo i test web e Android. Sfortunatamente, IOS è una storia completamente diversa (grazie Apple). Intendo presentare soluzioni e pratiche relative a IOS nelle prossime parti.
Valore per l'infrastruttura di automazione
Dal punto di vista dell'infrastruttura, l'esecuzione locale non ha alcun valore. Si sta solo verificando che i test funzionino sulla macchina locale nei browser e nei simulatori locali. Ma in ogni caso è un punto di partenza necessario.
Illustrazione dello stato attuale dell'infrastruttura

Link per approfondire
Strumenti analoghi
- qualsiasi linguaggio di programmazione che preferite, in combinazione con i test Selenium/Appium;
- qualsiasi test;
- qualunque test runner.
2. Sistemi di controllo versione (Git)
Breve descrizione della tecnologia
Non sarà una grande rivelazione per nessuno se dico che un sistema di controllo versione è una parte estremamente importante dello sviluppo sia in team che individualmente. Basandosi su diverse fonti, si può dire con certezza che Git è il rappresentante più popolare. Il sistema di controllo versione offre numerosi vantaggi, come lo scambio di codice, l'archiviazione delle versioni, il ripristino a rami precedenti, il monitoraggio della cronologia del progetto, i backup. Non approfondiremo ogni punto nei dettagli, dal momento che sono sicuro che voi già lo conosciamo bene e lo utilizzate nel lavoro quotidiano. Tuttavia, se così non fosse, vi consiglio di sospendere la lettura di questo articolo e di colmare il vuoto il prima possibile.
Valore per l'infrastruttura di automazione
E qui potreste porre una domanda legittima: "Perché ci parla di Git? Tutti lo sanno e lo usano sia per lo sviluppo del codice che per il codice dei test automatici". Avreste assolutamente ragione, ma in questo articolo parliamo di infrastruttura e questa sezione funge da anteprima per la sezione 7: "Infrastruttura come codice (IaC)". Per noi questo significa che tutta l'infrastruttura, compresa quella di test, è descritta sotto forma di codice, quindi possiamo anche applicare a essa sistemi di versioning e ottenere vantaggi simili a quelli per il codice di sviluppo e automazione.
Esamineremo IaC più in dettaglio al passo 7, ma anche ora è possibile iniziare a utilizzare Git localmente creando un repository locale. Il quadro generale sarà ampliato quando aggiungeremo un repository remoto all'infrastruttura.
Illustrazione dello stato attuale dell'infrastruttura

Link per approfondire
Strumenti analoghi
3. Containerizzazione (Docker)
Breve descrizione della tecnologia
Per dimostrare come la containerizzazione abbia cambiato le regole del gioco, torniamo indietro di alcune decadi. In quei tempi, le persone acquistavano e utilizzavano macchine server per eseguire applicazioni. Ma nella maggior parte dei casi, le risorse necessarie per l'esecuzione non erano note in anticipo. Di conseguenza, le aziende spendevano soldi per acquistare costosi server potenti, ma parte di queste potenzialità non era completamente utilizzata.
Il passo successivo nell'evoluzione sono state le macchine virtuali (VM), che hanno risolto il problema della spesa per risorse inutilizzate. Questa tecnologia ha consentito di eseguire applicazioni in modo indipendente all'interno di un singolo server, assegnando uno spazio completamente isolato. Ma, sfortunatamente, ogni tecnologia ha i suoi svantaggi. L'esecuzione delle VM richiede un sistema operativo completo, che consuma CPU, RAM e spazio di archiviazione, e, a seconda del sistema operativo, è necessario considerare anche le spese per la licenza. Questi fattori influenzano la velocità di avvio e complicano la portabilità.
Ed ecco che siamo arrivati alla containerizzazione. Ancora una volta, questa tecnologia ha risolto il problema precedente, poiché i container non utilizzano un intero sistema operativo, il che consente di liberare un grande numero di risorse e fornisce una soluzione rapida e flessibile per la portabilità.
Certo, la tecnologia di containerizzazione non è qualcosa di nuovo ed è stata presentata per la prima volta alla fine degli anni '70. In quel periodo sono state condotte molte ricerche, sviluppi e tentativi. Ma è stato Docker a adattare questa tecnologia e renderla facilmente accessibile per le masse. Oggi, quando parliamo di container, nella maggior parte dei casi ci riferiamo a Docker. Quando parliamo di container Docker, intendiamo i container Linux. Possiamo utilizzare sistemi Windows e macOS per eseguire i container, ma è importante capire che in tal caso si crea un ulteriore strato. Ad esempio, Docker su Mac avvia silenziosamente i container all'interno di una leggera VM Linux. Torneremo su questo argomento quando discuteremo dell'esecuzione di emulatori Android all'interno di container, poiché qui emerge un aspetto molto importante che necessita di un'analisi più approfondita.
Valore per l'infrastruttura di automazione
Abbiamo scoperto che la containerizzazione e Docker sono fantastici. Diamo un'occhiata a questo nel contesto dell'automazione, poiché ogni strumento o tecnologia dovrebbe risolvere un problema. Identifichiamo i problemi evidenti dell'automazione dei test nel contesto dei test UI:
- un'enorme quantità di dipendenze nell'installazione di Selenium e soprattutto di Appium;
- problemi di compatibilità tra le versioni dei browser, degli emulatori e dei driver;
- mancanza di uno spazio isolato per browser/emulatori, il che è particolarmente critico per l'esecuzione parallela;
- è difficile gestire e mantenere se è necessario avviare 10, 50, 100 o addirittura 1000 browser contemporaneamente.
Ma poiché Selenium è lo strumento di automazione più popolare e Docker è lo strumento di containerizzazione più popolare, non deve sorprendere nessuno che qualcuno abbia tentato di combinarli per ottenere uno strumento potente in grado di risolvere i problemi sopra menzionati. Analizziamo queste soluzioni in modo più dettagliato.
Selenium grid in docker
Questo strumento è il più popolare al mondo per Selenium per avviare più browser su più macchine e gestirli da un nodo centrale. Per l'avvio è necessario registrare almeno 2 componenti: Hub e Node(s). L'Hub è il nodo centrale che riceve tutte le richieste dai test e le distribuisce ai rispettivi Nodes. Per ogni Node possiamo configurare specifiche impostazioni, ad esempio specificando il browser desiderato e la sua versione. Tuttavia, dobbiamo ancora occuparci dei driver compatibili per i browser e installarli sui Nodes appropriati. Per questa ragione, Selenium grid non è utilizzato in modo puro, tranne nei casi in cui dobbiamo lavorare con browser che non possono essere installati su Linux OS. In tutti gli altri casi, una soluzione molto più flessibile e appropriata è l'utilizzo di immagini Docker per avviare Selenium grid Hub e Nodes. Questo approccio semplifica notevolmente la gestione dei nodi, poiché possiamo scegliere l'immagine che ci serve con versioni compatibili di browser e driver già installati.
Nonostante le recensioni negative sulla stabilità del funzionamento, soprattutto quando si avviano molti Nodes in parallelo, Selenium grid rimane ancora lo strumento più popolare per l'esecuzione parallela dei test Selenium. È importante sottolineare che nell'open-source compaiono continuamente varie revisioni e modifiche a questo strumento, che affrontano diversi colli di bottiglia.
Selenoid per Web
Questo strumento rappresenta una svolta nel mondo di Selenium, poiché funziona immediatamente e ha reso la vita di molti ingegneri di automazione molto più semplice. Prima di tutto, non è un'ennesima modifica del Selenium grid. Invece, gli sviluppatori hanno creato una versione completamente nuova del Selenium Hub in linguaggio Golang, che, insieme a immagini Docker leggere per diversi browser, ha dato una spinta allo sviluppo dell'automazione dei test. Inoltre, nel caso di Selenium Grid, dobbiamo definire in anticipo tutti i browser richiesti e le loro versioni, il che non è un problema quando si lavora solo con un browser. Ma quando si tratta di più browser supportati, Selenoid è la soluzione numero uno, grazie alla funzione 'browser on demand'. Tutto ciò che ci serve fare è caricare in anticipo le immagini necessarie con i browser e aggiornare il file di configurazione con cui interagisce Selenoid. Dopo che Selenoid riceve una richiesta dai test, avvierà automaticamente il contenitore necessario con il browser richiesto. Quando il test è terminato, Selenoid rimuoverà il contenitore, liberando così risorse per le richieste successive. Questo approccio elimina completamente il noto problema della 'degradazione dei nodi', che spesso incontriamo nel Selenium grid.
Ma, purtroppo, Selenoid non è ancora una soluzione magica. Abbiamo ottenuto la funzione 'browser on demand', ma la funzione 'risorse on demand' non è ancora disponibile. Per utilizzare Selenoid, dobbiamo distribuirlo su hardware fisico o su VM, il che significa che dobbiamo sapere in anticipo quante risorse dedicare. Credo che questo non sia un problema per i progetti piccoli che fanno girare 10, 20 o anche 30 browser in parallelo. Ma cosa succede se abbiamo bisogno di 100, 500, 1000 e oltre? Non ha senso mantenere e pagare per un numero così elevato di risorse continuamente. Nelle sezioni 5 e 6 di questo articolo discuteremo le soluzioni che consentono di scalare, riducendo significativamente i costi per l'azienda.
Selenoid per Android
Dopo il successo di Selenoid come strumento per l'automazione web, le persone volevano avere qualcosa di simile per Android. E questo è avvenuto: Selenoid è stato rilasciato con supporto per Android. Da un punto di vista utente ad alto livello, il principio di funzionamento è simile all'automazione web. L'unica differenza è che invece di contenitori con i browser, Selenoid avvia contenitori con emulatori Android. A mio avviso, attualmente è lo strumento gratuito più potente per eseguire test Android in parallelo.
Non mi piacerebbe parlare degli aspetti negativi di questo strumento, poiché mi piace davvero molto. Tuttavia, ci sono alcuni svantaggi, simili a quelli dell'automazione web, relativi alla scalabilità. In aggiunta, è importante menzionare un ulteriore limite che potrebbe essere una sorpresa se si sta configurando lo strumento per la prima volta. Per eseguire le immagini Android, abbiamo bisogno di una macchina fisica o di una VM con supporto per la virtualizzazione annidata. Nella guida pratica mostrerò come attivarlo su una VM Linux. Tuttavia, se sei un utente di macOS e vuoi eseguire Selenoid localmente, sarà impossibile eseguire test Android. Ma puoi sempre avviare una VM Linux localmente con la 'virtualizzazione annidata' impostata e distribuire Selenoid al suo interno.
Illustrazione dello stato attuale dell'infrastruttura
Nel contesto di questo articolo, aggiungeremo 2 strumenti per illustrare l'infrastruttura. Si tratta di Selenium grid per i test web e Selenoid per i test Android. Nella guida su GitHub mostrerò anche come utilizzare Selenoid per eseguire test web.

Link per approfondire
Strumenti analoghi
- Esistono altri strumenti di containerizzazione, ma Docker è il più popolare. Se vuoi provare qualcos'altro, tieni presente che gli strumenti che abbiamo esaminato per l'esecuzione parallela dei test Selenium non funzioneranno immediatamente.
- Come già detto, ci sono molte modifiche a Selenium grid, ad esempio,.
4. CI / CD
Breve descrizione della tecnologia
La pratica dell'integrazione continua è piuttosto popolare nello sviluppo e si colloca al pari dei sistemi di controllo versione. Tuttavia, sento che c'è confusione nella terminologia. In questo paragrafo vorrei descrivere 3 modifiche di questa tecnologia secondo il mio punto di vista. Online troverete molti articoli con diverse interpretazioni ed è assolutamente normale se la vostra opinione differisce. La cosa più importante è che siate sulla stessa lunghezza d'onda dei vostri colleghi.
Quindi, ci sono 3 termini: CI — Continuous Integration (integrazione continua), CD — Continuous Delivery (consegna continua) e di nuovo CD — Continuous Deployment (distribuzione continua). (Da qui in poi utilizzerò questi termini in inglese). Ogni modifica aggiunge alcuni passaggi aggiuntivi al vostro flusso di lavoro di sviluppo. Ma la parola continuous (continua) è la più importante. In questo contesto intendiamo qualcosa che avviene dall'inizio alla fine, senza interruzioni o interventi manuali. Diamo un'occhiata a CI & CD e CD in questo contesto.
- L'integrazione continua – è il primo passo dell'evoluzione. Dopo aver inviato nuovo codice sul server, ci aspettiamo di ricevere un feedback rapido che le nostre modifiche sono a posto. Di solito la CI include l'esecuzione di strumenti di analisi statica del codice e test modulari/API interni. Ciò consente di ottenere informazioni sul nostro codice già pochi secondi/minuti dopo.
- Continuous Delivery è un passo più avanzato, in cui eseguiamo test di integrazione/UI. Tuttavia, in questa fase non riceviamo risultati così rapidamente come nel caso della CI. In primo luogo, questi tipi di test richiedono più tempo per essere completati. In secondo luogo, prima di avviarli dobbiamo distribuire le nostre modifiche in un ambiente di test/staging. Inoltre, se parliamo di sviluppo mobile, c'è una fase aggiuntiva per creare una build della nostra applicazione.
- Distribuzione continua presuppone che rilasciamo automaticamente (release) le nostre modifiche in produzione, se tutti i test di accettazione sono stati superati nelle fasi precedenti. Inoltre, dopo la fase di rilascio, è possibile impostare diverse fasi, come l'esecuzione di test smoke in produzione e la raccolta di metriche di interesse. Il Continuous Deployment è possibile solo con una buona copertura di test automatizzati. Se sono necessari interventi manuali, inclusi i test, allora non è più Continuo (continuo). Allora possiamo dire che il nostro pipeline si attiene solo alla pratica del Continuous Delivery.
Valore per l'infrastruttura di automazione
In questa sezione devo chiarire che, quando parliamo di test UI end-to-end, si intende che dobbiamo distribuire le nostre modifiche e i servizi correlati negli ambienti di test. Il Continuous Integration non è applicabile a questo compito e dobbiamo assicurarci di implementare almeno le pratiche di Continuous Delivery. Anche il Continuous Deployment ha senso nel contesto dei test UI, se intendiamo eseguirli in produzione.
E prima di guardare l'illustrazione della modifica dell'architettura, voglio dire qualche parola su GitLab CI. A differenza di altri strumenti CI/CD, GitLab fornisce un repository remoto e molte altre funzioni aggiuntive. Pertanto, GitLab è più di un semplice CI. Include out of the box la gestione del codice sorgente, la gestione Agile, pipeline CI/CD, strumenti di logging e raccolta di metriche. L'architettura di GitLab è composta da GitLab CI/CD e GitLab Runner. Ecco una breve descrizione dal sito ufficiale:
GitLab CI/CD è un'applicazione web con un'API che memorizza il proprio stato in un database, gestisce progetti/build e fornisce un'interfaccia utente. GitLab Runner è un'applicazione che elabora i build. Può essere distribuito separatamente e lavora con GitLab CI/CD tramite un'API. Per eseguire i test hai bisogno sia dell'istanza di GitLab che del Runner.
Illustrazione dello stato attuale dell'infrastruttura

Link per approfondire
Strumenti analoghi
- E molti altri
5. Piattaforme cloud
Breve descrizione della tecnologia
In questa sezione parleremo di una tendenza popolare chiamata ‘cloud pubblici’. Nonostante i grandi vantaggi offerti dalle tecnologie di virtualizzazione e containerizzazione sopra descritte, abbiamo ancora bisogno di risorse computazionali. Le aziende acquistano server costosi o affittano data center, ma in tal caso è necessario effettuare dei calcoli (a volte irrealistici) su quante risorse ci serviranno, se le utilizzeremo 24/7 e per quali scopi. Ad esempio, per la produzione è necessario un server funzionante 24 ore su 24, ma sono necessarie risorse simili per i test durante gli orari non lavorativi? Questo dipende anche dal tipo di test che si sta eseguendo. Un esempio possono essere i test di carico/stress che prevediamo di eseguire durante le ore non lavorative per avere risultati il giorno dopo. Tuttavia, è evidente che la disponibilità 24 ore su 24 dei server non è necessaria per i test automatici end-to-end e soprattutto per gli ambienti di test manuale. In queste situazioni, sarebbe utile poter ottenere quante più risorse necessarie on demand, utilizzarle e smettere di pagare quando non sono più necessarie. Inoltre, sarebbe fantastico poterle ottenere immediatamente, facendo qualche clic o eseguendo un paio di script. È a questo scopo che si utilizzano i cloud pubblici. Vediamo la definizione:
«Il cloud pubblico è definito come servizi di calcolo offerti da fornitori di terze parti su Internet pubblico, rendendoli disponibili a chiunque desideri utilizzarli o acquistarli. Possono essere gratuiti o venduti su richiesta, permettendo ai clienti di pagare solo per l'uso dei cicli CPU, dello storage o della larghezza di banda che consumano».
Si dice spesso che i cloud pubblici siano costosi. Ma la loro idea principale è la riduzione dei costi aziendali. Come accennato in precedenza, i cloud pubblici permettono di ottenere risorse on demand e pagare solo per il tempo di utilizzo. Inoltre, a volte dimentichiamo che i dipendenti ricevono uno stipendio e gli specialisti sono anch'essi una risorsa costosa. È necessario considerare che i cloud pubblici semplificano notevolmente la manutenzione dell'infrastruttura, permettendo agli ingegneri di concentrarsi su compiti più importanti.
Valore per l'infrastruttura di automazione
Quali risorse specifiche ci servono per i test UI end-to-end? Fondamentalmente, si tratta di macchine virtuali o cluster (parleremo di Kubernetes nella sezione successiva) per eseguire browser ed emulatori. Più browser ed emulatori vogliamo eseguire contemporaneamente, maggiore sarà la CPU e la memoria necessarie, e più soldi dovremo pagare. Pertanto, i cloud pubblici nel contesto dell'automazione dei test ci consentono di avviare un numero elevato (100, 200, 1000 ...) di browser/emulatori su richiesta, ricevere i risultati dei test il prima possibile e smettere di pagare per queste enormi risorse.
I fornitori di cloud più popolari sono Amazon Web Services (AWS), Microsoft Azure e Google Cloud Platform (GCP). La guida pratica fornisce esempi di utilizzo di GCP, ma in generale non importa cosa si utilizzi per le attività di automazione. Tutti offrono funzionalità simili. Di solito, nella scelta del fornitore, la guida si concentra su tutta l'infrastruttura aziendale e sui requisiti aziendali, il che è al di fuori dell'ambito di questo articolo. Per gli ingegneri dell'automazione, risulta più interessante confrontare l'uso di fornitori di cloud con l'uso di piattaforme cloud specificamente per obiettivi di test, come Sauce Labs, BrowserStack, BitBar e così via. Quindi facciamolo! A mio avviso, Sauce Labs è la conosciuta fattoria di testing nel cloud, ed è per questo che l'ho scelta per il confronto.
GCP contro Sauce Labs per scopi di automazione:
Immaginiamo di dover eseguire contemporaneamente 8 test web e 8 test Android. Per questo, utilizzeremo GCP e avvieremo 2 macchine virtuali con Selenoid. Nella prima solleveremo 8 contenitori con browser. Nella seconda – 8 contenitori con emulatori. Diamo un'occhiata ai prezzi:

Per avviare un contenitore con Chrome, abbiamo bisogno di n1-standard-1 macchina. Nel caso di Android, sarà n1-standard-4 per un emulatore. In realtà, un modo più flessibile ed economico è impostare valori utente specifici per CPU/Memoria, ma al momento, per il confronto con Sauce Labs, non è fondamentale.
Ecco le tariffe per l'uso di Sauce Labs:

Suppongo che tu abbia già notato la differenza, ma per sicurezza, riporterò una tabella con i calcoli per il nostro compito:
Risorse richieste
Mensile
Ore lavorative(8 a.m — 8 p.m)
Ore lavorative+ Preemptible
GCP per Web
n1-standard-1 x 8 = n1-standard-8
$194.18
23 giorni * 12h * 0.38 = 104.88$
23 giorni * 12h * 0.08 = 22.08$
Sauce Labs per il Web
Test paralleli in Cloud8 virtuale
$1.559
—
—
GCP per Android
n1-standard-4 x 8: n1-standard-16
$776.72
23 giorni * 12h * 1.52 = 419.52$
23 giorni * 12h * 0.32 = 88.32$
Sauce Labs per Android
Test paralleli in Real Device Cloud 8
$1.999
—
—
Come è evidente, la differenza di costo è enorme, soprattutto se si eseguono test solo nell'orario lavorativo di dodici ore. Ma è possibile ridurre ulteriormente i costi utilizzando macchine preemptible. Di cosa si tratta?
Una VM preemptible è un'istanza che puoi creare ed eseguire a un prezzo molto inferiore rispetto alle normali istanze. Tuttavia, Compute Engine potrebbe terminare (preempt) queste istanze se ha bisogno di accedere a quelle risorse per altri compiti. Le istanze preemptible sono capacità in eccesso di Compute Engine, quindi la loro disponibilità varia in base all'utilizzo.
Se le tue app sono tolleranti ai guasti e possono sopportare possibili preemption delle istanze, allora le istanze preemptible possono ridurre significativamente i tuoi costi di Compute Engine. Ad esempio, i lavori di elaborazione batch possono essere eseguiti su istanze preemptible. Se alcune di queste istanze terminano durante l'elaborazione, il lavoro rallenta ma non siferma completamente. Le istanze preemptible completano i tuoi compiti di elaborazione batch senza aggiungere ulteriore carico di lavoro sulle tue istanze esistenti e senza richiedere di pagare il prezzo intero per ulteriori normali istanze.
E questo non è ancora tutto! In realtà sono sicuro che nessuno esegue test per 12 ore di fila senza pausa. E se è così, puoi avviare e fermare automaticamente le macchine virtuali quando non sono necessarie. Il tempo reale di utilizzo può ridursi a 6 ore al giorno. Allora il pagamento nel contesto della nostra attività scenderebbe fino a 11$ al mese per 8 browser. Non è fantastico? Ma con le macchine preemptible dobbiamo essere cauti e pronti a interruzioni e funzionamento instabile, anche se queste situazioni possono essere previste e gestite programmaticamente. Ne vale la pena!
Ma in nessun modo dico 'non utilizzare mai fattorie di test nel cloud'. Hanno una serie di vantaggi. Prima di tutto, non è solo una macchina virtuale, ma una soluzione completa per l'automazione dei test con un set di funzionalità pronte all'uso: accesso remoto, log, screenshot, registrazione video, vari browser e dispositivi mobili fisici. In molte situazioni può essere un'alternativa lussuosa insostituibile. Le piattaforme di test sono particolarmente utili per l'automazione iOS, quando i cloud pubblici possono offrire solo sistemi Linux/Windows. Ma parleremo di iOS nei prossimi articoli. Raccomando di valutare sempre la situazione e basarsi sugli obiettivi: in alcuni casi è più economico ed efficiente utilizzare cloud pubblici, mentre in altri le piattaforme di test valgono sicuramente i soldi spesi.
Illustrazione dello stato attuale dell'infrastruttura

Link per approfondire
Strumenti analoghi:
6. Orchestrazione
Breve descrizione della tecnologia
Ho buone notizie – siamo quasi alla fine dell'articolo! Attualmente la nostra infrastruttura di automazione è composta da test web e Android, che eseguiamo tramite GitLab CI in parallelo, utilizzando strumenti con supporto per Docker: Selenium grid e Selenoid. Inoltre, utilizziamo macchine virtuali create tramite GCP per sollevare contenitori con browser ed emulatori. Per ridurre i costi, avviamo queste macchine virtuali su richiesta e le arrestiamo quando non stiamo eseguendo test. C'è qualcos'altro che può migliorare la nostra infrastruttura? La risposta è sì! Presentiamo Kubernetes (K8s)!
Iniziamo a esaminare come le parole orchestrazione, cluster e Kubernetes siano correlate. A un alto livello, l'orchestrazione è un sistema che distribuisce e gestisce le applicazioni. Per automatizzare i test, tali applicazioni containerizzabili sono Selenium grid e Selenoid. Docker e K8s si completano a vicenda. Il primo è utilizzato per distribuire applicazioni, il secondo per l'orchestrazione. A sua volta, K8s è un cluster. L'obiettivo del cluster è utilizzare le VM come nodi, permettendo di installare varie funzionalità, programmi e servizi all'interno di un unico server (cluster). Se uno dei nodi si guasta, altri nodi si occupano della situazione, garantendo il funzionamento ininterrotto della nostra applicazione. Inoltre, K8s offre funzionalità importanti relative alla scalabilità, permettendoci di ottenere automaticamente la quantità ottimale di risorse in base al carico e ai limiti stabiliti.
A dire il vero, installare manualmente Kubernetes da zero è un compito piuttosto complesso. Lascio un link a un noto tutorial pratico "Kubernetes The Hard Way", e, se vi interessa, potete provare a esercitarvi. Ma, per fortuna, esistono alternative e strumenti. Il più semplice tra questi è utilizzare Google Kubernetes Engine (GKE) in GCP, che consente di ottenere un cluster pronto dopo pochi clic. Per iniziare a studiare, consiglio di adottare questo approccio, in quanto permette di concentrarsi sull'apprendimento di come utilizzare K8s per le proprie esigenze, piuttosto che esplorare come i componenti interni debbano essere integrati tra loro.
Valore per l'infrastruttura di automazione
Consideriamo alcune delle funzioni significative offerte da K8s:
- distribuzione dell'applicazione: utilizzo di un cluster multi-nodi, anziché VMs;
- scalabilità dinamica: riduce i costi delle risorse utilizzate solo su richiesta;
- auto-guarigione (Self-healing): ripristino automatico dei pods (con il ripristino dei contenitori);
- rilascio di aggiornamenti e rollback senza interruzioni: l'aggiornamento di strumenti, browser ed emulatori non interrompe il lavoro degli utenti attuali.
Ma K8s non è ancora una soluzione universale. Per comprendere tutti i vantaggi e i limiti nel contesto degli strumenti che stiamo considerando (Selenium grid, Selenoid), discutiamo brevemente la struttura di K8s. Il cluster contiene due tipi di nodi: Master Nodes e Workers Nodes. I Master Nodes sono responsabili della gestione, distribuzione e decisioni di scheduling. I Worker Nodes sono dove le applicazioni vengono eseguite. I nodi contengono anche l'ambiente di esecuzione dei contenitori. Nel nostro caso, si tratta di Docker, che si occupa delle operazioni relative ai contenitori. Ma ci sono anche soluzioni alternative, come. È importante capire che la scalabilità o l'auto-guarigione non si riferiscono direttamente ai contenitori. Questo si realizza attraverso l'aggiunta/rimozione del numero di pods, che a loro volta contengono i contenitori (solitamente un contenitore per pod, ma a seconda del compito potrebbero essercene anche di più). La gerarchia ad alto livello consiste in worker nodes, all'interno dei quali si trovano i pods, all'interno dei quali vengono eseguiti i contenitori.
La funzione di scaling è fondamentale e può essere applicata sia ai nodes all'interno del cluster node-pool che ai pods all'interno del node. Esistono 2 tipi di scaling, che si riferiscono sia ai nodes che ai pods. Il primo tipo è lo scaling orizzontale, dove si aumenta il numero di nodes/pods. Questo tipo è il più preferibile. Il secondo tipo, di conseguenza, è quello verticale. Lo scaling avviene aumentando le dimensioni dei nodes/pods, non il loro numero.
Ora esaminiamo i nostri strumenti nel contesto dei termini citati sopra.
Selenium grid
Come accennato in precedenza, Selenium grid è uno strumento molto popolare, e non sorprende che sia stato containerizzato. Di conseguenza, non sorprende che Selenium grid possa essere distribuito in K8s. Un esempio di come farlo si può trovare nel repository ufficiale di K8s. Come al solito, allego i link alla fine della sezione. Inoltre, nella guida pratica viene mostrato come farlo usando Terraform. Ci sono anche istruzioni su come scalare il numero di pods che contengono contenitori con browser. Tuttavia, la funzionalità di scaling automatico nel contesto di K8s è ancora un compito non del tutto chiaro. Quando ho iniziato a studiare, non ho trovato alcuna guida pratica o raccomandazioni. Dopo diverse ricerche e esperimenti con il supporto del team DevOps, abbiamo scelto un approccio che prevede l'innalzamento di contenitori con i browser necessari all'interno di un solo pod, che si trova all'interno di un singolo worker node. Questo metodo ci consente di applicare una strategia di scaling orizzontale dei nodes aumentando il loro numero. Spero che in futuro la situazione cambi, e vedremo sempre più descrizioni delle migliori pratiche e soluzioni pronte, soprattutto dopo il rilascio di Selenium grid 4 con l'architettura interna modificata.
Selenoid:
Attualmente, il deployment di Selenoid in K8s è la più grande fonte di delusione. Non sono compatibili. Teoricamente possiamo sollevare un contenitore Selenoid all'interno di un pod, ma quando Selenoid inizierà a lanciare contenitori con browser, essi saranno ancora all'interno dello stesso pod. Questo rende impossibile il scaling e, di conseguenza, il funzionamento di Selenoid all'interno del cluster non differirà dal funzionamento all'interno di una macchina virtuale. Fine della storia.
Moon:
Sapendo di questo collo di bottiglia lavorando con Selenoid, gli sviluppatori hanno rilasciato uno strumento più potente, chiamato Moon. Questo strumento è stato originariamente concepito per lavorare con Kubernetes e, come risultato, si può e si deve utilizzare la funzione di autoscaling. Inoltre, direi che al momento è l'unica lo strumento in ambito Selenium, che ha nativamente il supporto per il cluster K8s (non c'è più, guarda il prossimo strumento ). La caratteristica principale di Moon, che fornisce questo supporto, è:
Completamente stateless. Selenoid memorizza in memoria le informazioni sulle sessioni del browser attualmente in esecuzione. Se per qualche motivo il suo processo si arresta, tutte le sessioni in esecuzione vengono perse. Moon, al contrario, non ha uno stato interno e può essere replicato tra i data center. Le sessioni del browser rimangono attive anche se uno o più replica si fermano.
Quindi, Moon è una fantastica soluzione, ma ha un problema: non è gratuito. Il prezzo dipende dal numero di sessioni. È possibile avviare gratuitamente solo da 0 a 4 sessioni, il che non è molto utile. Ma, a partire dalla quinta sessione, si dovrà pagare 5$ per ciascuna. La situazione può variare da azienda a azienda, ma nel nostro caso l'uso di Moon è senza senso. Come ho descritto sopra, possiamo avviare VM con Selenium Grid su richiesta o aumentare il numero di nodi nel cluster. Approssimativamente, per una pipeline avviamo 500 browser e fermiamo tutte le risorse dopo il completamento dei test. Se avessimo utilizzato Moon, avremmo dovuto pagare 500 x 5 = 2500 $ al mese, indipendentemente da quanto spesso avviamo i test. E ancora, non dico "non usate Moon". Per le vostre esigenze potrebbe essere una soluzione indispensabile, per esempio, se nella vostra organizzazione ci sono molti progetti/teams e avete bisogno di un enorme cluster condiviso per tutti. Come sempre, lascio un link alla fine e consiglio di fare tutti i calcoli necessari nel contesto del vostro compito.
Callisto: (Attenzione! Questo non è presente nell'articolo originale ed è contenuto solo nella traduzione russa)
Come ho detto, Selenium è uno strumento molto popolare e il settore IT si sta sviluppando rapidamente. Mentre lavoravo alla traduzione, è apparso in rete un nuovo strumento promettente, Callisto (saluti a Cypress e ad altri "killer" di Selenium). Funziona nativamente con K8s e permette di avviare i container Selenoid nei pods, distribuiti sui Nodes. Funziona immediatamente "out of the box", compresa l'auto-scalabilità. Fantastico, ma deve essere testato. Sono già riuscito a implementare questo strumento e a condurre diversi esperimenti. Ma è presto per trarre conclusioni; dopo aver ottenuto risultati a lungo termine, forse farò una recensione nei prossimi articoli. Per ora lascio solo i link per ricerche autonome.
Illustrazione dello stato attuale dell'infrastruttura
Link per approfondire

Link per approfondire
Strumenti analoghi
7. Infrastruttura come codice (IaC)
Breve descrizione della tecnologia
E siamo giunti all'ultimo capitolo. Di solito, questa tecnologia e i compiti ad essa correlati non rientrano nelle responsabilità degli ingegneri dell'automazione. E questo ha le sue ragioni. In primo luogo, in molte organizzazioni le questioni infrastrutturali sono sotto il controllo del dipartimento DevOps e il team di sviluppo non si preoccupa granché di ciò che fa funzionare il pipeline e in che modo mantenere tutto ciò che lo riguarda. In secondo luogo, diciamolo chiaramente, la pratica "Infrastruttura come codice (IaC)" non è ancora adottata in molte aziende. Ma è sicuramente diventata una tendenza popolare ed è importante cercare di essere coinvolti nei processi, approcci e strumenti correlati. O, almeno, essere al corrente degli eventi.
Iniziamo con la motivazione per l'utilizzo di questo approccio. Abbiamo già discusso che per avviare i test in GitlabCI avremo bisogno di almeno risorse per eseguire Gitlab Runner. E per avviare i contenitori con i browser/emulatori dobbiamo riservare una VM o un cluster. Oltre alle risorse per il testing, abbiamo bisogno di un numero significativo di risorse per supportare gli ambienti di sviluppo, staging, produzione, il che include anche database, pianificazioni automatiche, configurazioni di rete, load balancer, diritti degli utenti e così via. Il problema chiave riguarda gli sforzi richiesti per mantenere tutto ciò. Ci sono diversi modi in cui possiamo apportare modifiche e implementare aggiornamenti. Ad esempio, nel contesto di GCP possiamo usare la console UI nel browser e svolgere tutte le operazioni cliccando sui pulsanti. Un'alternativa potrebbe essere l'utilizzo delle chiamate API per interagire con le entità cloud o l'applicazione dell'utility da riga di comando gcloud per eseguire le necessarie manipolazioni. Tuttavia, con un numero davvero elevato di diverse entità ed elementi infrastrutturali, diventa difficile se non impossibile eseguire tutte le operazioni manualmente. Inoltre, tutte queste azioni manuali sono incontrollabili. Non possiamo inviarle in revisione prima dell'esecuzione, utilizzare un sistema di controllo versioni e ripristinare rapidamente le modifiche che hanno causato un incidente. Per affrontare tali problemi, gli ingegneri hanno creato e stanno creando script automatici in bash/shell, il che non è molto diverso dai metodi precedenti, poiché non sono così facili da leggere, comprendere, mantenere e modificare rapidamente in uno stile procedurale.
In questo articolo e guida pratica utilizzo 2 strumenti legati alla pratica dell'IaC. Questi sono Terraform e Ansible. Alcuni ritengono che non abbia senso usarli contemporaneamente, poiché le loro funzionalità sono simili e sono intercambiabili. Ma il punto è che inizialmente vengono posti obiettivi completamente diversi. E il fatto che questi strumenti debbano completarsi a vicenda è stato confermato durante una presentazione congiunta da sviluppatori che rappresentano le aziende HashiCorp e RedHat. La differenza concettuale sta nel fatto che Terraform è uno strumento di provisioning per la gestione dei server stessi. Mentre Ansible è uno strumento di gestione delle configurazioni, il cui compito è l'installazione, la configurazione e la gestione del software su questi server.
Un'altra caratteristica chiave distintiva di questi strumenti è lo stile di scrittura del codice. A differenza di bash e Ansible, Terraform utilizza uno stile dichiarativo, basato sulla descrizione dello stato finale desiderato da raggiungere come risultato dell'esecuzione. Ad esempio, se intendiamo creare 10 VM e applicare le modifiche tramite Terraform, otterremo 10 VM. Se applichiamo lo script di nuovo, non accadrà nulla, poiché abbiamo già 10 VM, e Terraform è a conoscenza di questo, poiché memorizza lo stato attuale dell'infrastruttura in un file di stato. D'altra parte, Ansible utilizza un approccio procedurale e, se gli chiediamo di creare 10 VM, al primo avvio otterremo 10 VM, analogamente a Terraform. Ma dopo un secondo avvio, avremo già 20 VM. Qui sta la differenza importante. Nello stile procedurale non memorizziamo lo stato attuale e descriviamo semplicemente la sequenza di passaggi che devono essere eseguiti. Naturalmente, possiamo gestire diverse situazioni, aggiungere controlli sull'esistenza delle risorse e lo stato attuale, ma non ha senso sprecare il nostro tempo e fare sforzi per controllare questa logica. Inoltre, ciò aumenta il rischio di commettere errori.
Riassumendo tutto quanto detto sopra, si può concludere che per il provisioning dei server lo strumento più adatto è Terraform e la notazione dichiarativa. Mentre il lavoro di gestione delle configurazioni è meglio delegarlo ad Ansible. Capito questo, vediamo alcuni esempi di utilizzo nel contesto dell'automazione.
Valore per l'infrastruttura di automazione
È importante capire che l'infrastruttura per l'automazione dei test deve essere considerata come parte dell'intera infrastruttura aziendale. Ciò significa che tutte le pratiche IaC devono essere applicate globalmente alle risorse dell'intera organizzazione. La responsabilità di questo dipende dai vostri processi. Il team DevOps ha più esperienza in queste questioni, vedendo l'intero quadro degli eventi. Tuttavia, gli ingegneri QA sono più coinvolti nel processo di costruzione dell'automazione e nella struttura del pipeline, il che consente loro di vedere meglio tutte le modifiche richieste e le opportunità di miglioramento. La soluzione migliore è lavorare insieme, scambiando conoscenze e idee per raggiungere il risultato atteso.
Ecco alcuni esempi di utilizzo di Terraform e Ansible nel contesto dell'automazione dei test e degli strumenti che abbiamo discusso finora:
1. Descrivere attraverso Terraform le caratteristiche e i parametri necessari delle VM e dei cluster.
2. Installare con Ansible gli strumenti necessari per i test: docker, Selenoid, Selenium Grid e caricare le versioni desiderate dei browser/emulatori.
3. Descrivere tramite Terraform le caratteristiche della VM in cui sarà eseguito GitLab Runner.
4. Installare con Ansible GitLab Runner e gli strumenti ausiliari necessari, impostare le configurazioni.
Illustrazione dello stato attuale dell'infrastruttura

Riferimenti per l'approfondimento:
Strumenti analoghi
Riassumiamo!
Passo
Tecnologia
Strumenti
Valore per l'infrastruttura di automazione
1
Esecuzione in locale
Node.js, Selenium, Appium
- Strumenti più popolari per web e mobile
- Supporto per molti linguaggi e piattaforme (incluso Node.js)
2
Sistemi di controllo versione
Git
- Analoghe Vantaggi con il codice di sviluppo
3
Containerizzazione
Docker, Selenium grid, Selenoid (Web, Android)
- Esecuzione parallela dei test
- Ambienti isolati
- Aggiornamento delle versioni semplice e flessibile
- Arresto dinamico delle risorse non utilizzate
- Facile da configurare
4
CI / CD
Gitlab CI
- I test fanno parte del pipeline
- Riscontro rapido
- Visibilità per l'intera azienda/team
5
Piattaforme cloud
Google Cloud Platform
- Risorse on demand (paghiamo solo quando necessario)
- Facile da gestire e aggiornare
- Visibilità e controllo su tutte le risorse
6
Orchestrazione
Kubernetes
Nel contesto di contenitori con browser/emulatori all'interno dei pod:
- Scalabilità / autoscalabilità
- Guarigione automatica
- Aggiornamenti e rollback senza interruzioni
7
Infrastruttura come codice (IaC)
Terraform, Ansible
- Analoghi Vantaggi con l'infrastruttura di sviluppo
- Tutti i vantaggi del versionamento del codice
- Modifiche e manutenzione semplici
- Completamente automatizzato
Mappa mentale diagrammi: evoluzione dell'infrastruttura
step1: Locale

step2: VCS

step3: Containerizzazione

step4: CI/CD

step5: Piattaforme Cloud

step6: Orchestrazione

step7: IaC

Cosa succede dopo?
Quindi, questo è la fine dell'articolo. Ma in conclusione, vorrei stabilire alcune intese con voi.
Da parte vostra
Come ho accennato all'inizio, vorrei che l'articolo portasse un beneficio pratico e vi aiutasse ad applicare le conoscenze acquisite nel lavoro reale. Rinnovo nuovamente.
Ma anche dopo questo, non fermatevi, praticate, studiate i link e i libri pertinenti, scoprite come funziona nella vostra azienda, trovate aree da migliorare e partecipate. Buona fortuna!
Da parte mia
Dal titolo si vede che questa era solo la prima parte. Nonostante sia venuta piuttosto lunga, ci sono ancora temi importanti da affrontare. Nella seconda parte intendo esaminare l'infrastruttura di automazione nel contesto di IOS. A causa delle limitazioni di Apple, relative all'esecuzione degli emulatori IOS solo sui sistemi macOS, il nostro insieme di soluzioni è ristretto. Ad esempio, non abbiamo la possibilità di utilizzare Docker per eseguire l'emulatore o cloud pubblici per avviare macchine virtuali. Ma questo non significa che non ci siano altre alternative. Cercherò di tenervi aggiornati sulle soluzioni avanzate e sugli strumenti moderni!
Inoltre, non ho menzionato temi piuttosto ampi legati al monitoraggio. Nella parte 3 intendo esaminare gli strumenti più popolari per il monitoraggio dell'infrastruttura, oltre a quali dati e metriche dovrebbero essere presi in considerazione.
E infine. In futuro, intendo pubblicare un corso video sulla costruzione di un'infrastruttura di test e sugli strumenti più popolari. Attualmente, su internet ci sono molti corsi e lezioni su DevOps, ma tutto il materiale è presentato nel contesto dello sviluppo, non dell'automazione dei test. In questo senso, ho davvero bisogno di feedback, se un corso del genere sarebbe interessante e prezioso per la comunità dei tester e degli automatizzatori. Grazie in anticipo!
Fonte: habr.com
