AI per lo sviluppo software

Se l'AI scrive anche i test, chi controlla che i test siano giusti?

Una ricerca chiamata ExecCritic ha misurato qualcosa che molti sviluppatori sospettavano ma raramente avevano quantificato: quando un agente AI corregge un bug e scrive da solo anche il test che dovrebbe verificare la correzione, un test debole o mal formulato può far approvare una correzione sbagliata, peggiorando il tasso di successo complessivo invece di migliorarlo. Il problema non è "l'AI scrive test di bassa qualità" in astratto: è che il giudice e l'imputato, in questo schema, sono la stessa entità.

Il problema in una frase

Quando chiedi a un assistente AI di risolvere un bug, e lo stesso assistente scrive anche il test che dimostra che il bug è risolto, manca un ingrediente fondamentale di qualunque verifica seria: l'indipendenza tra chi implementa e chi controlla. Un umano che scrive sia il codice sia il test tende, per gli stessi bias cognitivi, a scrivere un test che conferma quello che ha appena fatto, non un test che lo mette davvero alla prova. Un modello linguistico ha lo stesso problema, amplificato dal fatto che lavora molto più in fretta e produce entrambi — implementazione e verifica — nello stesso respiro, senza la pausa che a un umano servirebbe per cambiare prospettiva.

Il risultato pratico è un test che passa non perché il bug sia davvero risolto, ma perché il test è scritto in modo da passare quasi sempre: un caso limite non coperto, un'asserzione troppo generica, una condizione che il codice corretto e quello sbagliato soddisfano entrambi allo stesso modo. Il segnale verde nella pipeline di CI diventa un falso senso di sicurezza, esattamente nel momento in cui serve di più fidarsi di quel segnale.

Segnali che un test generato dall'AI è debole

  • Il test passa anche sul codice vecchio, buggato. Se non hai mai verificato che il test fallisse prima della correzione, non sai se sta davvero testando il bug o semplicemente non sta testando nulla di rilevante.
  • Asserzioni troppo generiche. Controllare che il risultato "non sia nullo" o "sia dello stesso tipo atteso" è molto più debole che controllare il valore esatto che ti aspetti in quel caso specifico.
  • Il test rispecchia l'implementazione, non il comportamento. Un test che verifica "che la funzione chiami X e poi Y", invece di verificare "che il risultato finale sia corretto", si rompe a ogni refactoring innocuo e non protegge affatto da un refactoring pericoloso che produce comunque quella sequenza di chiamate.
  • Mock troppo aggressivi. Quando quasi tutto attorno alla funzione sotto test è simulato, spesso quello che resta da testare è talmente poco che il test non copre più il percorso logico che contava davvero.

Come verificare i tuoi test in dieci minuti

Non serve uno strumento sofisticato per fare un primo controllo concreto. Il test più semplice ed efficace è quello che si chiama, in gergo, "red before green": prima di accettare un test generato dall'AI insieme alla sua correzione, rimetti temporaneamente il codice alla versione precedente (con git stash o semplicemente commentando la riga corretta) e rilancia il test da solo. Se continua a passare anche con il bug ancora presente, quel test non sta verificando nulla di utile, indipendentemente da quanto sembri ben scritto.

Un secondo controllo, leggermente più impegnativo ma molto efficace, è una forma leggera di mutation testing fatta a mano: modifica volontariamente una condizione nel codice corretto (inverti un confronto, cambia un operatore) e verifica che il test si accorga del problema. Se il test continua a passare anche con una modifica che dovrebbe romperlo, il test è troppo permissivo. La regola pratica di fondo resta semplice: non lasciare che la stessa esecuzione AI scriva il codice, il test e la conferma finale che tutto vada bene, senza un punto di verifica indipendente in mezzo — che sia un umano che rilegge, o un controllo automatico pensato apposta per non fidarsi.

Fonte: AI-Generated Tests Can Make Coding Agents Worse. Here's How to Check Yours, su dev.to