Özet: Pest PHP, kodunuzun yapısını, sadece davranışını test edebilir. Takım kurallarınızı mimari testler olarak yazın ve CI, her bir commit’te bunları uygulamayı zorunlu kılar. Böyle bir test, insan incelemesinin atladığı çoklu kiracı veri sızıntısını yakaladı.
Bir kuralımız vardı. Her kiracıya özel verileri tutan model, BelongsToTenant trait’ini kullanmalıdır. Bu trait, bir kliniğin başka bir kliniğin verilerini görmesini engelleyen global bir kapsam ekler.
Kural, oryantasyonda yer aldı. Kod inceleme kontrol listesindeydi. Herkes bunu biliyordu.
Bir geliştirici takıma katıldı. Üç hafta geçtikten sonra yeni bir model ekledi ve trait’i unuttu. İncelemeyi yapan kişi iş mantığına odaklanmıştı ve eksik trait’i fark etmedi. Model piyasaya sürüldü.
İki gün boyunca bir klinik, belirli bir raporda başka bir kliniğe ait verileri görebildi. Bir destek bileti bunu yakaladı. Ancak testlerimiz bunu yapamadı.
O gün mimari testler projeye dahil edildi.
Mimari Test Nedir
Mimari Test Nedir
Çoğu test, davranışı kontrol eder. Bu girdiye karşılık gelen fonksiyon, o çıktıyı döndürür. Bir mimari test ise yapıyı kontrol eder. Yani, kodun nasıl düzenlendiği hakkında belirli şeyleri doğrular.
Pest, tam da bunu yapabilmeniz için bir arch fonksiyonuna sahiptir.
// tests/Architecture/ArchTest.php
arch('tenant models must use the BelongsToTenant trait')
->expect('App\Models')
->toUseTrait('App\Traits\BelongsToTenant')
->ignoring('App\Models\SystemSetting');
arch('controllers may not touch the DB facade directly')
->expect('App\Http\Controllers')
->not->toUse();
arch()
->expect()
->not->toUse();
arch()
->expect()
->not->toUse();
Bu testler, her commit sırasında CI’de çalışır. Bir kuralı ihlal ederseniz, yapı başarısız olur ve ihlal edilen kuralın ismi ile ihlalin gerçekleştiği dosya belirtilir.
Teslim Almayı Başaran Testler
Teslim Almayı Başaran Testler
Kiracı trait testimiz, takip eden aylarda daha dört modelin trait’ini atladığını yakaladı. Her biri, potansiyel bir veri sızıntısıydı. O bir test, tüm çabanın maliyetini tek başına karşıladı.
Controller testimiz, “hızla bir sorgu ekleyeceğim” hareketini yakalar. Bu, genellikle teslimat baskısı altında daha sık olur.
// Bu mimari testi başarısız kılar
class ReportController extends Controller
{
public function index()
{
$total = DB::table()->sum();
return response()->json();
}
}
Env testinin, ilk günden eklemiş olsaydık keşke. Config dosyaları dışında env çağrılması, geliştirme aşamasında çalışıyor ve üretimde, konfigürasyon önbelleğe alındığında null dönüyor. Bu, klasik bir Laravel tuzağıdır. Test, bir daha buraya düşmenizi imkansız hale getirir.
Bunu Mevcut Bir Kod Tabanına Tanıtmak
Bunu Mevcut Bir Kod Tabanına Tanıtmak
Eğer sıkı mimari testleri büyük bir eski kod tabanına eklerseniz, hemen yüzlerce hata alırsınız. Takım bunu istemeyecek ve çaba duracaktır. İşte bizim için işe yarayan dağıtım süreci.
Bir kural ile başlayın. En önemli olanı. Bizim için bu, kiracı trait’i idi. Bunun birkaç ihlalini düzeltin ve sadece o kısmı birleştirin.
Daha sonra her hafta bir kural ekleyin. Takımın her birini sindirebilmesi ve mevcut ihlalleri düzeltmesi için yeterince yavaş.
Birçok eski ihlali olan bir kural için, eski kodu dışlamak için ignoring method’unu kullanın.
arch()
->expect()
->not->toUse()
->ignoring();
Bu, yıkıcı değişiklikler yapmadan eski kodları kendi takviminde yeniden yapılandırmanıza olanak tanır. Sonra, ignore istisnalarının sayısını takip edin. Bu sayı her sprint’te düşmelidir. Eğer yükselirse, yeni kod eski istisnaya yazılıyor ve bir problem var demektir.
Yaptığım Hata
Yaptığım Hata
On kuralı tek bir pull request içinde eklemeye çalıştım. Yapı, tüm kod tabanında ihlallerle dolup taştı. Bu göz korkutucuydu ve takım sert bir şekilde itiraz etti. Neredeyse bu fikri terk edecektim.
Kural eklemek tek tek yapılmalıdır, bu bir lüks değil. Gerçek bir projede bu yöntemi kullanmak tek yoldur. Kırmızı hatalar duvarı, insanların testleri silmesini ister. Tek bir yeni ihlal ise, insanların bir şeyi düzeltmesini ister.
Farklı Olarak Ne Yapardım
Farklı Olarak Ne Yapardım
Her yeni projenin ilk commit’inde mimari testler eklerdim. Mevcut bir kod tabanına eklemek, yalnızca takip işidir. Başlangıçtan itibaren kurallar uygulanır ve hiç ihlal birikimi olmaz.
Ayrıca, ortak testlerin bulunduğu küçük bir paylaşılan paket oluştururdum. Üç projede de neredeyse aynı mimari testleri yazdık. Tekrar kullanılır bir paket, bu çoğaltmayı önlerdi.
Samimi Değerlendirmem
Samimi Değerlendirmem
Mimari testler, kendi başına katı olma üzerine değildir. Amaç, kod tabanını öngörülebilir hale getirmektir.
Her kiracı modelinin provyetif olarak trait’e sahip olması, yalnızca bir umut değil; yapının doğruladığı bir gerçek. Hiçbir controller veritabanına dokunamıyorsa, hizmet katmanı gerçekten tek bir yolda işlemektedir. Bu garantiler, takım değiştiğinde ve kod tabanı büyüdüğünde bile geçerlidir, çünkü makine bunları her commit’te kontrol eder ve insan bunu hatırlamak zorunda değildir.
Takım kurallarınız, test kümenizde yer almalıdır. Bir wiki’deki kural, bir öneridir. CI’deki bir kural gerçektir.
Hangi kuralı önce test haline getirmek isterdiniz?
Kaynak: Orijinal Makale


