Testare angular

Eseguire test singoli tramite Karma ed Angular CLI quando i test rallentano lo sviluppo dei progetti più grandi

Le modifiche da applicare ad un progetto standard per avere più controllo sull’esecuzione dei test unitari tramite karma.

Per chi sviluppa frontend, le questioni relative al testing sono spesso “meno lineari” rispetto al classico approccio TDD dello sviluppo backend. Chi ha avuto occasione di lavorare in angular 2 avrà sicuramente potuto apprezzare angular CLI e gli strumenti che mette a disposizione, soprattutto per il testing.

Nello sviluppo quotidiano ho riscontrato che “ng test”, il comando che ci permette di eseguire test unitari tramite karma, non fornisce la possibilità di scegliere quali test eseguire, cosa che al crescere del numero dei test rallenta considerevolmente l’esecuzione, soprattutto in modalità “watch” rendendo così quasi impossibile un approccio TDD.

Infatti, ci capita spesso di lavorare su progetti frontend molto complessi per i nostri clienti e, nonostante questo tipo di problema, al contempo vogliamo mantenere alti i livelli qualitativi, anche con tecniche come appunto il TDD.

Per ovviare al problema ho perciò applicato le seguenti modifiche al mio progetto angular per avere la possibilità di lanciare e tenere in modalità watch solo i test che mi interessano durante lo sviluppo.

In questa maniera posso avere sott’occhio lo stato dei test relativi alla feature che sto sviluppando in piena modalità TDD senza dover aspettare il pacchetto completo ad ogni salvataggio o riga di codice aggiunta, mantenendo la retrocompatibilità posso lanciare in qualsiasi momento la suite completa di test.

L’idea di base è quella di passare un parametro aggiuntivo a karma e modificare il modo in cui questo “seleziona” i file .spec.ts da eseguire.

Repository di riferimento

Un esempio funzionante del progetto angular base su cui sono state apportate le modifiche di cui parleremo è reperibile presso: https://github.com/mzuccaroli/angular-cli-tests-example si tratta di un semplice progetto angular2 generato con angular CLI col comando “ng new”. Per maggiori informazioni vedere il quickstart di un progetto angular2.

Modifiche da eseguire

Step 1. minimist

Come primo passo è necessario installare minimist una libreria che ci da la possibilità di leggere delle opzioni e argomenti direttamente da bash:

$ npm install --save-dev minimist

Ora potremo chiamare angular cli con un parametro aggiuntivo, leggerlo tramite minimist e passarlo a test.ts: la parte di codice delegata a selezionare i file .spec.ts

Step 2. karma.conf

Modificare karma.conf.js aggiungendo all’inizio del file il codice che segue:

const argv = require('minimist')(process.argv.slice(2)),
components = (argv.components !== true) && argv.components;

nella parte relativa all’oggetto “config” aggiungiamo il campo ‘components’ appena letto rendendo disponibile a karma il parametro appena letto

client:{
components: components,
clearContext: false
},

Step 3. tests.ts

Modifichiamo ora  il file src/test.ts  sostituendo il frammento di codice:

// then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// and load the modules.
context.keys().map(context);

con il seguente:

// then we find all the tests.
const filterRegExp = (tags) ? new RegExp(tags, 'g') : /\.spec\.ts$/,
context = require.context('./', true, /\.spec\.ts$/),
specFiles = context.keys().filter(path => filterRegExp.test(path));
// and load the modules.
specFiles.map(context);

In poche parole se presente l’opzione “components” verrà usata per eseguire un filtro su tutta la lista di file .spec.ts, identificando un sottoinsieme della suite di test prima che questa venga eseguita.

Eseguire i test

A questo punto tutto è pronto per “chiedere” a karma di eseguire solo i test che ci interessano, basterà eseguire il comando:

$ ng test --components test3

per verificare che viene lanciato soltanto  il test “app.component.test3.spec.ts”

test singolo con Angular CLI

É utile sapere che di fatto viene eseguita un’espressione regolare sul titolo dei file “.spec.ts” quindi  il comando:

$ ng test --components header

eseguirà i test :

“header-menu.spec.ts”
“header-login-form.spec.ts”
“header-search.spec.ts”

cosa che è  estremamente utile sia ad eseguire sottoinsiemi specifici dei nostri test ma anche per aiutarci ad organizzare coerentemente l’albero dei componenti.

Da notare che angular cli restituirà un warning poichè non contempla il parametro aggiuntivo “components” nella versione 1.4 questo non ne pregiudica in nessuna maniera il funzionamento.

$ ng test --components test3
The option '--components' is not registered with the test command. Run `ng test --help` for a list of supported options.

Retrocompatibilità

Come verifica possiamo lanciare la suite di test nel modo canonico e constatare che tutti i test vengono eseguiti in maniera completamente retrocompatibile

$ ng test

test con Angular CLI

Eseguire i test tramite npm

Se siamo abituati a lanciare i test tramite npm sarà sufficiente modificare il file package.json

cambiando la riga:

"test": "ng test",

con:

"test": "ng test --components $tags",

a questo punto il comando:

$ npm test test3

sarà equivalente a

$ ng test --components test3

Altre versioni di angular cli

Il procedimento descritto è stato testato con le versioni 1.4 e 1.6 di Angular cli, è forse possibile che con versioni successive sia necessario qualche adattamento o angular CLI introduca nativamente la feature discussa.

Nel caso, ne parleremo in un nuovo articolo su questo blog, perciò continua a seguirci, ad esempio iscrivendoti qui sotto alla nostra newsletter.

0 commenti

Lascia un Commento

Vuoi partecipare alla discussione?
Fornisci il tuo contributo!

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *