Quando si lavora con Claude Code per generare test automatici su un’API REST, il momento più istruttivo non arriva dai test che funzionano al primo colpo. Arriva dai fallimenti, in particolare da quello che l’agente non è riuscito a chiudere da solo. Il terzo caso emerso durante l’esperimento riguarda un test che verificava il comportamento dell’API quando due richieste concorrenti provavano a creare ordini con lo stesso customerId, mentre l’API doveva garantire un tetto massimo di ordini aperti per cliente.
Il caso che è rimasto aperto, la race condition
Qui Claude Code ha capito subito la natura del problema. Non era un bug dell’API, era una questione di timing nel test. Le due richieste non erano davvero concorrenti perché Jest le eseguiva una dopo l’altra, così l’AI ha suggerito Promise.all per farle partire in parallelo. Idea giusta sulla carta. Nella pratica meno, perché l’ambiente di test usava un database SQLite in memoria che non gestiva le transazioni concorrenti come ci si aspettava. Il test continuava a fallire, e per giunta in modo non deterministico.
Dopo due tentativi andati a vuoto, l’agente ha prodotto quello che è stato forse il passaggio più onesto dell’intera sessione. Ha spiegato che serviva un database capace di gestire una concorrenza reale, che SQLite in modalità WAL avrebbe potuto reggere ma richiedeva una modifica alla configurazione, e che la strada più pulita era probabilmente mockare il layer di persistenza solo per quel test. Ha messo sul tavolo entrambe le opzioni con i relativi compromessi. Non ha risolto in autonomia, però ha lasciato allo sviluppatore un’analisi abbastanza chiara da decidere in pochi minuti, invece di perderne sessanta a inseguire una race condition.
I fallimenti letti come documentazione
Una delle cose più interessanti è stata la qualità del ciclo di interpretazione e correzione che Claude Code ha portato avanti da solo nelle prime iterazioni. A ogni test fallito leggeva l’output completo di Jest, diff tra valore atteso e valore ricevuto compresi, e restituiva la correzione insieme a una spiegazione del perché stava fallendo. Spesso quella spiegazione valeva più del fix. Faceva emergere discrepanze tra la specifica OpenAPI e l’implementazione vera che nessuno aveva notato.
Un esempio concreto. Un endpoint documentato come idempotente restituiva 201 alla prima chiamata e 200 alla seconda, mentre la specifica prevedeva 201 in entrambi i casi. Il comportamento in sé era sensato, non sbagliato, ma contraddiceva la documentazione. Il test ha reso quella contraddizione visibile e misurabile. Senza, sarebbe rimasta nascosta fino al giorno in cui un client avesse basato le sue scelte sul codice di stato.
Quando conviene davvero e quando no
L’esperimento ha prodotto ventisette test funzionanti, ventisei togliendo la race condition, in circa quaranta minuti di sessione supervisionata. Scriverli a mano ne avrebbe chiesti tre o quattro ore, con una qualità paragonabile sui casi standard e forse migliore sui casi limite più contorti. Il rapporto costi benefici è favorevole in un contesto preciso, un’API con una specifica OpenAPI esistente, aggiornata e dettagliata, ancora priva di copertura di test.
Cambia tutto negli altri scenari. Se la specifica è incompleta o disallineata, l’agente genera test che falliscono per motivi che nulla hanno a che fare con bug reali, e capire la differenza richiede tempo. Se l’API ha una logica di business piena di dipendenze esterne da mockare, il setup dei test diventa presto il collo di bottiglia e l’agente tende a fare assunzioni non sempre corrette. E se il progetto non ha nemmeno una configurazione minima, niente Jest, nessuna struttura di cartelle, nessun modo di avviare l’app in modalità test, metà sessione se ne va nel costruire quell’infrastruttura, con risultati meno prevedibili.
Resta un ultimo punto che si nota solo guardando il tutto dall’alto. La suite prodotta è diventata subito la documentazione eseguibile più affidabile del comportamento dell’API. Non la specifica OpenAPI, che descrive l’atteso ma non gira. Non i commenti nel codice, che non si aggiornano da soli. I test sì, perché falliscono quando il comportamento diverge da quello dichiarato e chiunque può lanciarli in locale in trenta secondi. Non è un merito esclusivo dell’approccio agentico, qualsiasi suite ben scritta fa lo stesso. Cambia però il calcolo su quando investire nella copertura, perché non serve più trovare il tempo per farla bene, ne bastano quaranta per supervisionare un agente che la fa in modo accettabile. Accettabile con review critica e consapevolezza dei limiti, il che nella maggior parte dei progetti reali è già molto meglio di niente.