Cloud Services

Cloudy nuvoloso II: Introduzione a Pester

Nel corso degli anni, ho scoperto che anche con uno script ben testato e indipendentemente dalla cura con cui scrivi il codice, ci possono essere alcuni casi limite che vengono dimenticati o che si verificano raramente. Questo è particolarmente vero se testi i tuoi script manualmente. Inoltre, anche se il tuo script di implementazione può essere stato eseguito in modo impeccabile, ha effettivamente soddisfatto i requisiti aziendali originali?

Se non conosci ancora Pester, questo articolo ti fornirà una panoramica su cos'è Pester, cosa puoi ottenere con esso e perché è una buona idea impararlo e implementarlo nel tuo ambiente. Se invece conosci già Pester, questo articolo ti fornirà una breve panoramica di come lo abbiamo implementato nel reparto Windows Operations & Engineering di Swisscom.

In questo articolo spiegherò innanzitutto i concetti di base di Pester e parlerò dei diversi casi d'uso di Pester. Nella seconda parte dell'articolo, spiegherò come utilizziamo Pester nel mio team (Windows Operations & Engineering) presso Swisscom. Mostrerò come usiamo Pester per testare un grande framework che utilizziamo e come Pester ci aiuta a misurare la conformità dei nostri server.

Che cos'è Pester?

Pester è un framework di unità di test per PowerShell. Ci permette di scrivere codice che automatizza il test dei nostri script. Controlla automaticamente se il nostro script funziona effettivamente come previsto (o meno). Si tratta di un'ottima funzione che gli sviluppatori utilizzano da anni e finalmente PowerShell ha il suo framework di unità di test: Pester.

La storia di Pester è molto interessante: Pester era un progetto open source della comunità che è stato forkato da Microsoft e distribuito con Windows 10. Si tratta di una cosa davvero importante, perché Microsoft non ha mai integrato ufficialmente progetti comunitari nel sistema operativo prima d'ora. E noi lo adoriamo! 🙂

Casi d'uso di Pester

Pester viene generalmente utilizzato per rispondere a due domande principali:

Come posso assicurarmi che il codice che ho scritto funzioni effettivamente come previsto?In genere si parla di "test delle unità". Il principio è semplice: vuoi assicurarti che il codice funzioni in tutti i casi. Che tutti i parametri siano stati testati. Che lo script venga terminato correttamente con un messaggio di errore specifico in caso di errore. Vuoi anche assicurarti che lo script restituisca i valori e i tipi che ti aspetti e che il 100% (o forse un po' meno) del tuo codice sia coperto dai test. In questo modo potrai garantire che il tuo script funzioni in produzione e non fallisca.

La seconda domanda sarebbe:

Come posso assicurarmi che ciò che ho configurato con il mio script faccia effettivamente ciò che intendiamo fare? Può sembrare un po' vago, ma potresti avere uno script che configura un server per applicare alcune impostazioni predefinite. Imposta chiavi di registro, regole del firewall, server WSUS, impostazioni di backup ecc... È una buona idea verificare se la comunicazione con i server esterni funziona, ad esempio se le regole del firewall implementate hanno effettivamente aperto le porte giuste e se la comunicazione tra il tuo server e la risorsa remota avviene effettivamente. L'apertura delle porte è un'azione che fornisce un servizio ai nostri clienti/clienti finali ed è opportuno assicurarsi che questo servizio funzioni effettivamente prima di consegnare il server al cliente.

Si tratta della cosiddetta "convalida operativa".

Nella prossima parte ti mostrerò come noi di Swisscom lo abbiamo implementato nelle nostre attività operative quotidiane.

Pester a Swisscom

Ora che abbiamo trattato alcuni dei concetti di base dei test di unità, vediamo come li abbiamo implementati nel nostro team, Windows Operations & Engineering di Swisscom.

Test di unità in Swisscom

Nel mio team attuale (Windows Operations & Engineering), tutti gli ingegneri utilizzano un framework di costruzione personalizzato per scrivere i nostri script. Questo ci aiuta a mantenere gli script coerenti all'interno del team e a garantire che lo scripter abbia la stessa esperienza con ogni script che scrive (comportamento di registrazione, file di configurazione, output, ecc.

Poiché diversi ingegneri si affidano al mio framework, è importante che ogni modifica che io o uno dei miei colleghi aggiungiamo al repository sia priva di errori. È qui che iniziamo a parlare della scrittura di test di unità con Pester.

Per testare il nostro framework, abbiamo circa 50 test che verificano diverse cose del framework. Cose come la creazione di un nuovo script, la sua esecuzione, la verifica della creazione dei file di log, la verifica che il file di log contenga il nostro output standard ecc...

L'output di un test Pester assomiglia alla schermata seguente.

Figura 1 Risultati del test di Pester

Il colore viola indica un'informazione, il verde significa che il test è stato superato e il rosso significa che non è stato superato.

Voglio sottolineare che un punto rosso (che indica che il test è fallito) in realtà non è una cosa negativa. Significa semplicemente che il test Pester ha trovato qualcosa che deve essere corretto nel tuo script e non un utente finale o, peggio ancora, un cliente che avrebbe scoperto per primo l'errore.

Puoi trovare una versione semplificata di uno dei test che ho scritto qui.

Il blocco describe aggiunge un livello informativo (la parte viola dell'output) e il test stesso viene sempre eseguito in un blocco it. Se il blocco it è controllato, l'output è verde. Altrimenti l'output è rosso. Il testo che viene aggiunto accanto al blocco "describe" o "it" è informativo e può essere qualsiasi cosa che ti aiuti a spiegare quale test stai chiamando e cosa fa.

Nell'estratto di codice qui sopra, controllo semplicemente se la variabile $testFolder contiene una sottocartella chiamata "logs". Inoltro la mia espressione alla parola chiave "should". Questa parola chiave valuta la condizione del test e restituisce un errore o conferma il mio test.

Anche se la sintassi di pester è facile da capire, questo non significa che non possa essere utilizzato per eseguire compiti complessi.

Nel prossimo estratto di codice, effettueremo alcuni altri controlli.

Assicura che il framework che utilizziamo per creare i nostri modelli di script generi effettivamente lo script nel formato che ci aspettiamo e che generi il messaggio appropriato nel file di log quando lo script viene richiamato. In questo caso particolare, sto verificando se ci sono due messaggi diversi. Se solo uno di essi è presente, il test globale fallisce.

Utilizzo i test di unità per verificare blocchi di codice o funzioni complete. In generale, cerco di procedere secondo il seguente schema: Un blocco "describe" per testare una funzione e un blocco "it" per ogni funzione di quella funzione che voglio testare.

Convalida operativa presso Swisscom

Con la convalida operativa, non stai scrivendo il codice di controllo per testare lo script che hai scritto, ma per verificare che le modifiche o le implementazioni che lo script apporta soddisfino effettivamente le esigenze aziendali originali. Quando crei una regola del firewall per aprire una porta specifica al solo scopo di accedere a un server web e leggere dati da un database, vuoi essere sicuro di poter effettivamente interagire con quel server web e recuperare i dati di cui hai bisogno. Se hai impostato correttamente la regola del firewall e hai aperto le porte corrette, ma c'è un altro firewall tra il tuo server client e il server web o il cavo di rete è semplicemente scollegato, non sarai in grado di fornire il servizio previsto anche se hai implementato correttamente la regola del firewall.

Noi di Windows Operations & Engineering utilizziamo la convalida operativa per garantire che i nostri server soddisfino i nostri standard (sicurezza, configurazione, ecc.). Questo ci permette di garantire che il server che forniamo sia conforme ai nostri standard. Gli stessi test vengono utilizzati in una fase successiva per garantire che non ci siano deviazioni nella configurazione.

I test consistono in una serie di script Pester che vengono utilizzati su uno o più server. Uno script esegue i test Pester e raccoglie i dati in un formato XML standard (NunitXML). Questo XML standard ci permette di automatizzare i risultati dei nostri test e di creare ottimi report!

Ho scritto una classe PowerShell che ci permette di creare un report individuale per ogni server o un report globale che può essere generato in diversi formati (docx, html ecc.).

Il report personalizzato si basa su un progetto open source chiamato "ReportUnit", di cui puoi vedere un esempio qui sotto.

Figura 2 Risultati dei test individuali

Se necessario, possiamo generare molto rapidamente un report su un determinato server e verificare immediatamente se tutto è come ci aspettiamo che sia. Ma anche se il report è davvero bello, non è quello che uso di più.

Il report che uso di più è quello globale. Ci permette di avere una panoramica di tutto il nostro ambiente in un colpo d'occhio. Il report è composto da 5/6 pagine per server. Ciò significa che può diventare molto ampio. Dato che può diventare così ampio, mostro solo le parti più interessanti di questi report.

Qui di seguito trovi un estratto di una delle prime pagine del rapporto. Contiene una tabella che elenca tutti i server che si trovano in una situazione di fallimento. (il che significa che almeno uno o più test sono falliti). Utilizzando la riga 'PercentageSuccess' (Percentuale di successo) possiamo vedere rapidamente la percentuale media di conformità per server che abbiamo.

Figura 3 Panoramica del test globale

Questo ci permette di vedere rapidamente dove qualcosa non è configurato correttamente. Ogni server contiene un rapporto dettagliato su ogni test. Contiene lo stato di successo del test, il tempo di esecuzione e una breve descrizione. (Come mostrato qui sotto).

Figura 4 Panoramica dettagliata del test

L'uso di colori vivaci rende immediatamente visibili i test falliti. Alla fine c'è una vista dettagliata dei test falliti con una breve descrizione, come si può vedere nella schermata qui sotto.

Figura 5 Vista dettagliata dei test falliti

Con questo metodo, possiamo controllare lo stato attuale dei nostri server e identificare un server che è stato mal configurato (o modificato) dopo la distribuzione. Se questo problema riguarda un gran numero di server, lo vedremo nel rapporto globale e potremo quindi distribuire una soluzione all'intero gruppo di server in modo tempestivo.

Vorrei sapere se avete implementato Pester nel vostro ambiente e, in caso affermativo, come lo utilizzate? Solo per i test di unità? O anche per la validazione operativa? Per favore, condividi le tue esperienze con noi!

Spero che ti sia piaciuto leggere questo articolo tanto quanto è piaciuto a me scriverlo e non vedo l'ora di leggere le tue implementazioni di Pest nella sezione commenti qui sotto.

Stéphane Van Gulick

Stéphane Van Gulick

DevOps Engineer III

Altri articoli getIT

Pronti per Swisscom

Trova il posto di lavoro o il percorso di carriera che fa per te. Dove dare il tuo contributo e crescere professionalmente.

Ciò che tu fai, è ciò che siamo.

Vai ai percorsi di carriera

Vai alle posizioni vacanti cibersicurezza