
Saltare i test del software sembra un risparmio di tempo, finché un bug non arriva in produzione. Ecco cosa costa davvero e come costruire una QA su misura.
È una delle decisioni più comuni nei progetti software, ed è anche una delle più costose: la scadenza si avvicina, la funzionalità sembra funzionare quando la si prova a mano, e i test vengono rimandati a "dopo". Dopo, spesso, vuol dire dopo il rilascio, quando a trovare i bug non è più un tester ma un cliente pagante. A quel punto la correzione costa molto di più di quanto sarebbe costata poche settimane prima — in ore di sviluppo, in ticket di assistenza, e nella fiducia di chi usa il prodotto.
Questo non è un invito a testare tutto in modo esaustivo prima di ogni rilascio. La maggior parte delle aziende in crescita non può permetterselo, e non ne ha nemmeno bisogno. È un invito a capire cosa costa davvero saltare i test, dove i team tagliano più spesso gli angoli, e come si costruisce una strategia di test proporzionata alla dimensione reale dell'azienda, invece di copiare quella di un'organizzazione molto più grande.
Ogni difetto ha una curva di costo, e questa curva diventa più ripida quanto più tardi viene scoperto. Un bug individuato mentre lo sviluppatore sta ancora scrivendo il codice costa pochi minuti da correggere: il contesto è fresco, la modifica è piccola, e nulla dipende ancora da quella parte di codice. Lo stesso bug scoperto durante una code review costa un po' di più: qualcun altro deve prima capire il contesto prima di poterlo correggere. Se emerge in ambiente di staging prima del rilascio, il costo sale ulteriormente: bisogna riprodurlo, isolarlo e verificare la correzione senza interferire con altro lavoro già in corso.
Se emerge invece in produzione, il costo cambia categoria. Non si tratta più solo di correggere il codice: ci sono ticket di assistenza da gestire, un hotfix scritto sotto pressione, un possibile rollback che rischia di rompere qualcos'altro, e in certi casi un danno economico o di reputazione concreto. I dati potrebbero già essere stati creati o alterati usando la logica difettosa, quindi la correzione deve anche occuparsi di ripulire le conseguenze, non solo di prevenire il problema in futuro. Quella che sarebbe stata una modifica da cinque minuti diventa un incidente di più giorni, che coinvolge diverse persone che non avevano previsto di passare così la propria settimana.
I costi di un testing insufficiente raramente compaiono come una voce unica di bilancio, ed è proprio per questo che è facile sottovalutarli. Si manifestano come ore di sviluppo spese a spegnere incendi invece che a costruire nuove funzionalità. Si manifestano come ticket di assistenza che si sarebbero potuti evitare, ognuno dei quali richiede a una persona di leggerlo, riprodurlo ed eventualmente escalarlo. Si manifestano come clienti che smettono silenziosamente di usare una funzionalità — o il prodotto stesso — dopo essersi scontrati due volte con lo stesso problema.
C'è anche una dimensione legata alla sicurezza che è facile trascurare. Saltare i test raramente significa saltare solo i controlli funzionali: spesso significa saltare anche il lavoro meno gratificante di testare i casi limite, gli input inattesi e i percorsi di errore — esattamente le aree dove tendono a nascondersi le vulnerabilità di sicurezza. Una funzionalità che "funziona" nel percorso previsto può comunque gestire male i permessi, esporre dati che non dovrebbe, o fallire in un modo sfruttabile da un malintenzionato. Niente di tutto questo emerge in una demo. Prima o poi, emerge tutto.
Alcuni schemi ricorrono continuamente in team che non sono negligenti per scelta, ma semplicemente sotto pressione di tempo e senza una strategia di test definita.
Testare solo alla fine, come fase separata. Quando il testing viene compresso negli ultimi giorni prima del rilascio, non resta tempo per correggere ciò che emerge — così i problemi vengono declassati a "problemi noti" e rilasciati comunque.
Testare solo il percorso previsto. È naturale testare lo scenario per cui è stata pensata la funzionalità. È molto più raro, senza uno sforzo deliberato, testare cosa succede quando un utente inserisce un dato inatteso, perde la connessione a metà di un'azione, o fa le cose in un ordine che nessuno aveva previsto.
Nessuna rete di sicurezza contro le regressioni. Senza una suite di test che ricontrolli automaticamente le funzionalità esistenti, ogni nuovo rilascio è una scommessa sul fatto che non si sia rotto nulla di importante. Il team lo scopre quando è un cliente a segnalarlo.
Test manuali che non scalano. Il testing manuale ha un valore reale, soprattutto per l'esplorazione di nuove funzionalità, ma affidarsi solo a quello significa che lo sforzo di test non cresce con il prodotto: diventa sempre più sottile man mano che il codice si espande, anche se l'impegno del team resta lo stesso.
Ambienti di test che non somigliano alla produzione. Un codice che funziona sul portatile di uno sviluppatore ma si comporta diversamente con volumi di dati reali, condizioni di rete reali o integrazioni reali con terze parti dà una falsa sensazione di sicurezza.
L'obiettivo non è coprire il 100% del codice con dei test — non è realistico, né un buon uso del tempo di un team piccolo. L'obiettivo è dare priorità in base al rischio: capire quali parti del prodotto farebbero più danno se si rompessero, e proteggere quelle per prime.
Per la maggior parte delle aziende, questo significa test di regressione automatizzati sui flussi che generano ricavi o gestiscono dati sensibili — checkout, autenticazione, fatturazione, i processi core da cui i clienti dipendono ogni giorno. Sono le aree dove una regressione silenziosa costa di più, e l'automazione permette di controllarle a ogni rilascio senza consumare ore manuali ogni volta.
Significa riservare il testing manuale ed esplorativo alle funzionalità davvero nuove o complesse, dove il giudizio umano su "cosa proverebbe a fare un utente reale" vale più di un controllo scriptato. E significa mantenere gli ambienti di test abbastanza vicini alla produzione — per struttura dei dati, configurazione e scala — che superare i test in staging significhi davvero qualcosa.
Niente di tutto questo richiede un grande reparto QA dedicato. Richiede una decisione consapevole su dove indirizzare lo sforzo di test, presa una volta e rivista mano a mano che il prodotto cresce, invece di essere lasciata al caso a ogni nuova scadenza.
I team più solidi non trattano il testing come un cancello alla fine dello sviluppo: lo trattano come parte del modo in cui il lavoro viene svolto. Gli sviluppatori scrivono unit test come parte del completamento di una funzionalità, non come un extra facoltativo. La code review include la domanda "cosa potrebbe rompersi", non solo se il codice compila. Una pipeline di integrazione continua esegue automaticamente la suite di test a ogni modifica, individuando le regressioni prima ancora che una persona guardi il codice.
Questo spostamento — spesso chiamato "shift left", perché il testing si sposta prima nel processo — tende a essere più economico e veloce di quanto sembri, perché sostituisce un costoso lavoro di emergenza in fase avanzata con controlli economici in fase iniziale. Crea anche un utile ciclo di apprendimento: quando qualcosa si rompe davvero in produzione, la correzione include un nuovo test che garantisce che lo stesso problema non possa ripresentarsi silenziosamente, così la rete di sicurezza si rafforza nel tempo invece di restare statica.
Poche domande oneste rivelano più di qualsiasi audit. Quanti dei bug segnalati dai clienti erano cose che un test avrebbe potuto plausibilmente individuare? Con quale frequenza un rilascio è seguito da un hotfix nel giro di pochi giorni? Quanto tempo passa prima di accorgersi che qualcosa si è rotto — ore, oppure è un cliente a doverlo segnalare? Esiste una suite di test automatizzati che cresce ed è eseguita a ogni modifica, o "testare" significa che qualcuno clicca in giro nell'app prima del rilascio?
Se lavori con un partner di sviluppo esterno, le stesse domande valgono anche per lui. Un partner che tratta il testing come parte reale del processo ingegneristico — e non come un ripensamento infilato se resta tempo — è di solito in grado di descrivere concretamente il proprio approccio: cosa viene automatizzato, cosa viene testato manualmente e perché, e come vengono intercettate le regressioni prima che arrivino ai clienti.
Saltare i test non fa risparmiare tempo: lo prende in prestito dal futuro, di solito con gli interessi. Le aziende che gestiscono bene questo aspetto non sono quelle con i reparti QA più grandi, ma quelle che hanno preso una decisione chiara, basata sul rischio, su dove concentrare lo sforzo di testing, l'hanno integrata nel modo di lavorare invece di aggiungerla in fondo, e continuano ad aggiustarla man mano che il prodotto cresce. È un obiettivo molto più raggiungibile di "testare tutto", ed è quello che protegge davvero sia il prodotto sia le persone che lo usano.
Explore more from Software Development