Bu durumda karşılaştığımız her ekip aynı takvime göre yaşıyor. Sürüm günü gelir ve birkaç saat içinde destek kuyruğu alev alır: sessizce ödeme almayı bırakmış bir ödeme akışı, boş görüntülenen bir rapor, açması hiç beklenmeyen bir kapıyı açan bir izin. Düzeltme o gece devreye girer ve ertesi hafta başka bir şey bozulur. Burada anlatacağımız şirket, bu ritmin içinde o kadar uzun yaşamıştı ki artık bir kriz gibi hissettirmeyi bırakıp hava durumu gibi hissettirmeye başlamıştı — içinde çalıştığınız iklimin ta kendisi.
Daha fazla kahramanlığa ihtiyaçları yoktu; bundan bolca vardı. Eksik olan şey, dağıtımdan önce tek bir yalın soruyu yanıtlayabilmenin bir yoluydu: Bu sürüm gerçekten çalışıyor mu?
İçine adım attığımız durum
Müşteri, yaklaşık kırk kişilik bir B2B SaaS işletmesiydi; tek bir ürünü ve bir yıl içinde kabaca iki katına çıkan bir müşteri tabanı vardı. Mühendislik ekibi bir düzine kadar geliştiriciden oluşuyordu. Ayrılmış bir QA fonksiyonu yoktu — test etmek, bir geliştiricinin sürümden önceki akşam uygulamayı kendi makinesinde tıklayıp umut ederek yapabildiği her neyse oydu. Bu yaklaşım, ürün küçükken ve ekip onun her köşesini ezbere bilirken işe yaramıştı. Ölçeklenmedi ve büyüme onu sessizce geride bırakmıştı.
Asıl sorun
Bunu "araç eksikliği" olarak sınıflandırmak kolay olurdu, ama bu pek doğru değil. Daha derin sorun, kimsenin o yalın soruyu herhangi bir güvenle yanıtlayamamasıydı. Manuel regresyon testi bir haftanın büyük bölümünü alıyordu, bu yüzden pratikte atlanıyordu. Bir güvenlik ağı olmadan, her değişiklik karanlıkta oynanan küçük bir bahisti. Ve dağıtım tehlikeli hissettirdiği için ekip değişiklikleri toplu hâle getirip daha seyrek dağıtıyordu — bu da her sürümü daha büyük, daha riskli ve bozulmaya daha yatkın kılıyordu. Korku, tam da herkesin korktuğu sonuca doğru büyüyordu.
Nasıl yaklaştık
Tek bir satır test koduna dokunmadan önce birkaç ilke belirledik:
- Araçlardan değil, olaylardan başlayın. Tahmin etmek yerine, son altı ayın arızalarının bize kalitenin gerçekte nereden sızdığını söylemesine izin verin.
- Önce kritik yolları koruyun. Bir kapsam yüzdesinin peşinden koşmak bir tuzaktır; bizim istediğimiz, bozulduklarında gerçek para ya da gerçek güven kaybettirecek bir avuç akıştı.
- Boru hattını (pipeline) reddedebilir kılın. Kötü bir birleştirmeyi (merge) engelleyemeyen bir test paketi, bir güvenlik ağı değil, belgedir.
- Kaliteyi öne çekin. Doğrulama, kodu yazan kişilere aittir; işi bunun nasıl kontrol edileceğini tasarlamak olan biri tarafından desteklenerek.
- Değişim birimini küçültün. Daha küçük, daha sık sürümleri anlamak daha kolaydır ve düzeltmesi çok daha ucuzdur.
Gerçekte ne yaptık
İlk birkaç haftayı yazarak değil, okuyarak geçirdik — önceki yarım yılın her acil düzeltmesini (hotfix) ve olayını inceleyerek. Neredeyse hemen net bir örüntü belirdi: Üretim arızalarının büyük çoğunluğu birkaç akışta kümeleniyordu — kimlik doğrulama, faturalandırma ve ürünün kalbindeki temel oluştur-oku-güncelle yolları. Bu bize tam olarak nereye yatırım yapacağımızı, nereye yapmayacağımızı söyledi.
Ardından bu kritik akışların etrafına kasıtlı olarak ince bir otomatik regresyon testi katmanı inşa ettik: müşterinin gerçekten fark edeceği yolculuklar için uçtan uca testler ve bunların altındaki dikiş yerleri için entegrasyon testleri. Paketi CI'a bağladık; böylece kırmızı bir derleme (build) bir birleştirmeyi engelledi — istisna yok, geçersiz kılma yok. Kod dağıtmak ile bir özelliği yayınlamak iki ayrı karar hâline gelsin diye feature flag'ler devreye aldık: yeni iş karanlıkta (dark) dağıtılabilir ve gerçekten hazır olduğunda açılabilirdi.
Otomasyonun yanı sıra hafif bir sürüm kontrol listesi getirdik ve bir mühendisi ayrılmış bir QA rolüne yönlendirdik — en sonda hataları yakalayan kişi olarak değil, her değişikliğin en baştan nasıl doğrulanacağını tasarlayan kişi olarak. Hazırlık (staging) ortamında ve her üretim dağıtımından sonra tekrar çalışan duman testleri (smoke test), ekibe çekirdeğin hâlâ çalıştığına dair hızlı ve dürüst bir sinyal verdi.
Sonuç
| Metrik | Öncesi | Sonrası |
|---|---|---|
| Sürüm başına üretime ulaşan kritik hatalar | Her sürümde birkaç tane | Yaklaşık bir tane, çoğu zaman hiç |
| Regresyon testi süresi | Kabaca bir hafta, tamamen manuel | Bir günün altında, çoğunlukla otomatik |
| Kritik akışların otomatik kapsamı | Sıfıra yakın | Kritik yolların çoğunluğu |
| Acil düzeltmeler (hotfix) | Ayda birkaç kez | Ara sıra |
| Sürüm ritmi | Birkaç haftada bir, gergin | Haftalık, rutin |
Müşteri için önemli olan manşet rakamı, o tablodaki herhangi tek bir sayı değildi; kaçan hataların kabaca üç kat azalması, üstelik sürümler daha seyrek değil daha sık hâle gelirken olmasıydı. Güven bir kez var olduğunda, davranışı kendiliğinden değiştirdi. Ekip, bariz hataları yakalaması için boru hattına güvendiğinde, değişiklikleri biriktirmeyi bıraktı; daha küçük sürümler ise, nadiren bir şey bozulduğunda onu bulup geri almanın çılgın bir akşam yerine dakikalar sürmesi anlamına geldi.
Farkı yaratan neydi
Üç ders, bu konumdaki neredeyse her ekibe taşınır:
- Kapsam bir yüzde değil, bir triyaj kararıdır. Geçmiş olaylar bize hangi akışların korunmayı hak ettiğini söyledi. Bir sayıyı yükseltmek için yazılan testler, arızanın zaten hiçbir zaman zarar vermeyeceği yere harcanan emektir.
- Bir test, ancak boru hattı hayır diyebiliyorsa önemlidir. Kırmızı bir derlemenin tavsiye niteliğinde olmayı bırakıp birleştirmeleri engellemeye başladığı an, kalite, kimin kontrol etmeyi hatırladığı meselesi olmaktan çıkıp sistemin bir özelliği hâline geldi.
- QA bir tasarım faaliyetidir, son bir kapı değil. Doğrulamayı öne almak — bir değişikliğin nasıl kanıtlanacağına baştan karar vermek — hattın sonundaki hiçbir denetimin başaramayacağı kadarını başardı.
Ekip hâlâ her hafta dağıtım yapıyor, ama takvim artık farklı okunuyor: sürüm günü, herkesin kendini hazırladığı gün değil, daha sakin günlerden biri. Uğrunda inşa etmeye değer olan "bitti" sürümü işte budur.