Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 1 di 1
  • livello intermedio
Indice lezioni

Testare un'API REST con l'AI

Scopriamo come utilizzare Claude Code per testare un'API REST già in fase di produzione scritta in Express e Node.js
Scopriamo come utilizzare Claude Code per testare un'API REST già in fase di produzione scritta in Express e Node.js
Link copiato negli appunti

Il nostro progetto è un'API REST scritta in Express e Node.js, nata come prototipo interno e poi promossa a produzione nel giro di poche settimane — come capita, più spesso di quanto si vorrebbe ammettere. La specifica OpenAPI era presente, aggiornata, e sufficientemente dettagliata da descrivere request body, response schema, codici di stato, casi di errore.

Quello che manca completamente è una suite di test. Nessun test unitario sui controller, nessun test di integrazione sugli endpoint, nessuna verifica automatica che il comportamento reale dell'API corrispondesse a quello documentato nella specifica.

La situazione è comune. La specifica OpenAPI viene scritta come documentazione, non come contratto verificabile. I test vengono posticipati al "prossimo sprint" che non arriva mai. E nel frattempo l'API viene chiamata da un frontend in React che si è adattato empiricamente al comportamento effettivo. Non necessariamente a quello documentato.

L'esperimento consiste nel dare a Claude Code la specifica OpenAPI e un obiettivo preciso: genera i test, eseguili contro l'istanza locale dell'API, interpreta i risultati e itera fino a quando i test passano o produci un report chiaro di cosa non funziona. Il vincolo è non scrivere manualmente nessuna riga di codice di test (non per pigrizia, ma per capire fino a dove arriva davvero l'autonomia dell'agente su un task di questo tipo).

La specifica OpenAPI come punto di ingresso per l'agente

Prima di descrivere cosa ha fatto Claude Code, vale la pena soffermarsi su cosa rende una specifica OpenAPI un input particolarmente adatto per un agente. A differenza del codice sorgente, che descrive come qualcosa è implementato, una specifica OpenAPI descrive cosa un sistema dovrebbe fare. Contiene i contratti: quali endpoint esistono, quali parametri accettano, quali risposte producono in quali condizioni. È, in sostanza, una raccolta di asserzioni verificabili.

Per un agente che deve generare test per una API REST, questo è oro. Invece di inferire il comportamento atteso leggendo l'implementazione, operazione che richiede di capire la logica applicativa, i side effect, le dipendenze, l'agente può leggere la specifica e tradurre ogni endpoint in un insieme di casi di test in modo quasi meccanico. Per ogni endpoint definito nella specifica, esistono almeno tre categorie di test che si possono generare automaticamente: il caso happy path con input valido, i casi di errore con input non valido o mancante e i casi di autorizzazione con token mancante o non valido.

Il frammento di specifica da cui siamo partiti descriveva, tra gli altri, un endpoint per la gestione degli ordini:

paths:
  /orders:
    post:
      summary: Crea un nuovo ordine
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [customerId, items]
              properties:
                customerId:
                  type: string
                  format: uuid
                items:
                  type: array
                  minItems: 1
                  items:
                    type: object
                    required: [productId, quantity]
                    properties:
                      productId:
                        type: string
                      quantity:
                        type: integer
                        minimum: 1
      responses:
        '201':
          description: Ordine creato con successo
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Order'
        '400':
          description: Request body non valido
        '401':
          description: Token mancante o non valido
        '422':
          description: Dati semanticamente non validi (es. prodotto inesistente)

Da questa specifica, un tester esperto scriverebbe almeno sette o otto casi di test. Claude Code ne ha generati undici al primo tentativo, coprendo tutti i casi ovvi e alcuni meno ovvi, come la verifica che un array items vuoto restituisse effettivamente un 400 e non un 422, distinzione che la specifica rendeva implicita ma non esplicita.

Come Claude Code ha strutturato la suite di test per l'API REST

La prima decisione che l'agente ha preso autonomamente, e che merita attenzione, è stata la scelta del framework di test. Leggendo il package.json del progetto, Claude Code ha rilevato che Jest era già installato come dipendenza di sviluppo, e ha scelto di usarlo invece di proporre Supertest o un altro framework esterno. È una scelta sensata: riduce le dipendenze, riusa ciò che è già presente e produce output compatibile con la configurazione CI esistente. Non è una scelta ovvia per un agente che potrebbe benissimo proporre sempre lo stesso stack indipendentemente dal contesto.

La struttura dei file generata segue una convenzione ragionevole: una cartella __tests__/integration separata dai test unitari, un file per ogni gruppo di endpoint correlati e un file di setup condiviso per la gestione dell'istanza Express e dei dati di fixture. Il codice del file di setup era questo:

// __tests__/integration/setup.ts
import { Express } from 'express';
import request from 'supertest';
import { createApp } from '../../src/app';
import { db } from '../../src/database';
let app: Express;
beforeAll(async () => {
  app = await createApp({ env: 'test' });
  await db.migrate.latest();
  await db.seed.run();
});
afterAll(async () => {
  await db.destroy();
});
afterEach(async () => {
  await db('orders').del();
});
export { app, request };

Qui Claude Code ha fatto un'assunzione non banale: ha ipotizzato che createApp accettasse un parametro di configurazione per distinguere l'ambiente di test, e che il database usasse Knex con migration e seed. Entrambe le assunzioni erano corrette nel contesto del progetto e l'agente le aveva inferite leggendo i file sorgente dell'applicazione prima di generare il setup. Ma è un buon esempio di come l'agente costruisca un modello implicito del progetto. Quando quell'assunzione fosse stata sbagliata, il file di setup sarebbe risultato silenziosamente inutilizzabile.

Nella seconda parte continueremo a parlare di test dell'API REST e passeremo alla fase di esecuzione.

Se vuoi aggiornamenti su Testare un'API REST con l'AI inserisci la tua email nel box qui sotto:

Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.

Ti consigliamo anche