Quando un committente (stakeholder) ha una esigenza che vorrebbe fosse soddisfatta da un software deve, in genere, comunicare tale esigenza a qualcuno che lo sappia progettare e sviluppare.
Aldo: “Ci serve un software che faccia questo.”
Barbara: “Sì, a grandi linee mi sembra di aver intuito ciò di cui ha bisogno e penso che si possa fare. Per raccogliere ulteriori informazioni avrei bisogno di sapere con un po' più di dettaglio cosa intende con il termine «questo».”
Aldo: “Bhe, «questo» vuol dire che il software deve portare l'utente lì e là.”
Barbara: “Lì e là sempre?”
Aldo: “No no, deve portare lì quando l'utente si è registrato e poi clicca quiricchicchi, e solo quando l'utente ha nel carrello vari prodotti, e ha nel conto abbastanza lallarallà, deve portarlo là.”
Barbara: “Va bene, e relativamente ai lallarallà come fa il software a sapere quando ne abbiamo «abbastanza»?”
Aldo: …
Per ridurre la spiacevole situazione in cui il software sviluppato faccia cose diverse da quelle comunicate i team agili hanno imparato a procedere per piccoli incrementi, al termine di ognuno dei quali si chiede al committente: “È «questo» quello che volevi?”.
Ma che fare quando «questo» non è quello che voleva il committente? Le incomprensioni, si sa, accadono, ma si possono ridurre? Esiste un modo affinché ciò che è stato comunicato guidi ciò che sarà sviluppato?
Sviluppo guidato
Nel mondo Agile si sono affermate metodologie di sviluppo software come:
- Test Driven Development (TDD) (sviluppo guidato dai test)
- Behaviour Driven Development (sviluppo guidato dal comportamento)
Con TDD gli sviluppatori usano i test come guida per sviluppare il software. Esistono vari tipologie di test: test di unità, test di integrazione, testi di accettazione, test di carico, ecc… . Una particolare variante dei test di accettazione verifica se ciò che è stato sviluppato dal team sia accettabile per il committente.
BDD fonde TDD con Domain-Driven Design (DDD). Quest'ultimo è un approccio allo sviluppo software che fra i suoi obiettivi ha quello di voler creare una collaborazione fra il committente, che conosce la realtà (domain) che si desidera informatizzare, ed il team di sviluppo, che sa progettare (design) il software. Lo scopo di tale collaborazione è quella di definire un linguaggio condiviso (ubiquitous langauage) che dovrebbe consentire la comunicazione di concetti, anche complessi, riducendo le incomprensioni fra committente e team.
Cucumber
Cucumber svetta sopra altri strumenti simili perché è stato appositamente progettato affinché committenti e team di progettazione e sviluppo siano in grado di leggere e scrivere test di accettazione in modo semplice.
I test di accettazione sono scritti in Gherkin, un Domain Specific Language (DSL) leggibile dal committente (in inglese).
Un esempio di due test di accettazione, scritti da Aldo (committente) e Barbara (team), potrebbe essere:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Il file questo.feature
è un tipico esempio di documentazione che
da un lato descrive ciò che il committente vuole e,
dall'altro lato (che vedremo a breve), è collegato al
codice sorgente
sviluppato.
È importante sottolineare che tale documentazione non potrà mai diventare
obsoleta, nel senso che non potrà mai riferirsi a codice sorgente vecchio che
non esiste più, perché se fosse obsoleta allora l'esecuzione dei test di
accettazione obsoleti fallirebbe nel momento in cui si collega al codice
sorgente che esiste ora. In questo senso i .feature
file di Cucumber sono
considerati documentazione vivente.
Con il passare del tempo i test di accettazione si accumulano e sia il
committente che il team continuano a riferirsi a tutti questi .feature
file per leggerli, per ragionarci sopra, per comunicare, per modificarli o
crearne di nuovi: essi diventano di fatto l'unica sorgente di verità
su cosa faccia il software.
Come funziona Cucumber
Cucumber guida il committente ed il team a pensare al proprio software come ad
un insieme di funzionalità, ognuna delle quali è documentata in un .feature
file.
A questo punto si esce dal territorio comune al committente ed al team e ci si addentra in quello specifico del team di progettazione e sviluppo. Per comprendere il funzionamento di Cucumber ci servono alcune definizioni.
Ogni funzionalità è caratterizzata, in genere, da vari scenari ognuno
dei quali è diviso in passi: Dato
, Quando
, Allora
, ecc… Ogni
scenario, nello caso del linguaggio Java, è descritto da una classe
che ha tanti metodi quanti sono i passi che lo costituiscono:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Ogni passo é associato al relativo metodo tramite, per esempio, un'appropriata
annotazione java (il simbolo @
seguito dal nome del passo) che prende
come parametro di input una
espressione regolare
che “specchia” il testo scritto nel passo. La coppia (annotazione, metodo)
è chiamata definizione del passo:
1 2 3 4 5 6 7 8 |
|
Il corpo del metodo costituisce il codice di supporto che implementa, invocando il codice sorgente sviluppato, ciò che è descritto a parole nel passo:
1 2 3 4 5 6 7 8 9 10 11 |
|
Il funzionamento di Cucumber, in breve, può essere descritto come segue.
Cucumber comincia a leggere tutti i .feature
file.
Per ogni scenario comincia ad eseguire tutte le definizioni dei passi.
Per ogni definizione, se eseguita con successo, procede con l'esecuzione
della definizione del passo successivo.
Se arriva in fondo allo scenario, superando con successo tutti i suoi passi,
allora l'intero scenario è marcato con successo.
Se lo scenario fallisce Cucumber lo marca come fallito e procede con lo
scenario successivo.
Invia un commento
Un commento è inviato attraverso una normalissima e-mail. Il tuo indirizzo e-mail non sarà pubblicato o diffuso.
Questo blog è moderato, per cui alcuni commenti potrebbero non essere pubblicati. I commenti sono solitamente approvati dal moderatore in uno/tre giorni.