Müqavilə testi
1) Müqavilələri harada tətbiq etmək olar
HTTP REST/JSON: resurslar, paginasiya, filtrlər, idempotentlik, səhv kodları.
gRPC/Protobuf: mesaj növləri, statuslar, semantika 'deadline', backward-compat v.proto.
GraphQL: sxemlər, qeyri-null, direktivlər, sahələrə permishen.
Mesajlar/axınlar (Kafka/Pulsar/SQS): hadisə sxemləri (Avro/JSON/Protobuf), partizan açarları, sifariş, idempotent açarları.
Daxili SDK/kitabxanalar: ictimai funksiyalar/istisnalar/performans müqavilələri.
2) CDC modeli: rollar və artefaktlar
İstehlakçı gözləntilər müqaviləsini dərc edir (təxmini sorğular/cavablar, növ matçları, invariantlar).
Təchizatçı öz xidmətinə/adapterinə/handlerlərinə qarşı müqavilələrin təsdiqini qaçırır.
Müqavilə brokeri (Pact Broker/Backstage/artefakt-repo) versiyaları, etiketləri ('prod', 'staging', 'canary') və 'consumer @v → provider @v' uyğunluq matrisini saxlayır.
Buraxılış siyasəti: Hər hansı bir «prod-müvafiq» müqavilə pozulursa, provayderin deplosu tərəfindən qadağan edilir.
3) Müqavilədə qeyd etmək nədir (HTTP nümunəsi)
Minimum:- Metod/yol/parametrlər/başlıqlar (daxil auth, idempotent açarı).
- Bədən və tipik matchers (tip/format/regexp/diapazonlar).
- Kodlar və səhv strukturu; sabit 'error _ code'.
- Semantik invariantlar: çeşidləmə, unikallıq, monotonluq 'created _ at'.
- Qeyri-funksional gözləntilər (isteğe bağlı): p95, ölçü limitləri, rate-limit başlıqları.
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) Hadisələr üçün müqavilələr (event-driven)
Hadisə sxemi: 'type', 'version', 'id', 'occurred _ at _ utc', 'producer', 'subject', 'payload'.
İnvariantlar: 'id' dəyişməzliyi və '(type, id)' idempotentliyi, partisiyanın açarı daxilində nizam, 'sequence' monotonluğu.
Schema Registry: təkamül və uyğunluq qaydalarını saxlayır (backward/forward/full).
Konsumer kontrakt testləri: «qızıl» hadisələri və mənfi fazaları (naməlum sahələr, nullable) təkrarlayın.
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) Təkamül və uyğunluq
Müqavilələrin versiyaları: MAJOR semantikası. MINOR. PATCH '(MAJOR - qırıcı).
REST üçün qaydalar:- Sındırmayın: sahələri silməyin, 'error _ code' növünü/dəyərini dəyişdirməyin.
- Variant sahələri əlavə edin; «sehr» əvəzinə yeni endpointlər.
- Deprekasiya: reklam, paralel dəstək, metrik silinmə.
- GraphQL: sahələr yalnız əlavə etmək, fazalar vasitəsilə qeyri-null daxil; deprekasiya direktivləri.
- gRPC/Proto: sahə nömrələrini yenidən istifadə etməyin; yalnız optional ilə yenisini əlavə edin.
- Events: 'vN' sxemi; konsumerlər naməlum sahələrə məhəl qoymamalıdırlar.
6) Mənfi və invariant yoxlamalar
Negative: səhv tiplər, qadağan dəyərlər, münaqişə parametrləri, limitləri aşmaq.
Invariants: cavabların çeşidlənməsi, 'id' unikallığı, 'next _ cursor' düzgünlüyü, təkrar edildikdə idempotent cavabın sabitliyi.
Müvəqqəti aspektlərin müqavilələri: 'created _ at' RFC3339/UTC, yerli günün düzgün proyeksiyası nəqliyyat müqaviləsinin bir hissəsi deyil - biznes invariantlarına verilir.
7) Stab-generasiya və yerli inkişaf
Müqavilələrdən provayderin istehlakçını inkişaf etdirmək üçün stabları yaranır.
Hadisələr üçün - sxem üzrə «valid/sərhəd» mesajlarının generatorları.
Yığımlar müqavilənin versiyası və yığılma tarixi ilə qeyd olunur; Prod nəşr qadağandır.
8) CI/CD inteqrasiya (referans-paypline)
1. Consumer CI:
Lint/montaj → müqavilələrin yaradılması → birlik/müqavilə testləri → contract-broker-də dərc (tag: 'consumer @ 1. 7. 0`).
2. Provider CI:
Xidmətin yerli/konteynerdə qaldırılması → müvafiq müqavilələrin fetç edilməsi ('prod '/' staging') → yoxlama → broker statusunun dərc edilməsi.
3. Release Gate:
Yerinə yetirilməmiş müqavilələr varsa, provayder deploy bloklanır.
4. Nightly Matrix:
Uyğunluq matrisi 'consumer versions × provider versions'; hesabatlar və narahatlıqlar.
9) Domen təcrübəsi nümunələri
9. 1 REST: kursorlarla paginasiya (müqavilə invariantı)
Cavabda 'items []', 'next _ cursor' (nullable), 'limit', 'total' (isteğe bağlı) var.
İnvariantlar: 'len (items) ≤ limit', eyni 'cursor' → idempotent dəsti ilə təkrar zəng.
'cursor' və 'page' eyni vaxtda təyin edildikdə səhv.
9. 2 POST idempotentliyi
Müqavilə 'Idempotency-Key' başlığı tələb edir.
İnvariant: Eyni açarla təkrar sorğu eyni 'id '/statusu qaytarır.
9. 3 Hadisələr: Sifariş zəmanəti
Müqavilədə partizan açarı: 'partition _ key = user_id'.
İnvariant: «sequence» açar daxilində monoton olaraq artır; konsumer təkrar emal etmək məcburiyyətindədir.
10) Müqavilələrdə təhlükəsizlik və məxfilik
PD/sirləri nümunələrə daxil etməyin - yalnız sintetik.
Məcburi təhlükəsizlik başlıqlarını qeyd edin: 'Authorization', 'X-Signature', 'Replay-Prevention'.
Vebhuk üçün - '2xx '/retray imza və cavab müqaviləsi.
Test müqaviləsi - həssas sahələrin maskalanması.
11) Alətlər
Pact/Pactflow/Pact Broker - HTTP/Message müqavilələri, uyğunluq matrisi.
OpenAPI/AsyncAPI - spesifikasiyalar + test generatorları (Dredd, Schemathesis).
Karate/REST Assured - REST müqavilələrinin ssenari yoxlamaları.
Protobuf/gRPC - 'buf', 'protolint', uyğunluq testləri; Avro/JSON/Proto üçün Schema Registry.
GraphQL (graphql-compat) üçün Conformance testlər, snapshot test sxemləri.
12) Provayderin saxta yoxlama kodu (sadələşdirilmiş)
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-nümunələr
«Postman ekran görüntüləri müqavilədir»: heç bir versiya/tipik matç/avtomatik validasiya yoxdur.
Oversneiping: müqavilə növləri/nümunələri → yanlış düşmə əvəzinə dəqiq dəyərləri qeyd edir.
Müxtəlif bölgələr/kanallar üçün bir ümumi müqavilə: dəyişkənliyə məhəl qoymur (bayraqlar, geo-qaydalar).
Broker/matris olmadan müqavilələr: hansı versiyaların uyğun olduğunu anlamaq olmaz.
Müqavilələr əvəzinə e2e bahis: yavaş, bahalı, qeyri-sabit.
Mənfi/invariant halların olmaması: yalnız «yaşıl yol» sınaqdan keçirilir.
14) Müşahidə və istismar
Broker + dashboard «sağlamlıq müqavilələri» statusu ixrac.
Alertlər: provayderin 'prod' müqavilələrinə qarşı yeni enişləri, hadisələrdə «unknown field» artımı.
Tracking: 'contract _ id', 'version', 'decision _ id' doğrulama loqlarında.
15) Deprekasiya prosesi
1. Sahə/end point əlavə edin (qırılmaz).
2. köhnə kimi qeyd 'deprecated' spesifikasiya, son tarixləri elan.
3. Log/broker vasitəsilə istehlakçıları izləmək; miqrasiya qaydaları.
4. «Kölgə» deny steyj (dry-run), sonra enforce.
5. Sıfır istifadə payından və uyğunluq təsdiqindən sonra sil.
16) Memarın yoxlama siyahısı
1. İstehlakçılar və onların sahibləri müəyyən edilib? Müqavilələr versiya olunur?
2. Broker və media etiketləri ilə uyğunluq matrisi var?
3. Müqaviləyə neqativlər və invariantlar (idiempotentlik, kursorlar, çeşidləmə) daxildir?
4. Hadisələr üçün xüsusi Schema Registry və uyğunluq rejimi?
5. Paypline prod müqavilələri pozulduqda provayderin buraxılışını bloklayır?
6. Deprekasiya prosesi və təkamül siyasəti təsvir olunur?
7. Müqavilələrdən bloklar yaradılır, yerli hadisə generatorları varmı?
8. PD maskalanması və məcburi təhlükəsizlik başlıqları sənədləşdirilib?
9. Müqavilələr üzrə metriklər/alertlər bağlıdır, drift hesabatları varmı?
10. Müqavilələr CI-də hər iki tərəfdə yoxlanılır (consumer və provider)?
Nəticə
Müqavilə testləri qarşılıqlı əlaqələrin «həqiqətini» versiyalaşdırıla bilən artefaktlara köçürür və inteqrasiyanı proqnozlaşdırıla bilən edir. CDC, broker müqavilələri və intizam təkamül sxemləri idarə olunan proses üçün «pozucu sürprizləri» əvəz edir: sürətli yoxlamalar, aydın invariantlar və şəffaf versiyaların uyğunluğu. Bu e2e dəyərini azaldır, buraxılışları sürətləndirir və bütün platformanın keyfiyyətini yaxşılaşdırır.