⚠️ F5 · Contract Defect'leri
F5 · Contract Defect'leri: Bir contract defect, F1'de öğrendiğin "mimari çizim" analojisine geri döner: çizimde "bu oda 20 metrekare" yazarken gerçekte 15 metrekare olması gibi —
Bir contract defect, F1'de öğrendiğin "mimari çizim" analojisine geri döner: çizimde "bu oda 20 metrekare" yazarken gerçekte 15 metrekare olması gibi — bina (kod) ÇALIŞIYOR, çizim (spec) de VAR, ama ikisi birbirini YALANLIYOR. F2'de gördüğün otomatik üretim bu riski AZALTIR ama SIFIRLAMAZ: spec üretilirken bile bir geliştirici yanlış bir `@ApiResponse` annotation'ı yazabilir, veya spec elle düzenlendiyse kod değişince güncellenmemiş olabilir. Peki bu neden özellikle SİNSİ bir defect kategorisidir — normal bir fonksiyonel bug'dan farkı ne? Çünkü UI'daki manuel test veya fonksiyonel bir otomasyon testi genelde SADECE "request başarılı mı?" sorar, "response tam olarak DOKÜMANDAKİ ŞEKİLDE mi?" sorusunu SORMAZ — bu yüzden bir contract defect, aylarca fark edilmeden production'da yaşayabilir, ta ki spec'e güvenen bir mobil uygulama veya üçüncü taraf entegrasyonu YANLIŞ varsayımla çökene kadar. Java'da bunun karşılığı, bir `interface`'in JavaDoc'unun kodla senkronize kalmaması gibidir — derleyici bunu YAKALAMAZ, çünkü JavaDoc derlemenin bir parçası değildir; tıpkı bir spec'in "derlemenin" (build'in) bir parçası olmasına rağmen İÇERİĞİNİN doğruluğunun ayrıca test EDİLMESİ gerektiği gibi. QA açısından contract testing, tam olarak bu boşluğu kapatan disiplindir.
4 Gerçek Contract Defect Senaryosu
Doküman Diyor ki... — Gerçek API Diyor ki...
**1. Status Kodu Uyumsuzluğu** — Spec `POST /api/v1/bugs` için `200` döndüğünü söyler, ama gerçek API `201 Created` döner. **Kök neden:** geliştirici kod tarafında doğru pratiğe (`201` = oluşturma) geçmiş ama spec'i güncellemeyi UNUTMUŞ. **Tester nasıl yakalar:** Swagger UI'da `Try it out` ile gerçek request'i çalıştırıp dönen status kodunu dokümandaki ile birebir karşılaştırarak.
**2. Enum Drift** — Spec `severity` için `[LOW, MEDIUM, HIGH]` üç değer listeler, ama geliştirici kod tarafına yeni bir `CRITICAL` değeri EKLEMİŞ ve spec'e YANSITMAMIŞ. **Kök neden:** enum bir Java/TS sabitler listesinde kolayca genişletilebilir ama spec'teki karşılığı elle güncellenmesi gereken AYRI bir liste. **Tester nasıl yakalar:** gerçek response'larda dokümanda OLMAYAN bir değer görerek, veya negatif testte "CRITICAL reddedilmeli" beklerken kabul edildiğini fark ederek.
**3. Required Yalanı** — Spec `reporter` alanını `required` listesinde gösterir, ama gerçek API bu alan OLMADAN gönderilen bir request'i de kabul edip `201` döner. **Kök neden:** backend'deki doğrulama kuralı (`@NotBlank`/`@IsNotEmpty`) ya hiç yazılmamış ya da bir yerde SESSİZCE devre dışı (bkz. B1/D3'teki eksik pipe/starter defect'leri) — spec doğru yazılmış ama koddaki GERÇEK davranış farklı. **Tester nasıl yakalar:** "zorunlu" işaretli her alanı bilerek BOŞ bırakarak deneyip 400 yerine 201 alındığında.
**4. Alan Tipi Uyumsuzluğu** — Spec `createdAt` alanının `type: string, format: date-time` (ISO-8601, örn. `2026-07-24T10:00:00Z`) olduğunu söyler, ama gerçek API bunu bir UNIX timestamp sayısı (`1753350000`) olarak döner. **Kök neden:** backend'de serialization ayarı değişmiş (örn. farklı bir JSON kütüphanesi/konfigürasyon) ama spec bu değişikliği YAKALAMAMIŞ. **Tester nasıl yakalar:** gerçek response'ta bir alanın TİPİNİ (string mi sayı mı) spec'teki `type`/`format` ile birebir karşılaştırarak — özellikle spec'e güvenerek otomatik parse eden bir istemci (mobil uygulama) bu farkta ÇÖKER.
Geliştirici kodu değiştirdi
Gerçek API: 201 dönüyor
Mobil uygulama dokümana güveniyor
Tester ayrışmayı yakalar
Doküman aylarca doğruydu: `POST /api/v1/bugs` başarıyla `200` döner diyordu, ve öyleydi.
Bir geliştirici kodu "doğru pratiğe" (`201 Created`) taşır — ama spec'i güncellemeyi UNUTUR.
Gerçek API artık `201` dönüyor — ama doküman HÂLÂ `200` diyor. Sözleşme SESSİZCE bozuldu.