Sorunun Geçmişi
Geleneksel test yürütme stratejileri, kod değişim kapsamına bakılmaksızın tam regresyon takımlarının çalıştırılmasına dayanır. Sistemler binlerce mikro hizmete ölçeklendikçe, bu yaklaşım 10 saati aşan geri bildirim döngüleri gibi darboğazlar yarattı. Test Etki Analizi (TIA), 2000'lerin başındaki değişim bazlı testlerden akademik araştırmalardan doğdu. Microsoft, Azure DevOps için TIA eklentisi ile endüstriyel uygulamanın öncüsü oldu ve %70 oranında yürütme süresinde azalma gösterdi. Uygulama, statik kod bağımlılıklarının ötesine geçerek tarihsel hata korelasyonunu anlamak için Makine Öğrenimi oluşturarak evrildi.
Problemin Tanımı
Büyük kod tabanlarında monolitik test yürütmesi hesaplama kaynaklarını boşa harcar ve geliştirici geri bildirimlerini geciktirir. Ancak, naif test seçimi, paylaşılan kütüphanelerdeki değişikliklerin bağımlılık zincirleri aracılığıyla yayılma riskini göze alır. Statik analiz, çalışma zamanı polimorfizmini, yansıtma tabanlı çağrıları ve ORM eşlemelerini etkileyen veritabanı şeması değişikliklerini kaçırır. Zorluk, yürütme hızını, özellikle dağıtık mimarilerdeki hizmetler arası bağımlılıklar için defekt tespitine güven ile dengelemede yatmaktadır.
Çözüm
Soyut Söz Dizimi Ağacı (AST) ayrıştırması ile çalışma zamanı kapsama korelasyonunu birleştiren hibrit bir etki analizi sistemi inşa edin. Komut farklılıklarını çözümleyerek değiştirilen yöntemleri tanımlayın, ardından tarihsel JaCoCo kapsama verilerini kullanarak kod öğelerini test durumlarına haritalayan bir grafik veritabanını (Neo4j) sorgulayın. Tarihsel hata örüntülerini kullanarak test önceliklerini ağırlıklandıran Python tabanlı bir risk sınıflandırıcı uygulayın. Doğrudan kapsama eşleşmelerinin yanı sıra istatistiksel olarak ilişkili yüksek riskli testleri de içeren dinamik test alt kümeleri oluşturun, kritik yol doğrulamasını sağlarken 15 dakikalık yürütme pencerelerini koruyun.
Mimari, üç entegre katman gerektirir. İlk olarak, bir Git diff ayrıştırıcı, JavaParser veya benzeri AST analiz araçlarını kullanarak değiştirilen dosyaları, sınıfları ve yöntemleri analiz eder. İkincisi, bir haritalama hizmeti, gece çalışmaları sırasında JaCoCo kapsama ajanları tarafından doldurulan kod öğeleri ile test durumları arasındaki ilişkileri saklayan bir Neo4j grafik veritabanını sorgular. Üçüncüsü, bir ML tahmin hizmeti, doğrudan kapsama bağlantıları olmayan ancak istatistiksel olarak birlikte başarısız olan yüksek riskli modül kombinasyonlarını belirlemek için tarihsel hata verilerini analiz eder.
Bir geliştirici kodu taahhüt ettiğinde, sistem önce statik analiz yoluyla doğrudan etkilenen testleri tanımlar. Daha sonra değiştirilen satırları kapsayan testleri bulmak için grafiği sorgular. Son olarak, ML katmanı tarihsel eş hata örüntülerine dayalı olarak tahmin edilen yüksek riskli testleri ekler. Bu alt küme, CI/CD boru hattına aktarılır, ayrıca tüm regresyonun gece çalışarak tahmin modelinin kaçırdığı kenar vakaları yakalaması sağlanır.
Java Spring Boot mikro hizmetlerini sürdüren bir fintech şirketi, kritik boru hattı sıkışması ile karşılaştı. 8,000 entegrasyon testinin bulunduğu takımları 6 saat içinde tamamlandı ve bu da geliştiricilerin aşırı bağlam değiştirmesine ve birleştirme çatışmalarının birikmesine yol açtı.
Çözüm A: Bayt kodu analizi kullanarak statik bağımlılık haritalama. ASM kullanarak sınıf bağımlılıklarını analiz eden ve etkilenen testleri tanımlamak için Maven modül grafiği yaratan bir araç prototipini geliştirdiler. Bu yaklaşım 30 saniyeden kısa bir sürede çalıştı ve minimum altyapı gerektirdi. Ancak, Spring'in bileşen taraması, Hibernate proxy nesneleri ve mesaj kuyruğu etkileşimleri gibi dinamik bağımlılıkları tespit edemedi. Deneme dönemi boyunca, üretim hatalarının %12'si tespit edilemedi ve bu yaklaşım, kritik finansal işlemler için yetersiz kaldı.
Çözüm B: Grafik veritabanlarıyla çalışma zamanı kapsama korelasyonu. JaCoCo ajanları ile testleri enjekte ederek satır düzeyinde kapsama kaydettirdiler ve ilişkileri Neo4j'de sakladılar. Kod değiştiğinde, sistem değiştirilen satırları işleyen testleri sorguladı. Bu, dinamik davranışı doğru bir şekilde yakaladı ancak yeni test durumları için önemli bir soğuk başlangıç gecikmesi getirdi ve satır düzeyindeki haritalama için 500GB depolama gerektirdi. Ayrıca, kaprisli testlerin kapsama temelini bozarak tutarsız test seçimine yol açtığını gördüler.
Çözüm C: Makine Öğrenimi tabanlı risk genişletmesi ile hibrit yaklaşım. Hızlı statik analizle anlık geri bildirim sağlamak ve gece saatlerinde kapsama verisi güncellemeleri yapmak üzere hibrit bir çözüm önerdiler. 18 aylık taahhüt ve hata verilerine dayanarak yüksek riskli modül kombinasyonlarını tanımlamak için bir scikit-learn sınıflandırıcı eklediler. Eğer bir değişiklik ödeme işleme modüllerini etkilediyse, sistem doğrudan kapsama kenarları olmadan bildirim hizmetleri testlerini otomatik olarak dahil etti, tarihsel eş hata örüntülerine dayanarak.
Üç aylık denemeden sonra hibrit çözümü seçtiler. Statik analiz, değişikliklerin %85'inde 2 dakikanın altında test listesi oluşturarak, ML katmanı karmaşık entegrasyon risklerini yönetti. Sistem, ortalama boru hattı yürütmesini 22 dakikaya düşürdü ve tam regresyona göre %99.1 defekt yakalama oranını korudu. Eğer defektler kaçtıysa, bunları eksik kapsama kenarlarına geri izlediler ve bunları eğitim setine besleyerek sürekli olarak gelişen bir seçim mekanizması yarattılar.
Kısmi test takımları yürütürken test verisi bağımlılıklarını nasıl yönetiyorsunuz?
Adaylar genellikle testlerin bağımsız olduğunu varsayıyorlar, ancak paylaşılan veritabanı durumları ve fikstürler gizli bir birleşme oluşturuyor. Eğer Test A, bir müşteri kaydını değiştirirse ve Test B bunu okursa, sadece Test A kod değişiklikleri nedeniyle seçilirse Test B, izole olarak geçer ama tam takımda veri kirliliği nedeniyle başarısız olur.
Çözüm, her test sınıfı için geçici veritabanı örnekleri sağlayan TestContainers kullanarak sıkı bir test izolasyonu uygulamayı gerektirir. Ayrıca, paylaşılmış SQL betikleri yerine test verisi oluşturmak için Builder pattern'ı benimseyin. Kaçınılmaz bağımlılıklar (örneğin, çok adımlı iş akışı testleri) için, A'nın bağımlılıkları değiştiğinde, ikisi de alt kümede yer alacak şekilde A'nın bağımlı olduğu Test B'yi sağlamayıiçin bir bağımlılık çözücü uygulayın. Bu, tüm takımı çalıştırmadan referans bütünlüğünü korur.
Tam entegrasyon testlerini çalıştırmadan, hizmetler arası sözleşme doğrulamasını nasıl sağlarsınız?
Birçok kişi yalnızca hizmet içi test seçimlerine odaklanırken, Hizmet A'nın API'sinde bir değişiklik olduğunun Hizmet B'nin kullanıcılarını etkileyebileceğini göz ardı ediyorlar.
Cevap, etki grafiğine Tüketici Tarafından Yönetilen Sözleşme (CDC) testlerini entegre etmeyi içerir. Tüketici beklentilerini tanımlamak için Pact veya Spring Cloud Contract kullanın. Bunları bir Pact Broker içinde saklayın ve etki analizinde sorgulayın. Hizmet A değiştiğinde, sistem, sadece A'nın iç testlerini değil, A'nın API'sine karşı doğrulama yapan tüm kayıtlı tüketici sözleşme testlerini de tanımlamalıdır. Bu, ağır uçtan uca entegrasyon takımları yerine, hafif sözleşme testleri aracılığıyla geriye uyumluluğun doğrulanmasını sağlar ve hız avantajlarını korurken, kırılma değişikliklerini önler.
Kaprisli testlerin etki analiz veritabanını bozmasını nasıl önlersiniz?
Adaylar sıklıkla, kararsız testlerin ML modellerini ve kapsama verilerini zehirlediğini görmezden gelirler. Eğer bir kaprisli test rastgele başarısız olursa, ML modeli, onu yüksek riskli olarak yanlış bir şekilde ağırlıklandırabilir veya kapsama verileri, erken sonlandırma nedeniyle tamamlanmamış olabilir.
DeFlaker metodolojisini veya istatistiksel yeniden yürüme stratejilerini (başarısız testleri 3 kez çalıştırın) kullanarak bir kaprislilik tespit katmanı uygulayın. Başarısızlık dağılımları üzerinde Benford's Law analizi kullanarak istatistiksel anormallikler gösteren testler için bir karantina listesi tutun. Yalnızca kararlı testler, kapsama grafiğine ve ML eğitim setlerine katkıda bulunmalıdır. Karantina bulunan testleri ayrı, engellemeyen gece saatlerinde çalışan hatlarda çalıştırın ve bunları kritik yoldan çıkararak tanısal değerini koruyun ve etki analiz sisteminde yanlış pozitiflerden kaçının.