Qualità e sviluppo software
Test basati su proprietà: verificare le regole del software aziendale
Un test costruito su un esempio dimostra che il programma produce un certo risultato in una situazione precisa. Le regole aziendali, però, devono restare valide anche quando cambiano quantità, sequenze e combinazioni di valori. Il collaudo basato su proprietà parte da questa esigenza: descrivere una condizione verificabile e cercare dati capaci di smentirla. Il valore del metodo dipende dalla qualità della regola e dal perimetro degli ingressi, prima ancora che dal numero di prove eseguite. È un lavoro di modellazione che avvicina sviluppo, revisione e conoscenza del processo.
Dall’esempio corretto alla regola che deve restare vera
Un esempio può verificare che un importo venga ripartito correttamente tra tre destinazioni specifiche. Una proprietà chiede invece che, per tutti gli ingressi ammessi dal contratto, la somma delle quote assegnate coincida con il totale da ripartire. Strumenti come Hypothesis, nel contesto Python, permettono di dichiarare un dominio di dati e generare casi sui quali controllare queste condizioni. La verifica esplora un insieme di situazioni: un esito positivo non costituisce una dimostrazione matematica universale, ma può far emergere combinazioni che gli esempi scelti manualmente non consideravano.
Per formulare una proprietà utile occorre chiarire che cosa debba rimanere invariato. In un trasferimento interno di quantità, il totale può restare costante; in una normalizzazione, applicare due volte la trasformazione può dover produrre lo stesso risultato ottenuto alla prima applicazione. Queste affermazioni valgono soltanto nel contratto che le prevede. Non ogni operazione aziendale conserva un totale e non ogni trasformazione è idempotente. Il confronto con chi conosce la regola evita di trasformare un’aspettativa intuitiva in un vincolo sbagliato.
Definire il dominio prima di generare gli ingressi
Consideriamo un esempio esclusivamente illustrativo: una funzione deve distribuire un totale non negativo, espresso in centesimi interi, tra destinazioni con pesi positivi. Il contratto stabilisce che tutte le quote siano non negative, che la loro somma conservi il totale e che gli eventuali resti vengano assegnati con un criterio deterministico. Il dominio deve comprendere valori piccoli, totali nulli, pesi molto diversi e casi in cui il totale sia inferiore al numero delle destinazioni. Sono proprio queste combinazioni a mettere in discussione le scorciatoie dell’implementazione.
La documentazione Hypothesis distingue il dominio degli ingressi dalla distribuzione con cui lo strumento li esplora. La scelta dei valori possibili spetta a chi progetta il test; restringerli senza una ragione può escludere il caso che rivela un difetto. Nel nostro esempio, limitarsi a importi divisibili esattamente per il numero delle quote eliminerebbe il problema dei resti prima ancora di verificarlo. I limiti imposti per sostenibilità delle prove devono essere espliciti e coerenti con il contratto, lasciando riconoscibili le aree che richiedono altri controlli.
Costruire un controllo indipendente dall’implementazione
Il test perde forza quando calcola il risultato atteso con la stessa procedura del programma. Copiare la formula di ripartizione in una funzione di verifica può riprodurre lo stesso errore due volte. Nel caso illustrativo, il controllo di conservazione può essere indipendente dalla strategia usata per assegnare i resti: sommare le quote e confrontarle con il totale originale. Occorre aggiungere altre proprietà, perché la sola conservazione ammetterebbe anche una soluzione che assegna tutto alla prima destinazione, ignorando i pesi concordati.
Le verifiche possono combinare condizioni diverse: numero delle quote, assenza di valori negativi, conservazione del totale e rispetto dei limiti di approssimazione definiti dal contratto. Se tutte le destinazioni hanno lo stesso peso, la differenza tra le quote può essere limitata secondo la regola di arrotondamento scelta. I casi semplici con risultato noto restano preziosi per controllare il significato delle proprietà. Il gruppo dovrebbe poter spiegare quale famiglia di errori ciascuna condizione riesce a intercettare e quali comportamenti scorretti rimangono ancora compatibili con essa.
Usare trasformazioni controllate quando manca un risultato completo
In alcuni problemi è più semplice prevedere una relazione tra due esecuzioni che l’intero risultato. Se il contratto tratta le destinazioni come identità indipendenti dall’ordine di presentazione, riordinare l’ingresso dovrebbe conservare l’associazione tra identità e quota. Questa verifica richiede però attenzione alla gestione dei resti: un criterio basato sulla posizione renderebbe la proprietà inapplicabile. Prima di usarla, bisogna stabilire se l’ordine abbia davvero un significato operativo. Anche una buona tecnica di collaudo può fallire quando incorpora un presupposto non condiviso.
Un’altra relazione possibile riguarda la normalizzazione dei dati. Se una procedura elimina soltanto spazi non significativi secondo una regola concordata, normalizzare un valore già normalizzato dovrebbe lasciarlo invariato. Non si può estendere automaticamente la stessa attesa a trasformazioni che perdono informazione, cambiano precisione o aggiungono una marca temporale. Le relazioni tra esecuzioni aiutano a verificare funzioni complesse, ma devono essere motivate singolarmente. Il test deve esprimere ciò che il dominio garantisce, senza inventare simmetrie comode soltanto per semplificare il controllo.
Interpretare un fallimento prima di cambiare il codice
Quando emerge un ingresso problematico, il primo compito è capire quale ipotesi sia stata smentita. Potrebbe esserci un difetto nel programma, un generatore che produce casi fuori contratto oppure una proprietà troppo forte. Nel nostro esempio, una destinazione con peso nullo può essere un ingresso valido da trattare oppure un errore da rifiutare: la risposta deve venire dalla specifica. Escludere quel valore soltanto perché il test fallisce nasconderebbe una decisione ancora aperta e ridurrebbe la capacità del collaudo di scoprire ambiguità.
La riproduzione deve comprendere ingresso, versione del codice e condizioni rilevanti dell’esecuzione. Dipendenze dall’orologio, stato condiviso o servizi esterni possono rendere il fallimento instabile. È utile isolare la regola pura dove possibile e verificare separatamente il collegamento con l’infrastruttura. Se una prova passa soltanto al secondo tentativo, il comportamento richiede un’analisi: ripeterla fino al successo non spiega il problema. Il risultato da conservare è una descrizione comprensibile del caso, insieme alla motivazione che permette di classificarlo correttamente.
Conservare i casi scoperti come patrimonio di regressione
Hypothesis prevede meccanismi per salvare e riprodurre i fallimenti, ma la sua documentazione raccomanda di usare esempi espliciti quando si vuole garantire che un ingresso venga provato a ogni esecuzione. Il database locale dello strumento non sostituisce quindi la manutenzione dei casi importanti. Dopo la correzione, conviene aggiungere il caso scoperto alla raccolta di regressione, mantenendo anche la proprietà generale. Il primo documenta un problema concreto; la seconda continua a cercare altre manifestazioni dello stesso errore o combinazioni ancora inesplorate.
Nel progetto aziendale questa raccolta dovrebbe conservare il legame con la regola, evitando di inserire dati personali o documenti reali quando bastano valori sintetici. Per la ripartizione illustrativa, un totale molto piccolo e pochi pesi possono descrivere il difetto senza ricostruire alcuna operazione di un cliente. Nomi chiari e una breve spiegazione aiutano chi interverrà dopo a capire perché quel caso esista. Una raccolta di ingressi incomprensibili rischia invece di essere semplificata o rimossa durante una revisione, perdendo la memoria dei problemi risolti.
Inserire il metodo nel ciclo di sviluppo
Il punto di partenza può essere una regola circoscritta e importante, con ingressi controllabili ed esiti interpretabili. Si definiscono proprietà e casi noti, si esegue la ricerca e si misura il costo delle prove. Le verifiche più rapide possono accompagnare le modifiche ordinarie; esplorazioni più ampie possono essere pianificate separatamente. Il criterio resta la capacità di trovare errori rilevanti entro un tempo sostenibile. Contare soltanto le esecuzioni non permette di valutare la qualità dei generatori o l’indipendenza delle condizioni controllate.
Le proprietà riguardano la correttezza tecnica delle regole; la valutazione delle capacità applicative richiede un confronto diverso. Per quel versante, il catalogo delle funzioni di Gestionale sul Web offre il riferimento di prodotto. Nel lavoro di ingegneria, il metodo diventa utile quando una variazione della regola porta a rivedere consapevolmente proprietà, generatori ed esempi. Il collaudo mantiene così una spiegazione verificabile del comportamento atteso, anche quando l’implementazione viene modificata, ottimizzata o riscritta con strumenti di automazione.
Riferimenti tecnici
Per approfondire i temi tecnici trattati:
- Hypothesis: introduzione ai test basati su proprietà
- Hypothesis: dominio e distribuzione degli ingressi
- Hypothesis: riprodurre i fallimenti e conservare esempi espliciti
Analisi metodologica originale. La funzione di ripartizione è un esempio illustrativo, non una regola fiscale o una descrizione di clienti e implementazioni di Gestionale sul Web.
A cura della redazione tecnica SoftJob. Pubblicato il .
