Automazione dei test del codice di un’applicazione Spring boot

Automazione dei test del codice di un’applicazione Spring boot

Nel lifecycle di sviluppo di un’applicazione, la fase di testing rappresenta un punto molto importante che può essere utilizzato sia per migliorare la struttura logica del codice, ad esempio delegando compiti specifici a funzioni diverse e rendendo così il codice più leggibile e modulare, sia per mettere alla prova la nostra applicazione e vedere come reagisce in base a input diversi, spingendoci dunque a riscrivere il nostro codice in modo che sia più sicuro.

In questo articolo vogliamo raccontare come abbiamo organizzato i processi di automazione dei test per un’applicazione Spring Boot, attraverso la CI di Gitlab e sfruttando i container Docker. L’applicazione, sviluppata in Java e gestita con il package manager Maven, prevede una struttura classica dell’organizzazione del codice, con il codice sorgente in src/main e i test in src/test.

Abbiamo deciso di utilizzare i plugin di maven Surefire e JaCoCo per la generazione rispettivamente dell’esito dei test e la fase di reporting. La configurazione dei due plugin nel file pom.xml di Maven è la seguente:

configurazione dei due plugin nel file pom.xml di Maven

mvn clean verify

Dopo aver lanciato i test tramite Maven, con il comando sopraccitato, possiamo verificare che i file generati dai plugin Surefire e JaCoCo si trovino rispettivamente nelle cartelle target/surefire-reports e target/site/jacoco. Inoltre, all’interno della cartella jacoco saranno presenti dei file html navigabili, che potremmo visualizzare via browser e indicheranno lo stato dei test.

A questo punto abbiamo istruito GitLab in modo che potesse automatizzare la fase di testing. Allo stesso livello del file pom.xml di Maven, abbiamo creato un file gitlab-ci.xml. Il file gitlab-ci contiene tre fasi di stage: il test, la build e il deploy.

Dato che la nostra applicazione si basa su Spring, e quindi sulla dependency Injection, avevamo necessità di testare l’applicazione in due modalità differenti: una iniettando un’implementazione MySQL delle repository che avevamo definito, e un’altra implementazione di tipo “Mock”, in cui i dati vengono semplicemente salvati nella memoria dell’applicazione.

A causa di questa “dualità” del codice abbiamo deciso di creare due file di configurazione.yml per Spring, cioè application-test-mock.yml e application-test-mysql.yml, che specificano rispettivamente la configurazione per il caricamento delle classi MySQL e le classi Mock.

È possibile lanciare i test delle classi in configurazione mock con il seguente comando:

mvn verify -Dspring.profile.active=test-mock

Per i test in modalità MySQL utilizzare invece il comando:

mvn verify -Dspring.profile.active=test-mysql

La parte di CI in GitLab è quindi strutturata in questo modo:

Nella fase di test, che abbiamo deciso di chiamare test-all, viene configurato un container con servizio MySQL, collegato all’immagine del container Maven in cui gireranno i test dell’applicazione. Nell’immagine Maven abbiamo inserito le istruzioni di update della repository e di installazione del client mysql, in modo da poter connetterci al servizio-container MySQL e definire lo schema del database attraverso lo script in tools/sql/create_db.sql.

Dopodiché vengono lanciati i test con i comandi maven descritti sopra. Dato che GitLab, alla versione 12.3.0, non supporta la gestione della coverage attraverso il plugin JaCoCo, abbiamo sfruttato le regex che GitLab mette a disposizione nei settings di progetto.

cat tagert/sites/jacoco/index.html

Con il comando sopraccitato, dopo aver lanciato i test, abbiamo fatto il print a schermo dei risultati rilevati da JaCoCo, che così vengono catturati dalla regex di coverage di GitLab.

Lo stato della coverage verrà poi visualizzato nella pipeline, e sarà disponibile all’indirizzo:

https://example.gitlab.com/<namespace>/<project>/badges/<branch>/coverage.svg