Kararsız testler: %0,5'ten %98'e
800 testin her biri %0,5 ihtimalle boşuna patlıyorsa süit neredeyse her koşuda kırmızı. Retry neden tedavi değil, kararsızlığı ne yakalar?
%98
Süit büyüdükçe daha az güvenilir
Temiz bir çalıştırmada herhangi bir testin patlama ihtimali
%0,5 ihtimalle boşuna patlayan tek bir test görünmez. Aynısından 800 tane koy: 1 − 0,995^800 ≈ %98.
İhtimaller birikiyor
Test sayısı arttıkça yanlış kırmızı
en az bir testin boşuna patlaması, %
Formülden hesaplandı: 1 − 0,995^n. Ölçüm değil; yazıda yalnız n = 800 için ≈ %98 geçer.
Patlamalar bağımsız da değil
Yerelde 50 ms, yük altında timeout.
CI, paylaşımlı ve throttle'lı donanımda koşar; laptop'unda 50 ms'de biten async test, yük altında timeout'a düşer.
AI kararsızlığı icat etmedi, seri üretime geçirdi
Doğru görünen dört kalıp
- Sabit bir sleepAsync işi "beklemek" için: time.Sleep(2 * time.Second), await page.waitForTimeout(2000), cy.wait(2000).
- Seed'siz rastgelelikHer çalıştırmada farklı değer: Math.random(), rand.Intn(100), sabit seed'i olmayan bir faker.
- Kırılgan bir selectorDOM yapısına çakılı: nth-child, otomatik üretilmiş bir class adı. Markup azıcık kayınca kırılır.
- Her şeye bir mockTest bir sonucu değil bir etkileşimi doğrular.
Retry bir koşu bandı, tedavi değil
Hepsi reaktif
- RetryGerçek CI dakikası yakar ve feedback loop'u uzatır; yeni hiçbir şey öğrenmemek için iki kez ödersin.
- QuarantineSessizce büyüyen bir devre dışı test yığını. O yığın borçtur ve faiziyle büyür.
- TicketBacklog gürültüsüne yaşlanır ve sessizce önemini yitirir.
Patlamayı değil, anti-pattern'i yakala
Ne zaman devreye giriyor?
| Retry, quarantine, ticket | Commit sınırında statik tarama | |
|---|---|---|
| Zaman | Test CI'ı zaten bozduktan sonra | Test daha çalışmadan, diff'te |
| Etki | Belirtiyi gizler, bedelini sana keser | Bilinen anti-pattern'leri işaretler |
| Tekrarlanabilirlik | Yeniden çalıştırınca geçer, sonra yine patlar | Aynı diff, aynı sonuç; model yok, network yok |
| Kapsam | Testi deterministik yapmaz | Bariz kararsızlığı CI'a hiç ulaşmadan durdurur |

Tespit emniyet ağı, asıl çözüm tasarım
Testi deterministik yaz
- Sabit beklemeleri koşula dayalı beklemeyle değiştir. Saati değil, bir olguyu bekle. (bekliyor)
- Her rastgele kaynağı seed'le; deterministik bir saat ve ID enjekte et. (bekliyor)
- DOM pozisyonuna değil, role veya test id'ye göre seç. (bekliyor)
- Logic'i değil, sınırı mock'la; en az bir gerçek integration yolunu koru. (bekliyor)
Bu kalıp ne zaman doğru cevap olmaktan çıkar?
Statik kapının sınırları
- Akıllı race'i yakalamazBariz anti-pattern'leri yakalar, kendi kodunun içine gömülü bir race condition'ı değil.
- Kuralları muhafazakâr tutGürültülü bir kapı yok sayılır; yok sayılan bir kapı ise hiç olmamasından kötüdür.
- Sistem kararsızsaTest edilen sistem deterministik olmadığı için kararsız olan bir test, sana sistem hakkında bir şey söylüyor.
Yeniden çalıştırman gereken yeşil bir CI, yeşil değildir.
Kararsız bir testi öldürmenin en ucuz yeri, yazıldığı satır: sana bir build'e mal olmadan önce.

Yazıldığı satırda
Kaynak: sade.dev, Kararsız Testler: Retry Çözüm Değil