Ciao, e benvenuto nella settima puntata della sessantanovesima stagione. Torniamo per un attimo alla prima puntata. Avevamo detto che un test verifica un caso: dato il due, mi aspetto il quattro. Ma un caso è una goccia in un oceano. Il tuo codice deve funzionare per infiniti valori diversi, e tu ne provi cinque, dieci, forse venti. Come si fa a coprire di più senza scrivere un milione di test a mano? Oggi vediamo una tecnica che sposta la domanda su un altro piano: i test basati sulle proprietà.
Partiamo dal limite dei test che conosciamo. Quando scrivi un test con un esempio, sei tu a scegliere i casi. E scegli quelli a cui pensi. Il problema è proprio lì: i bug si nascondono nei casi a cui non pensi. La stringa vuota, il numero negativo, la lista con un solo elemento, la data del ventinove febbraio. Il tuo cervello, quando sceglie gli esempi, tende a scegliere quelli comodi, quelli normali. E gli angoli scomodi, dove abitano i bug, restano fuori dall'esperimento proprio perché non ti sono venuti in mente.
Vediamo l'idea nuova, che è un salto di prospettiva. Invece di dire dato il due mi aspetto il quattro, dichiari una proprietà che deve valere sempre, per qualunque ingresso. Faccio un esempio classico: se prendo una lista, la rovescio, e poi la rovescio di nuovo, devo riottenere la lista di partenza. Sempre. Per qualunque lista, corta, lunga, vuota, piena di qualunque cosa. Non stai più parlando di un caso: stai parlando di una legge. E a questo punto entra in gioco lo strumento: tu dichiari la legge, e il computer genera per te centinaia di casi a caso, di ogni forma e dimensione, e prova a trovarne uno che la violi.
Nota la differenza rispetto a come lavoravamo prima, perché è enorme. Prima eri tu a fare la fatica di inventare i casi, e ne inventavi pochi, e tutti simili. Adesso la fatica la fa la macchina, e ne prova centinaia, molti dei quali bizzarri, proprio quelli che tu non avresti mai scritto. È come passare dal controllare qualche punto di una legge di natura al bombardarla con ogni situazione possibile, per vedere se in qualche caso strano crolla. È l'esperimento portato su scala industriale: mille prove automatiche al posto di dieci prove pensate a mano.
E c'è un dettaglio geniale, che rende questa tecnica davvero pratica. Quando lo strumento trova un caso che rompe la tua proprietà, magari una lista lunghissima e complicata, non si limita a dirtelo. Fa una cosa in più: prende quel caso mostruoso e lo semplifica, un pezzo alla volta, cercando il caso più piccolo che ancora fa fallire la proprietà. Così, invece di consegnarti una lista di cinquecento elementi impossibile da leggere, ti dice: guarda, si rompe già con la lista di due elementi, questi due. Ti serve su un piatto d'argento il controesempio minimo. Ti punta il dito esattamente sul cuore del problema, senza rumore intorno.
C'è un legame profondo con la stagione scorsa, e vale la pena nominarlo. Là avevamo parlato di verifica formale: dimostrare che una proprietà vale per tutti i casi. Questa tecnica è la sua cugina pratica, quella dei poveri, in senso buono. Non dimostra che la proprietà vale per tutti i casi: quello resta impossibile, per la nostra frase della prima puntata. Ma invece di controllare cinque casi scelti da te, ne campiona centinaia scelti apposta per essere difficili. È a metà strada tra il test con l'esempio e la dimostrazione: molto più della prima, molto meno della seconda, ma raggiungibile con uno sforzo umano ragionevole, senza scomodare la matematica pesante. Il punto giusto per moltissimo codice di tutti i giorni.
Voglio lasciarti con il cambio di mentalità che questa tecnica richiede, perché è la parte più preziosa. Ti costringe a smettere di pensare a esempi, e a cominciare a pensare a leggi. Invece di chiederti cosa deve restituire questa funzione per questo ingresso, ti chiedi: cos'è sempre vero sul risultato di questa funzione, qualunque sia l'ingresso? È una domanda più difficile, e più profonda. Spesso, solo formulare bene la proprietà ti fa capire meglio cosa dovrebbe fare davvero il tuo codice. E a volte scopri che una proprietà che credevi vera, vera non è: e questa è già una scoperta che nessun esempio ti avrebbe regalato.
Per oggi ci fermiamo qui. Siamo andati oltre l'esempio. I test con gli esempi li scegli tu, e scegli quelli comodi, mentre i bug si annidano nei casi a cui non pensi. La svolta è dichiarare una proprietà che deve valere sempre, per ogni ingresso, e lasciare che la macchina generi centinaia di casi difficili per provare a smentirla. Quando ne trova uno, lo restringe fino al controesempio minimo e te lo serve pronto. È la cugina pratica della verifica formale: non dimostra tutto, ma campiona molto più e molto meglio di te. E ti cambia la testa: dagli esempi alle leggi, dal cosa fa qui al cosa è sempre vero. Nella prossima puntata: a cosa servono davvero. Nelle note trovi qualche spunto. Se ti è utile, condividila. Grazie per l'ascolto, e ci sentiamo alla prossima.