İsim şaka gibi, fikir ciddi
CRAP, İngilizcede kaba bir kelime. Ama burada bir kısaltma: Change Risk Anti-Patterns, yani “değişiklik riski taşıyan kötü kalıplar”. Metriği 2007’de Alberto Savoia ve Bob Evans ortaya attı ve Java için crap4j adlı bir araçla kullanıma sundu. Sonra uzun süre unutuldu.
Mayıs 2026’da Oleksandr Prokhorenko, Rust projeleri için cargo-crap aracını ve onu anlatan bir yazı yayınladı. Yazının ana fikri şu: Kodun büyük kısmını artık ajanlar yazıyorsa, hangi fonksiyonların riskli olduğunu ölçmek her zamankinden önemli.
İki ölçü, tek sayı
CRAP iki şeyi birleştiriyor:
- Döngüsel karmaşıklık (cyclomatic complexity): Bir fonksiyonun içinden kaç farklı yol geçtiği. Her
if,match, döngü ya da hata yakalama bloğu yolda yeni bir çatal açıyor. Çatal arttıkça fonksiyonu kafanda canlandırmak zorlaşıyor. - Test kapsamı (coverage): Testler çalışırken fonksiyonun satırlarının yüzde kaçının gerçekten çalıştırıldığı.
Formül şöyle: CRAP = K² × (1 − kapsam)³ + K. Burada K karmaşıklık, kapsam da 0 ile 1 arasında bir oran.
Formülün davranışı birkaç örnekle netleşiyor:
- Karmaşıklığı 10 olan, hiç testi olmayan bir fonksiyon: 100 × 1 + 10 = 110.
- Aynı fonksiyon testlerle tamamen kapsanmışsa ilk kısım sıfırlanıyor, skor 10 oluyor.
- Yarısı kapsanmışsa: 100 × 0,125 + 10 = 22,5.
Küp üssü, kapsam düştükçe skoru çok hızlı büyütüyor. Yani formül, karmaşık ama testsiz kodu ağır cezalandırıyor. Basit bir fonksiyon testsiz kalsa bile skoru düşük kalıyor.
Eşik: 30
cargo-crap varsayılan olarak 30’un üstündeki fonksiyonları riskli sayıyor. Buradan iki pratik sonuç çıkıyor:
- Karmaşıklığı 5 olan testsiz bir fonksiyon tam sınırda (25 + 5 = 30). Daha karmaşık her testsiz fonksiyon eşiği geçiyor.
- Karmaşıklığı 30’u aşan bir fonksiyon, testleri ne kadar iyi olursa olsun eşiğin üstünde kalıyor. Bu durumda çözüm daha çok test değil, fonksiyonu bölmek.
Videodaki deneme de bunu gösteriyor: Testleri olan karmaşık bir fonksiyon düşük skor alıyor. Testler yorum satırına alınınca aynı fonksiyonun skoru 100’ün üstüne çıkıyor.
cargo-crap nasıl çalışıyor?
Araç kendi başına test çalıştırmıyor. Önce cargo-llvm-cov gibi bir araçla kapsam raporunu LCOV biçiminde üretiyorsun. cargo-crap kaynak kodu okuyup her fonksiyonun karmaşıklığını hesaplıyor, kapsam raporuyla eşleştiriyor ve en riskliden başlayarak bir tablo veriyor.
CI için kullanışlı birkaç özelliği var:
- Mutlak eşik: Skoru belli bir değeri aşan fonksiyon varsa derlemeyi kırmak.
- Referans (baseline) modu: Eski borcu bir dosyaya kaydedip sadece kötüleşmeyi engellemek. Büyük ve eski bir projede her şeyi bir günde düzeltmen gerekmiyor.
- PR yorumu: Sonucu pull request’e okunabilir bir yorum olarak yazmak.
Yapay zekâ çağında neden önemli?
Prokhorenko’nun yazısına göre ajanlar kodu sadeleştirmek yerine üstüne ekleme eğiliminde: Her yeni durum için bir koşul, her hata için bir yedek yol. Kod çalışıyor, derleniyor, ama karmaşıklık sessizce birikiyor. Videoya göre ajanlar karmaşık kodu kolay üretiyor, ama zorlanmadıkça anlamlı testleri aynı özenle yazmıyor.
CRAP burada bir hakem gibi davranıyor. “Bu kod kötü” demiyor. “Bu fonksiyonu değiştirirsen kırılma ihtimali yüksek, ve seni uyaracak test yok” diyor. Bu soru, kodu kimin yazdığından bağımsız.
Düşün
- Senin projende en karmaşık fonksiyon hangisi? Onu değiştirdiğinde seni uyaracak bir test var mı?
- Ajanın yazdığı koda bir CRAP eşiği koysan, ilk hangi fonksiyonlar takılırdı?
Videoyu izle
Kaynaklar (4, İngilizce)
Kendi cümlelerimizle yazılmış bir özettir, çeviri değildir. Tüm kaynaklar yukarıda.