CI/CD Pipeline'ım 3 Ay Boyunca Başarılı Oldu — Sonra Logları Okudum
Yeşil onay işaretleri iyi hissettirir. Her pull request geçti. Her deploy çalıştı.
Sonra bir kullanıcı bozuk bir özellik bildirdi. Haftalardır bozuktu.
Pipeline loglarını açtım. Başarılı olan build'lerimiz bize yalan söylemişti.
Sürecimiz kusursuz görünüyordu:
- Linting
- Unit testler
- Entegrasyon testleri
- Build
- Deploy
Her adım aylarca %100 başarı oranına sahipti.
Dışa aktar (export) butonuna tıklandığında hiçbir şey olmuyordu. Hiçbir hata görünmüyordu. Sorunu 11 hafta önceki bir değişikliğe kadar takip ettim. Pipeline geçmişti. Kod incelemesi (code review) onaylanmıştı. Özellik en başından beri bozuktu.
Sorun kodumuz değildi. Test kodumuzdu.
Entegrasyon testlerimiz her şey için mock kullanıyordu. Tüm export servisini mock'lamıştık. Test, gerçek kod yerine mock'u kontrol ediyordu. Mock her zaman başarılı bir durum (success status) döndürüyordu.
Aşırı mock'lama (over-mocking) tuzağına düştük:
- Unit testler: Birimi izole etmek için her şeyi mock'ladık. Bu sorun değil.
- Entegrasyon testleri: Hız için her şeyi mock'ladık. Bu bir hata.
- E2E testleri: Bu özel akışı kaçırdık.
Entegrasyon testlerimiz sadece maliyetli unit testlerden ibaretti. Mock'larımızın çalışıp çalışmadığını doğruluyorlardı. Kodumuzun çalışıp çalışmadığını doğrulamıyorlardı.
Bunu düzeltmek için üç değişiklik yaptım:
Mock'ları unit testlerle sınırlayın. Entegrasyon testleri gerçek veritabanlarına, API'lere ve dosya sistemlerine erişmelidir. Eğer bir test yavaşsa, onu bir mock ile gizlemeyin. Bu hızı bir optimizasyon sinyali olarak kullanın.
Contract testleri ekleyin. Bunlar, mock'larınızın gerçek servis davranışı ile eşleşmesini sağlar. Eğer bir mock, gerçek bir servisin döndürmeyeceği bir veri döndürürse, contract testi başarısız olur.
Gerçek kapsamı (coverage) takip edin. Basit başarı oranlarına bakmayı bıraktık. Testlerin gerçekte neleri çalıştırdığına baktık. Coverage oranlarımız %94'ten %67'ye düştü. Bu, sahip olduğumuz en dürüst metrikti.
Yeşil bir pipeline, kodunuzun çalıştığı anlamına gelmez. Testlerinizin geçtiği anlamına gelir. Bunlar farklı şeylerdir.
En tehlikeli hatalar, pipeline'ınızın "sorun yok" dediği hatalardır.
Kendinize şu soruları sorun:
- Testlerim hataları mı yakalıyor yoksa sadece mock'ları mı onaylıyor?
- Entegrasyon testlerim gerçekten entegre oluyor mu?
- Tüm mock'ları kaldırırsam kaç test hala geçer?
- Kapsamı (coverage) mı yoksa güveni (confidence) mi ölçüyorum?
Hiç hata vermeyen bir pipeline güvenilir değildir. Test edilmemiştir.
Kaynak: https://dev.to/kollittle/my-cicd-pipeline-passed-for-3-months-then-i-read-the-logs-4mbj
