Il sito usa solo cookie tecnici necessari al funzionamento: nessun tracciamento, nessuna profilazione. Cookie Policy

Salta al contenuto
Tutti i termini

Cos'è il contract testing?

Verifica che consumer e provider di un'API rispettino un contratto condiviso, senza un ambiente integrato.

Il contract testing è una tecnica di verifica che controlla se il consumer e il provider di un'API rispettano un contratto condiviso, senza dover montare un ambiente di integrazione completo con entrambi i servizi in esecuzione. Il consumer registra, in un test isolato, le richieste che invia e le risposte che si aspetta di ricevere; quel contratto viene poi rieseguito contro il provider, in isolamento, per verificare che lo rispetti davvero. La variante più diffusa è consumer-driven, con strumenti come Pact: è il consumer a definire cosa gli serve, non il provider a dettare cosa offre, così il contratto resta ancorato all'uso reale. Esiste anche l'approccio provider-driven, in cui è il provider a pubblicare uno schema (spesso OpenAPI) che i consumer devono rispettare, più adatto a API pubbliche con molti consumer sconosciuti. La garanzia però è più debole: verifica che il provider rispetti lo schema dichiarato, non che i consumer lo stiano usando come previsto. Il vantaggio comune resta la velocità: test eseguibili in pipeline separate dalle due parti.

Come funziona in pratica

Nel flusso consumer-driven, il test del consumer produce un file di contratto (in Pact, un documento JSON) che descrive interazione per interazione: richiesta attesa, risposta attesa. Quel file viene pubblicato in un broker condiviso. Il provider, nella propria pipeline di CI/CD, scarica i contratti pubblicati dai suoi consumer e li riesegue contro la sua implementazione reale: se una risposta cambia forma, il test di verifica del provider fallisce prima del deploy, non dopo, quando il consumer in produzione smette di funzionare. Non serve avviare entrambi i servizi insieme: ogni lato testa la propria metà del contratto in isolamento, in pochi secondi invece dei minuti (o delle ore) di un ambiente di staging condiviso. È qui che il contract testing si distingue nettamente dal data contract: quest'ultimo governa lo schema e la semantica di un dataset scambiato fra chi produce e chi consuma dati, mentre il contract testing verifica il comportamento di un'API fra servizi, cioè richieste e risposte HTTP o messaggi, non righe di una tabella. I due si assomigliano nel nome e nell'idea di fondo, ma vivono su livelli diversi dello stack.

Un esempio enterprise

Un retailer che scompone il monolite in servizi con dati propri ha un servizio ordini che chiama il servizio prezzi per calcolare un totale. Senza contract testing, ogni modifica al servizio prezzi richiede un deploy in staging con entrambi i servizi attivi per scoprire se qualcosa si è rotto, un ciclo che rallenta ogni release. Con Pact, il team ordini scrive un test che registra: "mi aspetto un campo totalPrice numerico dato questo SKU". Quel contratto entra nella pipeline del servizio prezzi: se un rilascio rinomina il campo o ne cambia il tipo, la build del servizio prezzi fallisce subito, con il nome esatto del consumer che si romperebbe. I due team rilasciano indipendentemente, senza coordinare un ambiente comune. Va detto il limite: un test che passa garantisce solo che il campo esista e sia numerico, non che il prezzo calcolato sia corretto. La correttezza funzionale e gli effetti collaterali restano ai test del servizio prezzi, non al contratto.

Perché conta per chi decide

Il contract testing è la risposta pratica al costo crescente dei test end-to-end quando i servizi si moltiplicano: quei test sono lenti, fragili e diventano un collo di bottiglia condiviso da tutti i team. Sostituirli, dove possibile, con contratti verificati indipendentemente accelera i rilasci e sposta la scoperta dei problemi di compatibilità dal giorno del deploy al momento della build. Il costo onesto: introdurre e mantenere un broker di contratti è un investimento organizzativo, e conviene sulle interfacce che cambiano spesso o attraversano confini di team, non su ogni chiamata interna di un sistema stabile con un solo team, dove l'overhead supera il beneficio.

  • Data contract · Accordo formale tra chi produce e chi consuma un dato: schema, semantica e SLA versionati e verificati automaticamente in CI.
  • Piramide dei test · Modello che distribuisce lo sforzo di test su più test unitari, meno di integrazione, pochi end-to-end.
  • CI/CD · Continuous Integration e Continuous Delivery: ogni modifica al software viene testata e portata in produzione in modo automatico e frequente.
  • Database per servizio · Ogni microservizio possiede il proprio archivio dati e nessun altro lo legge direttamente: solo tramite le sue interfacce.
  • Bounded context · Confine esplicito entro cui un termine di business ha un unico significato coerente, senza forzare un modello dati unico globale.

Un termine che ti riguarda da vicino? Parliamone.

CONTATTAMI