TB
← Tüm yazılar

CI icinde test kapilari

CI pipeline'larında test kapılarının (quality gates) nasıl tasarlanacağını, eşik değerlerin belirlenmesini ve başarısızlık stratejilerini detaylı olarak inceliyoruz.

CI pipeline'ı yalnızca kodu derleyen bir otomasyon değildir; kalite kapıları (quality gates) ile hatalı değişikliğin ana dala ve üretime ulaşmasını engelleyen savunma hattıdır. Kapısız pipeline hızlı görünür ama teknik borcu sessizce biriktirir. CI içinde test kapıları doğru tasarlandığında ekip hızlanır; yanlış tasarlandığında geliştiriciler kapıları bypass etmeye başlar.

Test kapısı nedir?

Test kapısı, pipeline'ın belirli aşamasında tanımlı eşik veya koşul sağlanmadığında ilerlemeyi durduran kontrol noktasıdır. Kapı geçilemezse merge veya deploy yapılmaz. Kapılar kod kalitesi, güvenlik, performans ve test sonuçlarına uygulanabilir.

  • Hard gate: koşul sağlanmazsa pipeline durur, override yok
  • Soft gate: uyarı verir, manuel onay ile geçilebilir
  • Scheduled gate: nightly/full suite; PR'da hafif subset

Kapı tasarım ilkeleri

İyi kapı hızlı geri bildirim verir, false positive oranı düşüktür ve başarısızlık mesajı eyleme dönükür. "Test failed" yerine "OrderServiceTests.CreateOrder_InvalidAmount: Expected 400, got 500" mesajı geliştiricinin dakikalar içinde düzeltmesini sağlar.

Fail fast

En hızlı ve en ucuz kontroller önce çalışmalıdır: lint, format check, birim test. Entegrasyon test ve E2E sonra gelir. Lint 30 saniyede kırılıyorsa 15 dakikalık entegrasyon testinin bitmesi beklenmez.

Tipik PR pipeline kapıları

  1. Statik analiz: linter, formatter, compiler warning threshold
  2. Birim test: tüm testler geçmeli, süre eşiği aşılmamalı
  3. Diff coverage: yeni kod minimum %80 kapsama
  4. Entegrasyon test: kritik senaryolar (Testcontainers ile)
  5. Güvenlik taraması: dependency vulnerability, SAST
  6. Contract test: tüketici sözleşmeleri doğrulanmış

Eşik değer belirleme

Eşik değerler veriye dayanmalıdır. Mevcut ortalama pipeline süresi, flaky test oranı ve bug escape rate analiz edilir. Eşik ani sıkılaştırılırsa ekip bypass kültürü oluşur; çok gevşek bırakılırsa kapı anlamsızlaşır.

quality_gate:
  unit_tests:
    pass_rate: 100%
    max_duration: 8m
  coverage:
    diff_line: 80%
    diff_branch: 75%
  integration:
    pass_rate: 100%
    max_duration: 20m
  flaky:
    max_retry: 2
    quarantine_threshold: 3 failures / 7 days

Flaky test yönetimi kapısı

Flaky testler kapı güvenilirliğini yok eder. Geliştirici "CI yine rastgele kırıldı" dediğinde kapıya güven azalır. Flaky test tespit edildiğinde quarantine listesine alınır: test hâlâ çalışır ama kapıyı kırmaz; ayrı ticket açılır ve düzeltme SLA'si uygulanır.

Retry stratejisi

Kontrollü retry yalnızca E2E testlerde ve maksimum 2 kez uygulanır. Birim test retry anlamsızdır; gerçek hata gizlenir. Retry sayısı metrik olarak izlenir; artış trendi altyapı veya test sorununa işaret eder.

Branch protection entegrasyonu

GitHub/GitLab branch protection, CI kapıları ile birleştiğinde etkili olur. "Require status checks to pass" ayarı ile belirli job adları merge ön koşulu yapılır. Admin bypass kapalı tutulur; acil durum prosedürü ayrı tanımlanır.

Ortam bazlı kapılar

PR pipeline hafif kapılar içerir; staging deploy öncesi tam suite çalışır; production deploy öncesi can-i-deploy ve smoke test kapısı devreye girer. Aynı ağır test her commit'te çalıştırılmaz; risk seviyesine göre katmanlı kapı uygulanır.

Deploy kapısı örneği

deploy_production:
  needs: [integration, contract_verify, security_scan]
  rules:
    - if: $CI_COMMIT_TAG
  script:
    - pact-broker can-i-deploy ...
    - ./deploy.sh production
    - ./smoke-test.sh production

Başarısızlık stratejileri

Kapı kırıldığında ne olacağı önceden bellidir. Otomatik bildirim PR yorumuna test özeti ekler. Blame culture yerine "kapı seni yavaşlatmak için değil, üretim olayını önlemek için var" mesajı kültürde yer eder.

  • Anında PR yorumu: hangi test, hangi satır, hangi assertion
  • Slack bildirimi yalnızca main branch kırılmasında
  • Flaky şüphesi varsa otomatik rerun log'a işlenir
  • Kapı bypass audit log'a kaydedilir, gerekçe zorunlu

Performans regresyon kapısı

Benchmark testleri CI'da ayrı job olarak çalışır. Önceki baseline ile karşılaştırma yapılır; %10'dan fazla yavaşlama kapıyı kırar. Benchmark ortamı izole tutulur; paylaşımlı runner gürültüsü false positive üretir.

Güvenlik kapıları

Dependency vulnerability scan (Dependabot, Snyk) critical CVE bulduğunda hard gate tetikler. SAST araçları güvenlik açığı pattern'i tespit eder. Secret scanning commit'te API key bulursa push reddedilir. Güvenlik kapıları test kapıları kadar otomatik olmalıdır.

Kapı metrikleri

Kapı etkinliğini ölçmek için: merge öncesi yakalanan hata oranı, kapı bypass sayısı, ortalama pipeline süresi, flaky oranı, bug escape rate (üretime kaçan hata). Kapı süresi 45 dakikayı aşıyorsa geliştirici paralel iş yapar ve geri bildirim döngüsü uzar; optimizasyon gerekir.

Anti-pattern'ler

  1. Çok fazla hard gate: pipeline 1 saat sürer, ekip merge'i geciktirir
  2. Kapı bypass kültürü: admin her acilde override eder, kural ölür
  3. Anlamsız eşik: %100 coverage zorunluluğu sahte test üretir
  4. Test olmadan kapı: coverage var ama assertion kalitesi kontrol edilmez
  5. Ortam tutarsızlığı: CI geçer, staging'de aynı test kırılır

Olgunluk seviyeleri

Seviye 1: yalnızca birim test kapısı. Seviye 2: coverage + lint. Seviye 3: entegrasyon + contract. Seviye 4: performans + güvenlik + can-i-deploy. Ekipler mevcut seviyeden bir üstüne sprint bazında tırmanır; bir gecede Seviye 4 hedeflenmez.

Pipeline süresi optimizasyonu

Kapı sayısı arttıkça pipeline süresi uzar. Cache stratejisi: NuGet/npm restore cache, Docker layer cache, test sonuç cache (değişmeyen modül testleri skip). Test impact analysis: yalnızca değişen modülün testleri PR'da çalışır; full suite nightly'de koşar. Bu hibrit model hız ve güven dengesini korur.

Test verisi ve kapı izolasyonu

Entegrasyon testlerinde paylaşılan test veritabanı kapı flakyliği yaratır. Her pipeline job izole schema veya container kullanmalıdır. Testcontainers ile job başına PostgreSQL instance oluşturmak izolasyon sağlar. Paralel job'lar aynı veritabanını paylaşmaz.

Notification ve görünürlük

Kapı kırıldığında geliştiriciye anında PR yorumu eklenir. Main branch kırılması Slack incident kanalına düşer. Haftalık kalite raporu: kapı pass rate, ortalama süre, flaky sayısı, bypass sayısı. Trend düşüşte kapı eşikleri değil altyapı ve test sağlığı incelenir.

Paralel test execution

Kapı süresini kısaltmak için testler paralel shard'lara bölünür. xUnit collection, Playwright shard ve pytest-xdist aynı prensibi uygular. Shard sayısı runner kapasitesiyle sınırlıdır; aşırı paralellik veritabanı lock çakışması yaratabilir. Entegrasyon testlerinde Testcontainers instance'ları shard başına izole tutulur.

Kapı bypass ve acil durum

Acil hotfix senaryosunda kontrollü bypass tanımlanır: incident ticket numarası, onaylayan kişi ve 24 saat içinde kalıcı fix zorunluluğu. Bypass audit log'da kalıcıdır; retrospektifte neden kapı atlandığı incelenir. Sık bypass kapı tasarımının yanlış olduğuna işaret eder.

CI test kapıları, yazılım kalitesini kişisel disipline değil sisteme bağlar. Doğru eşik, hızlı geri bildirim ve flaky yönetimi ile kapılar geliştirici deneyiminin parçası haline gelir. Amaç merge'i engellemek değil, güvenle merge etmektir.

Monorepo kapı stratejisi

Monorepo'da yalnızca etkilenen paketlerin testleri PR kapısında çalıştırılır. Path filter ile değişmeyen servis testleri skip edilir. Full monorepo test suite nightly ve release branch'te koşar. Bu model 200+ servisli repolarda PR süresini 15 dakikanın altında tutar.

Kapı sahipliği

Her kalite kapısının sahibi bellidir: birim test geliştirici ekibi, E2E QA, güvenlik AppSec, performans platform. Kapı kırılması ilgili sahip kanalına düşer. Sahipsiz kapılar güncellenmez ve ekip güvenini kaybeder.

Artifact ve test raporu saklama

Kapı sonuçları yalnızca geçti/kaldı değil; JUnit XML, coverage HTML ve screenshot artefakt olarak saklanır. Başarısız PR bir hafta sonra yeniden incelendiğinde artefakt kök neden analizini hızlandırır.