Behaviour VS Test-driven development

Se ti interessa approfondire il tema del Behaviour driven development, partecipa al nostro talk BDD: tutta questione di comunicazione  il 15 novembre alle ore 15:30 durante l’Italian Agile Day di Ancona!

Quando si inizia a studiare Behaviour-driven development, specialmente se si è lavorato per un po’ in Test-driven development, una delle prime cose che ci si domanda è sempre “va bene, ma in sostanza, che cambia? Di che si tratta?”. Non appena l’attenzione si sposta dagli strumenti al metodo e si cerca di risalire al nocciolo della questione, le cose in comune tra le due metodologie sono così tante che il dubbio viene e la sensazione di déjà vu cresce. A me per lo meno, è successo.

Dopo qualche tempo e alcuni progetti portati a termine provo a riflettere sulla questione e a dare il mio punto di vista sulla questione.

Partiamo dalla definizione di BDD su wikipedia:

behavior-driven development (abbreviato in BDD e traducibile in Sviluppo guidato dal comportamento) è una metodologia di sviluppo del software basata sul test-driven development (TDD)

Quel “basata sul test-driven development” ci dice che non siamo proprio fuori strada quando ci interroghiamo sulle differenze e le similitudini nei due approcci. D’altra parte la questione non è nuova e in passato il concetto che, tutto sommato, BDD == TDD è già stato espresso. In parte sono d’accordo con l’idea che BDD sia una forma migliorata di TDD, ma mi pare una semplificazione eccessiva: c’è di più sotto la superficie.

Il problema del test-driven development

È la parola test. Senza ombra di dubbio la parola test ci ha portato fuori strada. Siamo programmatori, siamo preoccupati che il nostro codice funzioni bene (non tanto per gli utenti, poveracci, ma per non essere interrotti da fastidiose segnalazioni di bug durante la prossima puntata di Games of Thrones) e ci siamo rifugiati dietro il “testo tutto così sono sicuro“. Se Kent Beck avesse usato un termine diverso, probabilmente, non sarei qui a scrivere questo post in questo momento.

In realtà nel libro “Test-driven development: by example” ci sono tantissimi riferimenti al fatto che il metodo serve a diminuire la paura, migliorare il design, facilitare il refactoring.

One of the ironies of TDD is that it isn’t a testing technique (the Cunningham Koan). It’s an analysis technique, a design technique, really a technique for all the activities of development.

Scrivere un test per un componente, prima di averlo implementato, significa decidere come quel componente si deve comportare, non certo verificare se funziona, proprio perchè non esiste ancora. Eppure le domande che si sentono più spesso da chi sta approcciando per la prima volta TDD sono del tipo:

  • Come faccio a testare questa particolare condizione?
  • Dovrei testare i metodi privati?
  • Dovrei avere una copertura del 100% con i test o basta il 90%

Sono caduto anche io in questo trannello, nei miei primi progetti in TDD non mi è capitato ma di domandarmi:

  • Questo test è chiaro da leggere?
  • Questo test specifica correttamente il comportamento del componente che testa?
  • Quando questo test fallirà, sarà un’utile indicazione di cosa è stato cambiato e come?

È tutta questione di comunicazione

Il merito principale di BDD, secondo me, è di non parlare più di test, ma di esempi. Se faccio un esempio è palese che non sto verificando se una cosa funziona, sto descrivendo come deve funzionare. Alla fine la sostanza non è molto differente, parliamo di un pezzo di codice in grado di dirmi ok se il mio codice fa quello che deve o ko se non lo fa, ma il cambio di atteggiamento mentale nei due differenti metodi, è fondamentale (d’altra parte le parole sono importanti). Si definisce cosa deve essere fatto, interrogandosi sul perché, prima di pensare al come.

La differenza tra BDD e TDD è tutta qui quindi? Se fosse così, probabilmente, non avremmo avuto bisogno di nuovi strumenti, sarebbe bastato appendere un cartello gigante in ufficio che ci ricordasse “devi descrivere, non testare” e avremmo risolto il problema. No, non penso che sia tutto qui, BDD si spinge oltre e ha un obiettivo completamente nuovo che non ho mai letto nel TDD: quello di allargare il numero di persone coinvolte.

Se sei un programmatore che lavora in un team di 1 programmatore, allora BDD e TDD per te sono esattamente la stessa cosa, puoi tranquillamente migliorare i tuoi test tenendo conto delle considerazione che ho fatto fino ad ora, ma non ti serve altro. Se invece ti capita di lavorare con altre persone, per dei clienti allora ho buone notizie per te.

Capire e farsi capire

Quello che BDD cerca di fare è fare in modo che i ragazzi del marketing, quelli che conoscono le regole del business, chi si occupa di frontend e/o di ux e gli sviluppatori riescano a capirsi, parlino la stessa lingua e possano essere allineati su quello che il software deve risolvere e come.

Descrivendo le funzionalità con un linguaggio naturale, tramite user stories, si crea una definizione comune del comportamento che si vuole ottenere con il software. Una sorta di glossario comune che può essere arricchito e utilizzato da tutti gli attori coinvolti, tanto nel codice quanto in tutte le discussioni di progetto. Trasformando questa definizione in codice eseguibile si ha un collegamento indissolubile tra le aspettative e il risultato finale, abbiamo ottenuto una documentazione viva e non solo una descrizione che può essere o non essere rispettata. Non è più possibile trovarsi nella situazione in cui “mi aspettavo che funzionasse diversamente” o “avrebbe dovuto funzionare così”. È questa, secondo me, la più grande e fondamentale differenza tra BDD e TDD.

In definitiva

Credo che considerare queste due tecniche simili sia corretto ma riduttivo. Il grande merito del Behaviour-driven development è quello di aver spostato l’attenzione dal concetto di “test” al concetto di “comportamento”. Migliorando la terminologia è stato messo a fuoco lo scopo vero dello scrivere i test: la progettazione e la comunicazione nel team.

Avere ben presente questo concetto è molto importante, perché significa anche che puoi iniziare a ragionare in termini di behaviour-driven development in qualsiasi progetto, da subito. Niente ti impedisce di farlo anche se nel tuo progetto stai utilizzando PHPUnit, proprio perché, alla fine, non è una questione di strumenti, ma di comunicazione.