Logo GH

Test API contractuel

1) Pourquoi les tests contractuels

Le contrat enregistre les attentes du client et les promesses du fournisseur : itinéraires/méthodes, titres, schémas de corps, statuts, sémantique d'erreur et restrictions. L'objectif est de capturer les modifications incompatibles avant l'intégration et de sortir les versions en toute sécurité, sans E2E graves.

2) Approches

Contrats de consommation (CDC) : le client forme des attentes (Pact et analogues) ; le fournisseur les vérifie régulièrement.
Spécification : le contrat comme source unique de vérité (OpenAPI/Protobuf/GraphQL SDL) ; les tests valident l'implémentation par rapport au cahier des charges.
Evénement : schémas de messages (Avro/JSON Schema/Protobuf) + règles de compatibilité dans le courtier/registre.

3) HTTP/REST : flux de spécifications

1. Contrat : OpenAPI 3. x (schémas, exemples, codes).
2. Lint et statanalyse : style, champs obligatoires, codes uniques.
3. Validation de l'implémentation : générateur de tests anti-OpenAPI (schemathesis/Dredd-approche) + négatifs manuels.
4. Snapshots : enregistrer des exemples de réponses, ETag sémantique, titres d'idempotence.

Exemple de contrat negatif (fragment OpenAPI) :
yaml paths:
/v1/payments:
post:
responses:
"201": { $ref: "#/components/responses/PaymentCreated" }
"409": { description: Duplicate by Idempotency-Key }
"422": { description: Schema/Business validation failed }

4) CDC (approche Pact)

Cycle de vie :

1. Consumer écrit un test, forme un fichier pact (attente).

2. Publication auprès d'un courtier (artefact).

3. Provider in CI soulève le service (ou le comptoir contractuel), vérifie pact's.

4. Le courtier calcule la matrice de compatibilité can-i-deploy.

Exemple de test de consommation (pseudo-JS) :
js pact
.given("wallet exists")
.uponReceiving("get wallet")
.withRequest({ method:"GET", path:"/v1/wallets/w123", headers:{ "Authorization": term({generate:"Bearer x", matcher:/^Bearer\s.+/}) }})
.willRespondWith({
status: 200,
headers: { "Content-Type": "application/json" },
body: like({ id:"w123", currency: "EUR", balance: 0 })
});

5) gRPC/Protobuf contrats

Le contrat est '.proto' avec la version des paquets/services.
Compatibilité : ne pas utiliser de balises, seulement en ajouter de nouvelles avec optional, ne pas supprimer les champs utilisés ; réserver les numéros.
Tests : Génération de la stabilité du serveur/client, location de cas auto-génériques + négatifs (terrain unknown, size-limits).

6) Contrats d'événements (Kafka/NATS/...)

Схемы: Avro/JSON Schema/Protobuf в Schema Registry.
Politique de compatibilité : 'BACKWARD' (souvent suffisant) ou 'FULL'.
Tests du producteur : Valider le message contre le circuit ; tests consumers : accepte l'ancienne et la nouvelle version.
Invariants : clés d'idempotence, ordre/répétabilité, sémantique de déduplication.

Exemple de schéma Avro (fragment) :
json
{"type":"record","name":"PayoutCreated","fields":[
{"name":"payoutId","type":"string"},
{"name":"amount","type":"double"},
{"name":"currency","type":{"type":"string","logicalType":"iso-4217"}}
]}

7) Compatibilité et versions

Backward-compatible (minimum recommandé) : ajoutez des champs facultatifs, ne cassez pas les champs existants.
Forward-compatible : les consommateurs ignorent les champs inconnus.
Full : les deux.
Versioning : 'path (/v1)', 'Accept : application/vnd. brand. v2+json`, `proto package v2`.
Deprecation-policy : fenêtre de sortie (par exemple, 90 jours) qui avertit les titres/événements.

8) Négatifs et erreurs - c'est aussi un contrat

Normaliser les codes : 400/401/403/404/409/422/429/5xx, champs obligatoires "code", "message", "trace _ id'.
Dimensions/limites - partie du contrat (413/414/431).
Idempotence : comportement à répétition (409 vs 201 same id).
Titres : 'Retry-After' à 429/503, 'Idempotency-Key', 'Content-Language', etc.

Modèle d'erreur :
json
{ "code":"validation_error", "message":"amount must be ≥ 1", "trace_id":"..." }

9) Les données sont gérées par le contrat

Exemples/réponses d'essai (exemples) - vivants, validés dans CI.
Les fictions pour les CDC sont minimales, déterministes.
Génération de données - property-based pour les nombres/dates ; mais pas casser la stabilité des snapshots.

10) Pipline en CI/CD (référence)

1. Lint/validate: OpenAPI/Proto/Avro (`validate`, style-линер).
2. Publish : contrat en tant qu'artefact (courtier/registre).
3. Verify : le fournisseur lance les paquets CDC/tests de spécifications.
4. gate can-i-deploy : sans matrice verte, la sortie est interdite.
5. Diff : vérifie que les modifications sont compatibles (diff semantic).
6. Rapport : JUnit/HTML, liste des irrégularités/définitions.

Pseudo-matrice :
yaml jobs:
lint:...
publish-contract: needs: [lint]
verify-provider: needs: [publish-contract]
can-i-deploy:
if: always()
steps: [run: pact-broker can-i-deploy...]

11) Outils (par classe de tâche)

Lint/validateurs : openapi-linters, protobuf-lint, avro-tools.
CDC : Pact-family/broker, Spring Cloud Contract, Hoverfly (entrées/relais HTTP).
Runner de spécification : schemathesis/Dredd-like approche, Postman test + JSON Schema.
Diff : semantic-diff OpenAPI/Proto/Avro (identifie les modifications de breaking).
Conteneurs : Testontainers pour soulever le fournisseur/comptoir de contrat.

12) Anti-modèles

Spetz-dock est séparé du code → dissynchronisation. Gardez le contrat à côté du service.
Les moqueries d'un service extérieur au lieu d'un contrat → fragilité dans les updates.
Réponses aléatoires/génération sans lien avec le schéma de la flûte →.
Modifier les types/obligations des champs sans version.
Extensions silencieuses sans notification/dépréciation.
Absence de contrats négatifs et de codes d'erreur.

13) Spécificités d'iGaming/Finance

Formalisez les champs monétaires : 'amount' est un décimal à l'échelle, la monnaie est un ISO-4217, les invariants des sommes.
Contrats de paiement/webhooks : HMAC/mTLS, anti-replay ("X-Timestamp'fenêtre), idempotence," Retry-After ".
Régions/tenants : titres obligatoires « X-Tenant/X-Region », localisation des messages.
Evénements : logs immuables (audit), clés de déduplication, garanties de livraison (at least once + handler idempotent).

14) Exemples de « squelettes » de tests

14. 1 Style Schemathesis (pseudo)

bash schemathesis run openapi. yaml --checks all --hypothesis-deadline=200

14. 2 Postman comme runner de spécification

js pm. test ("Scheme/v1/wallets/{ id} is valid," () => {
const schema = pm. collectionVariables. get("wallet_get_schema");
pm. expect(ajv. validate(JSON. parse(schema), pm. response. json())). to. be. true;
});

14. 3 Provider-vérification CDC (pseudo)

bash pact-broker can-i-deploy --pacticipant wallets --version $SHA --to-environment staging

15) Chèque-liste prod-prêt

  • Contrats dans le référentiel, CI valide et publie des artefacts.
  • Le CDC est inclus pour les intégrations critiques ; le broker/matrix « can-i-deploy » fonctionne.
  • La politique d'interopérabilité (HTTP/gRPC/Events) est documentée ; semantic-diff automatique.
  • Contrats négatifs : erreurs, limites de taille, idempotence, 'Retry-After'.
  • Les données de test sont déterministes ; les snapshots d'exemples sont maintenus.
  • Versioning et deprecation : délais, notifications, titres.
  • Pour les événements - Schema Registry et mode de compatibilité ; le vendeur/consumer teste les deux versions.
  • Artefacts : JUnit/HTML, rapports diff/verify, matrice de compatibilité.
  • Procédure d'incident : rollback rapide du contrat/drapeau de ficha, notification aux intégrateurs.

16) TL; DR

Enregistrez les attentes dans les contrats et lancez-les automatiquement : CDC pour les attentes des clients, tests de spécifications pour la mise en œuvre, registre des schémas pour les événements. Gardez une politique de compatibilité stricte et des contrats négatifs (erreurs, limites, idempotence). Tu ne peux pas sortir sans green can-i-deploy matrix et semantic-diff sans breaking-change.

Contact

Prendre contact

Contactez-nous pour toute question ou demande d’assistance.Nous sommes toujours prêts à vous aider !

Telegram
@Gamble_GC
Commencer l’intégration

L’Email est obligatoire. Telegram ou WhatsApp — optionnels.

Votre nom optionnel
Email optionnel
Objet optionnel
Message optionnel
Telegram optionnel
@
Si vous indiquez Telegram — nous vous répondrons aussi là-bas.
WhatsApp optionnel
Format : +code pays et numéro (ex. +33XXXXXXXXX).

En cliquant sur ce bouton, vous acceptez le traitement de vos données.