GH GambleHub

Tests contractuels

1) Où appliquer les contrats

HTTP REST/JSON : ressources, pagination, filtres, idempotence, codes d'erreur.
gRPC/Protobuf : types de messages, états, sémantique 'deadline', backward-compat v.proto.
GraphQL : schémas, non null, directives, permishen par champ.
Messages/strimes (Kafka/Pulsar/SQS) : schémas d'événements (Avro/JSON/Protobuf), clés de lot, ordre, clés idempotent.
SDK/bibliothèques internes : fonctions publiques/exclusions/contrats de performance.


2) Modèle CDC : rôles et artefacts

Le consommateur publie un contrat d'attente (demandes/réponses approximatives, types de match, invariants).
Le fournisseur lance la vérification des contrats contre son service/adaptateur/handler 's.
Le courtier de contrats (Pact Broker/Backstage/artefact-repo) stocke les versions, les balises ('prod',' staging ',' canary ') et la matrice de compatibilité' consumer @ v → provider @ v '.
Politique de libération : Le fournisseur de dégagement est interdit si tout contrat « pro-pertinent » est violé.


3) Que fixer dans le contrat (exemple HTTP)

Minimum :
  • Méthode/chemin/paramètres/en-têtes (y compris auth, clé idempotent).
  • Corps et matchers types (type/format/regexp/fourchettes).
  • Codes et structure des erreurs ; stable 'error _ code'.
  • Invariants sémantiques : tri, unicité, monotonie de 'created _ at'.
  • Attentes non fonctionnelles (en option) : p95, limites de taille, en-têtes rate-limit.
Fragment de contrat (simplifié) :
json
{
"interaction": "GET /v1/users/{id}",
"request": { "method": "GET", "path": "/v1/users/123", "headers": {"Accept":"application/json"} },
"matchers": {
"response.body.id": "type:number",
"response.body.email": "regex:^.+@.+\\..+$",
"response.body.created_at": "format:rfc3339"
},
"response": {
"status": 200,
"headers": {"Content-Type":"application/json"},
"body": {"id": 123, "email": "alice@example.com", "created_at": "2025-10-31T12:00:00Z"}
},
"error_cases": [
{
"name":"not_found",
"request":{"path":"/v1/users/9999"},
"response":{"status":404, "body":{"error_code":"USER_NOT_FOUND"}}
}
]
}

4) Contrats pour événements (event-driven)

Schéma de l'événement : 'type', 'version', 'id', 'occurred _ at _ utc', 'producteur', 'subject', 'payload'.
Invariants : invariance "id'et idempotence par" (type, id) ", ordre à l'intérieur de la clé de lot, monotonie" sequence ".
Schema Registry : stocke l'évolution et les règles de compatibilité (backward/forward/full).
Contrats-tests consumer : Relier les événements « or » et les phases négatives (champs inconnus, nullables).

Exemple de schéma Avro (fragment) :
json
{
"type":"record","name":"UserRegistered","namespace":"events.v1",
"fields":[
{"name":"id","type":"string"},
{"name":"occurred_at_utc","type":{"type":"long","logicalType":"timestamp-millis"}},
{"name":"email","type":"string"},
{"name":"marketing_opt_in","type":["null","boolean"],"default":null}
]
}

5) Évolution et compatibilité

Versions des contrats : sémantique 'MAJOR. MINOR. PATCH '(MAJOR - cassant).

Règles pour REST :
  • Ne cassez pas : ne supprimez pas les champs, ne changez pas le type/la valeur 'error _ code'.
  • Ajouter les champs optionnels en défaut ; de nouveaux endpoints au lieu de la « magie ».
  • Dépréciation : annonce, support parallèle, suppression par métriques.
  • GraphQL : champs à ajouter uniquement, non null à entrer par phases ; directives de dépréciation.
  • gRPC/Proto : ne pas réutiliser les numéros de champ ; n'ajouter que de nouveaux avec l'option.
  • Events : circuit « vN » ; les consumers sont obligés d'ignorer les champs inconnus (léninité).

6) Contrôles négatifs et invariants

Negative : types incorrects, valeurs interdites, paramètres de conflit, dépassement des limites.
Invariants : tri des réponses, unicité de 'id', exactitude de 'next _ cursor', stabilité de la réponse idempotente à répétition.
Contrats d'aspects temporaires : 'created _ at' RFC3339/UTC, la projection correcte de la journée locale ne fait pas partie du contrat de transport - est présentée aux invariants d'affaires.


7) Production et développement local

Des meutes de fournisseurs sont générées à partir des contrats pour le développement du consommateur.
Pour les événements - générateurs de messages « valides/frontières » selon le schéma.
Les meutes sont marquées de la version du contrat et de la date d'assemblage ; la publication en prod est interdite.


8) Incorporation dans CI/CD (Pipline de référence)

1. Consumer CI:

Lint/building → génération de contrats → tests unitaires/contractuels → publication dans contract-broker (tag : 'consumer @ 1. 7. 0`).

2. Provider CI:

L'augmentation du service local/dans le conteneur → le fatch des contrats pertinents ('prod'/' staging') → la vérification → la publication du statut dans le broker.

3. Release Gate:

Le fournisseur est bloqué s'il y a des contrats en suspens.

4. Nightly Matrix:

Matrice de compatibilité 'consumer versions × provider versions' ; rapports et alarmes.


9) Exemples de pratiques par domaine

9. 1 REST : pagination par les cadets (invariant contractuel)

La réponse contient 'items []', 'next _ cursor' (nullable), 'limit', 'total' (facultatif).
Invariants : 'len (items) ≤ limit', rappel avec le même 'cursor' → jeu idempotent.
Erreur si 'cursor' et 'page' sont définis simultanément.

9. 2 Idempotence POST

Le contrat nécessite le titre 'Idempotency-Key'.
Invariant : une requête répétée avec la même clé renvoie le même "id'/état.

9. 3 Événements : garanties d'ordre

Clé de lot dans le contrat : 'partition _ key = user_id'.
Invariant : « sequence » augmente monotonalement à l'intérieur de la clé ; le consumer est tenu de traiter les répétitions.


10) Sécurité et vie privée dans les contrats

Ne pas inclure les PDn/secrets dans les exemples - seulement les synthétiques.
Fixer les titres de sécurité obligatoires : 'Autorisation', 'X-Signature', 'Replay-Prevention'.
Pour les webhooks, un contrat de signature et de réponse « 2xx »/rétroactifs.
Dans les logs de test de contrat, masquer les champs sensibles.


11) Outils

Pact/Pactflow/Pact Broker - contrats HTTP/Message, matrice de compatibilité.
OpenAPI/AsyncAPI - Spécifications + générateurs de test (Dredd, Schemathesis).
Karate/REST Assured - Vérifications de scénarios des contrats REST.
Protobuf/gRPC - 'buf', 'protolint', tests de compatibilité ; Schema Registry pour Avro/JSON/Proto dans les flux.
Tests de conformité pour GraphiqueQL (graphql-compat), tests de schéma snapshot.


12) Pseudo-code de vérification du fournisseur (simplifié)

python def verify_contract(provider, contract):
for case in contract["cases"]:
req = build_request(case["request"])
res = provider.handle(req) # локально/контейнер assert match_status(res.status, case["response"]["status"])
assert match_headers(res.headers, case["response"].get("headers", {}))
assert match_body(res.body, case["matchers"], allow_extra_fields=True)
for neg in contract.get("error_cases", []):
res = provider.handle(build_request(neg["request"]))
assert res.status == neg["response"]["status"]
assert res.json.get("error_code") == neg["response"]["body"]["error_code"]

13) Anti-modèles

« Les captures d'écran Postman sont un contrat » : aucune version/type de match/validation automatique.
Oversneiping : le contrat enregistre des valeurs exactes au lieu de types/patterns → de fausses chutes.
Un contrat commun pour différentes régions/canaux : ignore la variabilité (drapeaux, geo-règles).
Contrats sans courtier/matrice : vous ne pouvez pas comprendre quelles versions sont compatibles.
Parier sur e2e au lieu de contrats : lent, cher, instable.
Absence de cas négatifs/invariants : seule la « piste verte » est testée.


14) Observabilité et exploitation

Exporter le statut de broker + dashboard « contrats de santé ».
Alertie : nouvelles chutes du fournisseur contre les "prod' -contracts, croissance du" unknown field "dans les événements.
Trace : 'contract _ id', 'version', 'decision _ id' dans les logs de vérification.


15) Le processus de dépréciation

1. Ajouter un champ/endpoint (non cassant).
2. Marquer l'ancien comme « deprecated » dans la spécification, déclarer les délais.
3. Suivre les consommateurs par logue/courtier ; les hydes migratoires.
4. Inclure « shadow » deny dans le steadge (dry-run), puis enforce.
5. Supprimer après zéro utilisation et confirmation de compatibilité.


16) Chèque de l'architecte

1. Les consommateurs et leurs propriétaires ont-ils été identifiés ? Les contrats sont-ils versionnés ?
2. Y a-t-il un broker et une matrice de compatibilité avec les balises d'environnement ?
3. Le contrat comprend les négatifs et les invariants (idiempotentialité, curseurs, triage) ?
4. Schema Registry et le mode de compatibilité sont-ils configurés pour les événements ?
5. Pipline bloque-t-il la sortie du fournisseur en cas de violation des contrats ?
6. Le processus de dépréciation et la politique d'évolution sont décrits ?
7. Des meutes de contrats sont générées, y a-t-il des générateurs d'événements locaux ?
8. Masque PA et titres de sécurité obligatoires documentés ?
9. Métriques/alertes contractuelles connectées, avez-vous des rapports de dérive ?
10. Les contrats sont vérifiés par CI auprès des deux parties (consommateur et fournisseur) ?


Conclusion

Les tests contractuels transfèrent la « vérité » sur les interactions aux artefacts versionables et rendent les intégrations prévisibles. Les CDC, le courtier contractuel et la discipline de l'évolution des régimes remplacent les « surprises cassantes » par un processus gérable : vérifications rapides, invariants clairs et interopérabilité transparente des versions. Cela réduit le coût e2e, accélère les sorties et améliore la qualité de l'ensemble de la plate-forme.

Contact

Prendre contact

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

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.