Devo includere i test nell'immagine Docker?


19

Quando si tratta di test, posso pensare a due opzioni:

  1. Metti sia il test che l'applicazione in un'immagine.
  2. Includi solo il codice dell'applicazione nell'immagine. Crea un contenitore specifico per il test che si basa sull'immagine principale e aggiunge alcuni livelli (codice di test, dipendenze, ecc.).

Con la prima opzione, posso testare il container e spedirlo esattamente come testato. Un aspetto negativo evidente è il codice non necessario (e potenzialmente i dati dei test) saranno inclusi nell'immagine.

Con la seconda opzione, l'immagine che viene spedita non è esattamente la stessa di quella testata.

Entrambi sembrano strategie sbagliate. Esiste una terza strategia migliore?


1
Fondamentalmente hai risposto a te stesso. Entrambi sono una cattiva idea. Spedirai processi eseguibili già testati in un contenitore dimensionato e personalizzato in base alle esigenze. Non vuoi dipendenze dev né codice src. In produzione è considerato un rischio.
Laiv

1
Test prima della containerizzazione significa che l'ambiente non è testato, lo è solo il codice. Avrai testato solo una parte di ciò che stai spedendo, non tutto.
lk

Risposte:


10

Per l'esecuzione dei test in fase di build , il modo preferito sarebbe utilizzare una build in più fasi . I file Docker multi-stage ti consentono di avere uno stage più grande con tutte le dipendenze per la costruzione e il test, quindi copia gli artefatti esatti testati in un altro stage per un'immagine di runtime più piccola.

Volete anche test a livello di sistema di più contenitori, usando le loro interfacce esterne invece di essere eseguiti all'interno del contenitore. Poiché questi test comportano il coordinamento tra i servizi, richiedono dipendenze diverse come l'accesso alla tua orchestrazione, non sono accurati come i test di build-time e sono spesso scritti in lingue completamente diverse, non è un grosso problema eseguirli da un Docker separato contenitore dedicato solo ai test di sistema.


1
Quindi è praticamente l'opzione 2: eseguo i test in un ambiente / contenitore molto simile alla produzione, ma non è lo stesso. È giusto?
lk

9

C'è un terzo modo, come hai detto tu stesso. Penso che tu stia mescolando sviluppo, test e implementazione. Propongo di considerare l'intero SDLC nel suo insieme, in primo luogo, per capire cosa stai cercando di ottenere. Questo è un argomento importante, ma farò del mio meglio per riassumere.

TL; DR;

In breve, è necessario separare:

  • il tuo codice da
  • la configurazione dell'applicazione, da
  • la configurazione dell'ambiente di sistema.

Ognuno deve essere indipendente l'uno dall'altro e opportunamente:

  • versione controllata
  • testato
  • schierabili

Versione più lunga

Innanzitutto, hai un'applicazione composta da codice e (set separati di) configurazione. Questo deve essere testato, sia per la funzione build che per quella intenzionale - questo si chiama integrazione continua (CI). Esistono molti provider di questo servizio sia online che locale, ad esempio CircleCI per un provider cloud che si collega al tuo repository e crea e verifica ogni volta che commetti. Se il tuo repository è on-prem e non è possibile utilizzare un provider cloud, qualcosa del genere Jenkinssarebbe un equivalente. Se l'applicazione è abbastanza standard, probabilmente esiste un'immagine Docker esistente che può essere utilizzata dal servizio CI. Altrimenti dovrai crearne uno, o un cluster di tali, in cui è possibile distribuire il codice dell'applicazione e la configurazione. Configurato correttamente, avrai una vasta gamma di statistiche sulla qualità del codice dell'applicazione.

Successivamente, una volta che sei soddisfatto della funzionalità e della correttezza della tua applicazione, il codebase dovrebbe essere opportunamente taggato per una versione specifica. Questa build dovrebbe quindi essere distribuita in un ambiente di test. Si noti che il codice sarà lo stesso di quello testato nell'IC (di conseguenza, se lo si è fatto correttamente), ma la configurazione potrebbe essere diversa. Ancora una volta alcuni provider di elementi della configurazione possono offrire questo passaggio in modo da poter testare la distribuzione di un'applicazione in pacchetto e una configurazione discreta. Questa fase in genere includerà test funzionali dell'utente (per nuove funzionalità), nonché test automatizzati (per funzionalità note). Se il rilascio supera questa fase, si dispone di un candidato al rilascio per il test di integrazione. È possibile eseguire i test di automazione da un altro contenitore Docker,alcune metriche che affermano che lo sforzo di test è 1: 1 allo sforzo di codifica (anche se non sono sicuro su questo da solo).

Penultimo, il passo successivo è dove costruisci il tuo ambiente (di sistema) come se fosse produzione. Se stai usando Docker in produzione, è qui che penserai a rafforzamento della sicurezza, ottimizzazione della rete e del server, ecc. Le tue immagini Docker potrebbero essere basate su quelle che hai usato nello sviluppo (idealmente), ma potrebbero esserci cambiamenti per il ridimensionamento e la sicurezza , come ho detto. Ormai il test funzionale dell'applicazione dovrebbe essere completo, sei più interessato alla sicurezza e alle prestazioni. Come per i test funzionali, i test qui possono essere sviluppati, distribuiti ed eseguiti da altre immagini Docker. Questo passaggio era orribilmente costoso e raramente fatto per farlo, quindi era necessario un hardware dedicato sul posto che riproducesse la produzione. Oggi, questo è completamente praticabile in quanto puoi alzarti e abbattere l'intero ambiente di quasi tutte le scale su richiesta.

Infine, hai una versione che dovrebbe essere pronta per la produzione con solo una piccola serie di delta di configurazione rispetto a quella dei test di integrazione (indirizzi IP, URI del database, password ecc.). La tua base di codice è stata testata almeno in tre diversi ambienti in questo punto e la maggior parte della configurazione del sistema almeno una volta.


Ciò significa che il tuo CI non testerà affatto i tuoi Dockerfile? Ad esempio, se nel file Docker mancasse una dipendenza, i test continuerebbero comunque?
lk

1
Affatto. Prima prova il codice, quindi verifica la configurazione dell'app, quindi verifica il sistema. Quello che sto dicendo è che si tratta di attività discrete. La cosa grandiosa della containerizzazione è che il sogno di sviluppo in un ambiente che è lo stesso di prod è molto vicino. Ma l'indurimento renderebbe troppo difficile lo sviluppo.
avastmick,

0

Penso che tu stia mescolando diversi tipi di test. Fondamentalmente devi chiederti: qual è l'unità sotto test qui?

Lo scenario più comune quando lavori come sviluppatore è scrivere test di unità / integrazione per qualche pezzo di codice su cui stai lavorando, dove quel pezzo di codice è l'unità sottoposta a test. Questi test vengono eseguiti localmente e / o in CI.

Quando hai creato una nuova immagine docker, questa diventa una nuova unità che puoi testare. Quali tipi di cose vorresti testare per questa immagine? Qual è l'API che sta fornendo? Come lo testate?

Se si tratta di un'applicazione Web, è possibile avviare un contenitore basato sull'immagine ed eseguire alcune richieste HTTP e verificare che le risposte siano quelle previste. Il problema che penso tu stia riscontrando è che sei molto abituato al framework di test accoppiato al codice dell'applicazione. Va bene durante lo sviluppo, ma ora vuoi testare un'immagine docker e quindi hai bisogno di un nuovo tipo di framework di test che può farlo e non è legato al codice dell'applicazione.

Quindi penso che la terza opzione che stai cercando sia:

  • Esegui i test di unità / integrazione prima di creare un'immagine docker.
  • Crea un'immagine docker contenente solo l'applicazione che desideri distribuire.
  • Invece di aggiungere ulteriori livelli sopra l'immagine dell'applicazione, lo si verifica così com'è eseguendolo con alcuni parametri forniti e affermando i risultati previsti.

Quindi i passaggi CI / CD sarebbero:

Configura ambiente di sviluppo -> Esegui test su codice -> Crea immagine finale -> Esegui test su immagine -> Distribuisci 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.