• Non ci sono risultati.

2.4 Testing

2.4.3 Testing app

L’applicazione pensata per i contribuenti `e composta da una miriade di componenti con comportamenti rudimentali. ´E difficile pensare che possano nascondersi bug significativi a quel livello e operare un test coverage massivo su tutte quelle unit`a richiederebbe uno sforzo considerevole per risultati di dubbio interesse.

Per questo motivo non abbiamo scritto procedure di unit testing per quanto riguarda il frontend utente.

Il rischio che si annida invece in un sistema composto da una moltitudine di sotto elementi sta proprio nell’integrazione di tutti questi.

Trattandosi inoltre di una SPA, ricordiamo che lo stato del sistema viene maturato come una progressione di transizioni elementari: potrebbe bastare una sola transi- zione non funzionante per rendere irraggiungibile un’intera porzione del grafo dell’applicazione.

Figura 2.30: Scenario di esempio che mostra come in una SPA un bug isolato possa avere risvolti molto penalizzanti sulla navigabilit`a del sistema.

Per questo motivo tutti i flussi critici dell’applicazione (iscrizione, apertura di una pratica, pagamenti eccetera) sono stati coperti da procedure di testing end-2-end. Per scrivere tests di questo tipo serve uno strumento che permetta di eseguire delle interazioni su un browser simulando il comportamento di un utente. Questo strumento esiste e si chiama Selenium. Affinch´e questo possa dialogare correttamente con i browser installati sul sistema occorre installare appositi moduli di interfacciamento. Fortunata- mente nell’ecosistema Node.js esiste il tool webdriver-manager per automatizzare queste procedure di setup.

1 # C o n f i g u r a l ’ a m b i e n t e in b a s e ai b r o w s e r d i s p o n i b i l i 2 w e b d r i v e r - m a n a g e r u p d a t e

3

4 # A v v i a il s e r v e r S e l e n i u m 5 w e b d r i v e r - m a n a g e r s t a r t

Listing 2.13: Setup ambiente di esecuzione tests End 2 End.

Una volta che Selenium `e in funzione possiamo cominciare ad inviare comandi ai browser. Tra i vari framework di testing disponibili abbiamo scelto Protractor perch´e `

e quello che meglio si integra con la tecnologia usata dalla nostra applicazione.

Una modifica nello scope di un’applicazione AngularJS si riflette sull’interfaccia gra- fica solo dopo che il framework ha compiuto il cosidd´etto ciclo di digest. Se implemen- tassimo dei test senza tenere conto di questo fatto correremmo il rischio di verificare l’aspettativa prima che la view dell’applicazione abbia avuto l’occasione di aggiornarsi. Questo porterebbe ad avere dei risultati falsati.

Fortunatamente Protractor adotta un protocollo di comunicazione con Selenium che implementa una gestione delle attese tra un comando e l’altro, rendendo questa opera- zione completamente trasparente agli occhi dell’autore della routine di test.

Il flusso di esecuzione di una procedura e2e `e il seguente:

ˆ Protractor viene avviato specificando a linea di comando qual’`e la suite da eseguire. ˆ Si connette con l’istanza in esecuzione del server Selenium e richiede l’apertura di

un browser.

ˆ Le varie direttive elencate nella suite vengono tradotte in comandi WebDriver ed impartiti a Selenium per remotare il browser. Tipicamente la prima direttiva `e quella per portare il browser sull’URL dell’applicazione.

ˆ Protractor riconosce che quanto in esecuzione `e basato su AngularJS ed inizia a sincronizzare i comandi in funzione del ciclo di digest dell’applicazione.

ˆ L’applicazione in esecuzione nel browser remotato reagisce ai comandi ricevuti come se si trovasse di fronte ad un utente e produce gli output previsti.

ˆ La suite di test deve essere programmata per avere delle aspettative e per verificarle cercando la presenza di certi elementi del DOM.

Ricordiamo che i test e2e emulano il comportamento di un utente, quindi l’unico modo per percepire che sia avvenuto un certo accadimento `e quello di vedere nella pagina qualcosa che faccia pensare che cos`ı sia stato.

ˆ A questo punto viene fatto un matching tra quanto atteso e quanto verificato, proponendo un report nella console dalla quale si ha lanciato il comando.

Developer

Test Suite

1

L’applicazione viene rilasciata in modo che

sia accessibile da browser

2

Il server Selenium viene avviato

3

Il tool protractor viene avviato

4

Il tool protractor impartisce gli ordini scriptati nella suite di

test tramite il protocollo WebDriverJS

5

Selenium avvia un browser ed inizia a remotarlo come da comandi ricevuti

6

Il browser scarica l’app dal server ed inizia ad eseguirla

7

Il tool protractor produce un report sull’andamento dei tests

Come accennato nelle discussioni precedenti la stesura di procedure di test che emu- lano il comportamento di un utente `e una problematica non affatto banale e serve un’ingegneria su vari livelli.

ˆ Vista la necessit`a di interagire con il DOM dell’applicazione serve avere una visione di pi`u alto livello, altrimenti i tests sarebbero troppo accoppiati con il markup delle pagine e al loro minimo cambiamento sarebbero completamente da riscrivere. Abbiamo adottato il pattern Page Object

ˆ Diverse azioni elementari dell’utente si espletano attraverso numerose attivit`a di basso livello.

Ad esempio l’operazione effettua il login si traduce in: – Naviga fino alla pagina di login.

– Porta il focus sul campo user name. – Digita l’username.

– Porta il focus sul campo password. – Digita la password.

– Scorri la pagina fino a far comparire nello schermo il bottone di login. – Clicca sul bottone login.

Queste operazioni basilari si ripetono centinaia di volte quindi serve un metodo per poterle riusare senza doverle riscrivere.

Abbiamo adottato il pattern Step Object.

ˆ I test devono essere parlanti in modo che leggendoli si possa dedurre la specifica. I framework Protractor e Jasmine hanno delle direttive (describe, it, beforeEach) che se usate opportunamente permettono di raggiungere questo scopo.

La condotta da tenere nella stesura dei test `e a grandi linee questa:

– Usare frasi al verbo gerundio per il blocco describe (es. ’andando’, ’loggando’, ’cliccando’ eccetera).

– Implementare il codice che attua lo scenario descritto nell’handler beforeEach. – Usare frasi assertive al verbo presente per il blocco it (es ’accade questo e

quello’).

– Implementare nel blocco it la verifica sull’aspettativa indicata nel titolo usan- do le API del framework Jasmine.

1 2 d e s c r i b e (" A n d a n d o a l l a p a g i n a di L o g i n ", f u n c t i o n() { 3 4 b e f o r e E a c h (f u n c t i o n() { 5 // Uso d e l l o S t e p O p j e c t 6 g u e s t U s e r . g o T o L o g i n P a g e () ; 7 }) ; 8 9 10 d e s c r i b e (" e t e n t a n d o un a c c e s s o con d a t i f a s u l l i ", f u n c t i o n() { 11 12 b e f o r e E a c h (f u n c t i o n() { 13 // Uso del P a g e O b j e c t 14 l o g i n P a g e . f i l l F o r m (" v e r r y F a k e U z e r ", " s 3 c r e t ") ; 15 }) ; 16 17 it (" il l o g i n v i e n e r e s p i n t o ", f u n c t i o n() { 18 19 // Uso d e l l ’ o g g e t t o ’ b r o w s e r ’ o f f e r t o da P r o t r a c t o r

20 // Uso d e l l e API expect - to di J a s m i n e

21 e x p e c t ( b r o w s e r . g e t C u r r e n t U r l () ) . t o B e (’ / a c c e s s D e n i e d ’) ; 22 }) ; 23 }) ; 24 25 26 d e s c r i b e (" ed i n s e r e n d o c r e d e n z i a l i v a l i d e ", f u n c t i o n() { 27 28 b e f o r e E a c h (f u n c t i o n() { 29 l o g i n P a g e . f i l l F o r m (" g o o d B o y ", " s a f e P a s s w o r d ") ; 30 }) ; 31 32 it (" il l o g i n a v v i e n e con s u c c e s s o ", f u n c t i o n() { 33 34 e x p e c t ( b r o w s e r . g e t C u r r e n t U r l () ) . t o B e (’ / w e l c o m e ’) ; 35

36 // Uso d e l l ’ a s t r a z i o n e sul DOM o p e r a t a a l i v e l l o del P a g e O b j e c t

37 // i n s i e m e ai m e t o d i di p r o t r a c t o r ( i s X X X ) 38 // ed a l l e a s p e t t a t i v e ( c o m e u s u a l e ) 39 e x p e c t ( w e l c o m e P a g e . s a l u t e M e s s a g e . i s D i s p l a y e d () ) . t o B e T r u t h y () ; 40 }) ; 41 }) ; 42 }) ;

La precedente spec contiene due affermazioni (i blocchi it) quindi produrr`a a video 2 messaggi. Tali aspettative saranno verificate dopo aver completato l’esecuzione della cascata di blocchi beforeEach.

Il pattern precedentemente descritto `e stato rispettato in quanto i blocchi it con- tengono solo affermazioni ed aspettative, mentre i blocchi beforeEach contengono solo azioni.

In alcuni testi che reputo di buona fattura (es. [11] e [8]) veniva usato uno stile verbale differente. A mio avviso questo che ho descritto `e il migliore perch´e permette veramente di avere dei dei test che han valore di specifica.

1 OK - " A n d a n d o a l l a p a g i n a di L o g i n e t e n t a n d o un a c c e s s o con d a t i

f a s u l l i il l o g i n v i e n e r e s p i n t o " 2

3 OK - " A n d a n d o a l l a p a g i n a di L o g i n ed i n s e r e n d o c r e d e n z i a l i v a l i d e il

l o g i n a v v i e n e con s u c c e s s o "