Gioie e dolori del testing: corso accelerato per clienti

Per quanto l'argomento possa sembrare 'lontano' ed ostico, il testing è una questione sulla quale confrontarsi il prima possibile con chi si sta lavorando. A rischio c'è l'incolumità dell'intero prodotto!
Tempo di lettura: 6 minuti

Con questo post vogliamo inaugurare una serie dedicata ad uno degli aspetti più caratterizzanti del nostro lavoro quotidiano di sviluppo web, il testing.

Per esperienza personale, si tratta di un argomento che raramente raggiunge il tavolo di dicussione con il cliente. I motivi più frequenti sono due:

  1. i test semplicemente non vengono scritti, dunque non c’è nulla di cui discutere;
  2. quando vengono scritti, lo sono per iniziativa personale dello sviluppatore, dunque il concetto stesso di testing rimane totalmente “sommerso” ed invisibile agli occhi dello stakeholder.

Siamo convinti sia una scelta strategica sbagliata. Negli ultimi mesi abbiamo tentato una strada diversa, quella di elevare la pratica del testing ad argomento di vendita costante con i nostri clienti.

La ragione è semplice: i test portano valore tangibile e misurabile per il cliente; sono troppo importanti per essere relegati ai “piani inferiori”, per non essere sfruttati come vantaggio competitivo nei confronti di coloro che si ritrovano, volenti o nolenti, al punto 1 della lista precedente.

Certo, per poter spiegare bene il loro valore, è necessario prendersi del tempo con il cliente, ma la pratica ha dimostrato che è tutt'altro che impossibile e i successi sono concreti. D'altra parte, è sufficiente provare a mettersi nei panni di chi sta “dall'altra parte della barricata”: se, con poca esperienza diretta nel settore, dovessimo scegliere tra l'azienda X o Y, ci farebbe piacere trovare qualcuno che ci mettesse in guardia su un aspetto tanto importante, per noi ignoto fino a quel momento.

E quali sarebbero questi vantaggi?

In generale, la pratica del testing ha come obiettivo l'aumento della confidenza dello sviluppatore verso il codice prodotto. Per sviluppatore non intendo solo l'autore originario del codice, ma chiunque si trovi, da quel momento in poi, a doverci mettere le mani.

Questa confidenza si riflette a tutti i livelli nel ciclo produttivo del prodotto:

  • Meno sorprese: un software testato riserva ben poche sorprese al momento della pubblicazione in produzione. Le singole funzionalità sono già state verificate in profondità direttamente durante lo sviluppo, proprio grazie ai test;
  • Mantenibilità: un software è mantenibile nel tempo quando è possibile effettuare refactoring continui per migliorarne l’architettura interna, ma effettuare refactoring risulta impossibile o molto costoso senza un’ampia suite di test che scongiuri l’introduzione di regressioni sulle funzionalità già esistenti nel sistema;
  • Documentazione: se la classica documentazione testuale del codice rischia spesso di non riflettere più lo stato delle cose in quanto non aggiornata, una suite di test descrittiva fornisce la migliore documentazione _live _all’utilizzo di un componente software.

Miglior design con il TDD

Scrivere test prima dell'effettiva scrittura della funzionalità, è alla base di una metodologia di sviluppo che prende il nome di TDD, Test Driven Development (sviluppo guidato dai test).

Il TDD si basa su 3 “semplici” fasi:

  1. Scrivi un test che descriva la funzionalità desiderata;
  2. Scrivi il minimo codice sufficiente a far passare il test;
  3. Se necessario effettua del refactoring (facendo in modo che i test continuino a passare al termine dell’operazione);

Se per uno sviluppatore scrivere test non è poi così complesso e porta tutti i vantaggi menzionati, iniziare a lavorare in TDD è tutto un altro paio di maniche! Ci vuole tempo e costanza per riuscire ad invertire il classico flusso di produzione del codice, iniziando a pensare attraverso i test.

Partire dai test costringe a definire a priori casistiche di funzionamento concrete e interfacce comode di utilizzo della funzionalità desiderata da parte del mondo esterno. In altre parole, obbliga a pensare costantemente a quello che si sta facendo.

Quale è il risultato di questa fatica immane? Ottenere un design complessivo più pulito e modulare, composto da sotto-componenti più coesi, disaccoppiati e dalle responsabilità meglio definite.

Pensare da stakeholder con il BDD

Pur lavorando in TDD, deformazione professionale vuole che uno sviluppatore, per la realizzazione di una funzionalità richiesta dal cliente, spesso tenda a partire “dalle fondamenta” per spostarsi via via verso layer superiori ad astrazione più alta.

È una pratica assolutamente valida che porta con sè un rischio notevole: perdere per strada il focus sul senso ultimo di quello che si sta realizzando.

Può sembrare un'ovvietà, certo, ma quando si parla di task complessi, con decine di parti “in movimento” e condizioni da tenere in considerazione, è un rischio assolutamente concreto e da non sottovalutare, che spesso porta a generalizzare inutilmente i vari layer sottostanti.

The most insidious cause of overengineering is over-generalizing.

La naturale estensione della pratica del TDD, prende il nome di Behavior Driven Development, che cerca di risolvere il problema invertendo nuovamente l'approccio più “naturale” ma soggetto a errori.

Sviluppando in BDD, si parte sempre da un caso d'uso concreto. Questo caso d'uso — che sfruttando un dizionario più agile prende il nome di storia — non è altro che una specifica ad alto livello, redatta insieme allo stakeholder, espressa in un lessico business-oriented più che tecnico, per esempio:

“Come utente, per poter accedere ai miei ordini, voglio potermi loggare inserendo email e password”

L'obiettivo è evidenziare il fine ultimo, non lasciare spazio a incertezze interpretative e porre l'accento sul cosa realizzare, piuttosto che sul come.

La storia viene dunque implementata anch’essa sotto forma di test ad alto livello, e si procede con le regole TDD alla sua soluzione progressiva, producendo il numero minimo di sotto-funzionalità fondamentali a farlo passare.

In altre parole, lavorare per casi d’uso in BDD consente di avere sempre a disposizione uno straordinario filo d’Arianna in grado di mantenere fissa la rotta senza perdersi nei meadri del codice prodotto.

Untested code is broken code®

Dopo questo rapido excursus “ad alto livello”, speriamo che chiunque, compreso chi non proviene dal nostro settore, possa quantomeno intuire gli enormi rischi a cui si espone chi inizia lo sviluppo di un nuovo progetto senza esigere la presenza di una suite di test, e come questa decisione abbia degli impatti diretti sul prodotto finale in termini di mantenibilità, documentazione e qualità del design complessivo.

Il testing è più un'arte che una scienza. Il prossimo post sul mondo del testing avrà un carattere più tecnico e cerceremo di descrivere nel concreto il nostro modo di approcciarci alla tematica in un contesto Rails.

Hai trovato questo post interessante?Scopri chi siamo

Made with Middleman and DatoCMS, our CMS for static websites