Ana Sayfa / Blog / Test coverage yüzde 80: mit mi gerçek mi?

Test coverage yüzde 80: mit mi gerçek mi?

Yüzde 80 coverage hedefi sektörde kural gibi kabul ediliyor. Birkaç projede hem yüzde 95'i hem yüzde 30'u gördüm, anlattıklarım farklı.

Bir ajansta çalıştığım dönemde, kabul kriterlerinden biri coverage’ın yüzde 80’in üzerinde olmasıydı. Numarayı tutturmak için kod yazıyorduk. Yüzde 79 olursa pipeline kırmızı olurdu, yüzde 81 olsa deploy geçerdi. Geçtikten sonra prod’da bug çıkıyordu, çünkü yazdığımız testler çalıştırılan satırları ölçüyordu, o satırların doğru davrandığını değil.

Yüzde 80 rakamı bir efsaneye dönüşmüş durumda. Nereden geldiği bile belli değil. Büyük ihtimalle Martin Fowler’ın bir yazısındaki spekülatif yorumdan ya da eski Google dökümanlarından yayıldı. Ama bu rakam kontekstsiz söylenirse zararlı.

Gerçek soru şu, neyi ölçmek istiyoruz?

Line coverage: satır çalıştı mı? Branch coverage: if/else dalları ayrı ayrı test edildi mi? Function coverage: tanımlı her fonksiyon en az bir kez çağrıldı mı? Path coverage: kombinasyonlu dallar gezildi mi? Mutation coverage: kod içine bilerek bozulmuş değişiklikler yerleştirince testler bunu yakalıyor mu?

Katkı eşit değil. Bir proje line coverage’da yüzde 95, mutation’da yüzde 40 olabiliyor. İkincisi gerçek resmi gösteriyor, ilki kandırıyor.

Bir iOS projesinde şu durumu yaşadım. Bir view model için yüzde 100 coverage vardı. Her metoda test yazılmıştı. Ama testler sadece fonksiyonu çağırıp exception atmadığını kontrol ediyordu. Gerçek iş mantığı hiç doğrulanmamıştı. Bir validation fonksiyonu yanlış çıktı veriyordu, test geçiyordu çünkü test sadece fonksiyonun çağrıldığını doğruluyordu. Refactor sırasında fark ettim.

Öte yandan yüzde 30 coverage ile harika çalışan bir projem oldu. Yazar yalnız ben değildim, disiplinli bir arkadaşım critical path’leri yüksek kaliteli integration testlerle kaplamıştı. Edge case’ler, concurrent durumlar, error handling. Geri kalan kod genellikle UI wiring ve display logic’ti, gerçekten test değeri düşük şeyler. Proje iki yıl prod’da gitti, critical path bug’ı olmadı.

Kod tabanında hangi bölümleri test etmek değerli?

  • Para, güvenlik, yetkilendirme içeren yerler
  • Karmaşık domain logic
  • Zor yeniden üretilebilir bug’lar yaşanan yerler
  • Public API yüzeyi
  • Üçüncü taraf entegrasyonların sınırları

Hangi bölümlerin test edilmesi marjinal değer?

  • Basit getter/setter
  • Üçüncü taraf kütüphanenin trivial sarmalayıcıları
  • Kısa ömürlü deneyler
  • Framework’ün zaten test ettiği şeyler (SwiftUI View’ın render ettiğini test etmek)

Pratikte takımda şu politikayı uyguladım. Coverage’a minimum eşik koyduk ama hedef koymadık. Yeni eklenen kodun coverage’ı önceki seviyenin altına düşemez. Yani yüzde 55’teysek, yeni PR yüzde 54’e getiremez. Ama yüzde 56’ya çıkmaya zorlamıyoruz. Bu sayede önemli yerlere test yazıyoruz, önemsiz yerlere yazmak için kendimizi kandırmıyoruz.

Mutation testing aracı olarak iOS’ta Muter, PHP’de Infection kullandım. Sonuçlar gözünüzü açıyor. “Yüzde 90 coverage” diye övündüğünüz modülün mutation skoru yüzde 40 çıkınca gerçek resmi görüyorsunuz.

Coverage rakamı bir sinyal, hedef değil. Yüzde 80’in altındaysanız sebebini sorgulayın, üzerindeyseniz rahat olmayın. Sorun satırların çalıştırılıp çalıştırılmadığı değil, yazılı testlerin gerçek senaryoları kapsayıp kapsamadığıdır.

Bu konuda bir projeniz mi var?

Kısa bir özet bırakın, 24 saat içinde size dönüş yapayım.

İletişime Geç