Kırılgan Testler: Ekibin Test Takımına Olan Güvenini Nasıl Öldürür?
Bazen geçen bazen kalan bir test, hiç olmayan testten daha zararlıdır: gerçek hatayı da görünmez kılar.
Bir kırılgan test (flaky test), kod hiç değişmediği hâlde bazen geçen bazen kalan testtir. İlk bakışta küçük bir rahatsızlık gibi görünür — "tekrar çalıştır, geçer". Gerçekte ise test takımının en değerli özelliğini yok eder: kırmızı sonucun anlamını. Ekip bir süre sonra kırmızıyı gördüğünde kodu değil butonu kontrol eder, ve gerçek bir hatanın yakalandığı gün de aynı refleksle yeniden çalıştırıp geçer.

Gerçek maliyet: güvenin erozyonu
Kırılgan testlerin doğrudan maliyeti dağıtım hattında kaybedilen dakikalardır, ama asıl zarar dolaylıdır. Ekip testlere güvenmemeye başladığında üç şey olur: başarısız testler incelenmeden yeniden çalıştırılır, yeni test yazma isteği azalır ve zamanla test takımı "geçmesi gereken bir engel" hâline gelir. Bu noktadan sonra test kapsamı yüksek olsa bile hatalar üretime geçmeye devam eder — çünkü sinyal artık okunmuyordur.
Kırılganlığın kaynakları
Zamanlama ve sabit bekleme
En yaygın sebep budur. Test "iki saniye bekle, sonra elemanın geldiğini varsay" biçiminde yazıldığında, makine yavaşladığı gün test kalır. Çözüm bekleme süresini artırmak değildir — bu yalnızca testi yavaşlatır ve sorunu ileri atar. Doğru yöntem, koşula dayalı beklemedir: belirli bir durum gerçekleşene kadar, üst sınırla birlikte beklemek.
Paylaşılan durum
Testler aynı veritabanı satırlarını, aynı dosyayı veya aynı önbelleği paylaşıyorsa, biri diğerinin ortamını bozar. Bu özellikle paralel çalıştırmada patlar: tek tek geçen testler birlikte koşturulduğunda rastgele kalır. Her testin kendi verisini oluşturması ve sonunda temizlemesi (ya da her testin işlem içinde çalışıp geri alınması) bu sınıfı büyük ölçüde bitirir.
Sıra bağımlılığı
Bir test, kendinden önceki testin bıraktığı duruma güveniyorsa, sıra değiştiğinde kalır. Bunu ortaya çıkarmanın pratik yolu, testleri rastgele sırayla çalıştırmaktır. Sıra karıştırıldığında ortaya çıkan başarısızlıklar, gizli bağımlılıkların haritasını verir.
Dış dünya
Gerçek bir dış API'ye, gerçek saate veya rastgele üretilen değerlere bağlı testler doğaları gereği kırılgandır. Dış servisler taklit edilmeli, saat testte sabitlenmeli, rastgelelik tohumlanmalıdır. Uçtan uca testlerde bu bağımlılıkları tamamen kaldırmak mümkün olmayabilir; o katmanın neden kırılgan olduğunu ve nasıl sınırlanacağını uçtan uca testler yazımızda ele almıştık.
Tespit: önce ölçün
Kırılganlıkla mücadelenin ilk adımı, hangi testlerin kırılgan olduğunu bilmektir. Bunun için test sonuçlarının geçmişini saklamak gerekir: aynı commit üzerinde farklı sonuç veren testler otomatik olarak işaretlenebilir. Basit bir kural yeterlidir — son 50 çalıştırmada hem geçmiş hem kalmışsa, o test kırılgandır.
Bu ölçüm dağıtım hattının parçası olmalıdır. Sürekli entegrasyon kurgusunu yeni oluşturuyorsanız CI/CD yazımız temel yapıyı, pipeline güvenliği yazımız ise sık atlanan riskleri anlatıyor.
Tedavi: karantina, ama süreli
Kırılgan bir test tespit edildiğinde iki uç yaklaşım da yanlıştır. Testi olduğu gibi bırakmak güveni aşındırır; hemen silmek ise gerçek bir kapsamı yok eder. İşleyen orta yol karantinadır: test ana hattı kırmamak üzere ayrı bir kümeye alınır, ancak bir son tarihle birlikte. Süre dolduğunda test ya düzeltilir ya silinir. Son tarihi olmayan karantina, kısa sürede unutulmuş testler mezarlığına dönüşür.
Düzeltirken hedef, testi "geçirmek" değil kırılganlığın kök sebebini bulmaktır. Çünkü kırılganlık şaşırtıcı sıklıkta gerçek bir üretim hatasına işaret eder: yarış durumu, eksik kilit veya zaman dilimine bağlı bir mantık hatası. Testin bazen kalması, aslında sistemin bazen yanlış çalıştığının kanıtı olabilir — bu ihtimali baştan elemeyin.
Önlem: yazarken kırılganlığı engellemek
Yeni testlerde birkaç alışkanlık, sorunun büyük kısmını baştan engeller: sabit beklemeler yerine koşula dayalı bekleme kullanmak, her testi kendi verisiyle çalıştırmak, saat ve rastgeleliği kontrol altına almak, dış bağımlılıkları taklit etmek ve testleri baştan rastgele sırayla çalıştırmak. Test piramidinin hangi katmanında ne kadar test yazılacağı da belirleyicidir; hangi testi ne zaman yazmalı yazımız bu dengeyi ele alıyor. Test pratiklerinin genel çerçevesi için Martin Fowler'ın test yazıları hâlâ en iyi başvuru kaynaklarından biridir.
Sonuç
Kırılgan testler, test takımının verdiği tek değerli bilgiyi — "kırmızı ise bir şey bozuktur" — ortadan kaldırır. Çözüm, başarısız testi yeniden çalıştırmak değil; kırılganlığı ölçmek, kaynağını (zamanlama, paylaşılan durum, sıra bağımlılığı, dış dünya) tespit etmek ve süreli karantinayla birlikte kök nedeni gidermektir. Bu hafta ekibinizde küçük bir deney yapın: test takımını rastgele sırayla iki kez çalıştırın. İki çalıştırma farklı sonuç veriyorsa, düzeltmeniz gereken ilk şeyi bulmuşsunuz demektir.
Sık Sorulan Sorular
Genellikle hayır. Test bir davranışı koruyordu; silmek o kapsamı kaybettirir. Doğru sıra, süreli karantinaya almak ve kök nedeni düzeltmek; ancak test gerçekten değersizse silmek de meşru bir karardır.
Kısa vadede hattı akıcı tutar ama kırılganlığı gizler. Kullanılacaksa mutlaka raporlanmalıdır: hangi test kaç kez yeniden denendiğinde geçti bilgisi olmadan retry, sorunu görünmez yapar.
Neredeyse her zaman paylaşılan durumdur: aynı veritabanı kaydı, aynı dosya, aynı önbellek ya da global bir değişken. Her testin kendi verisini oluşturup temizlemesi bu sınıfı ortadan kaldırır.
Evet ve bu sıklıkla göz ardı edilir. Yarış durumları, eksik kilitler ve saat dilimine bağlı mantık hataları önce testte kırılganlık olarak görünür; testi susturmak, üretimdeki hatayı da saklar.
Yorumlar (0)
Bu yazıya henüz yorum yapılmamış. İlk yorumu siz yazın!
Yorum Yaz
Yorumunuz onaylandıktan sonra yayınlanır. Ekibimiz gerekirse konuyla ilgili bir yanıt da paylaşır.