Mutasyon testi açıklandı
Spec: ISO/IEC/IEEE 29119-4 ISO/IEC/IEEE 29119-4 Spec: PHPUnit PHPUnit Evidence: Test-backed
Bir bakışta
“Bir bakışta” başlıklı bölümSatır kapsamı size bir satırın test paketi sırasında çalıştığını söyler. O satır yanlış olsaydı herhangi bir testin başarısız olup olmayacağını söylemez. Mutasyon testi, kodu bilinçli olarak bozup testlerin bunu fark edip etmediğini denetleyerek bu boşluğu kapatır. Bu sayfa, bir mutasyon puanının ne anlama geldiğini ve NextPDF’in bunu bir ödül olarak değil, tanı aracı olarak nasıl kullandığını açıklar.
Bunun neden önemli olduğu
“Bunun neden önemli olduğu” başlıklı bölümKapsam, testlerde en çok güvenilen metriklerden biridir ve aynı zamanda en yanıltıcı olanlardan biridir. Bir metodu çağıran ama hiçbir şeyi doğrulamayan bir test, o metottaki her satırı çalıştırır: kusursuz kapsam, sıfır tespit. Standart literatürü, kapsam ölçütleri arasındaki sıralamanın bunların hataları ortaya çıkarma yeteneği hakkında hiçbir gösterge vermediğini açıkça belirtir. Bu yetenek, standardın test etkinliği olarak adlandırdığı özelliktir (ISO/IEC/IEEE 29119-4, §C.2.4). Bir kapsam yüzdesi ile hata bulma garantisi farklı iddialardır.
Bir PDF motoru için bu, teorik bir konu değildir. Bir imza bayt-aralığı kontrolü, bir çapraz başvuru ofseti, bir kodlama dalı — testler önemli olan değeri hiç doğrulamadan bunların tümünü tamamen “kapsayabilir”. Zayıf testler üzerine kurulu yeşil bir paket, dürüst bir boşluktan daha kötüdür; çünkü herkesin oraya bakmasını fiilen caydırır.
Kısa özet
“Kısa özet” başlıklı bölüm- Mutasyon testi, kaynakta binlerce küçük ve bilinçli düzenleme (mutant) yapar — bir
<işlecini<=yapar, bir+işlecini-yapar, birreturndeğerini değiştirir — ve testleri her biri için yeniden çalıştırır. - Bir test bir mutant nedeniyle başarısız olursa, mutant öldürülür: bir test o davranışı gerçekten doğrulamıştır. Her test yine de geçerse, mutant kaçmıştır: davranış çalıştırılmış ama hiç kontrol edilmemiştir.
- Mutasyon Puanı Göstergesi, yani Mutation Score Indicator (MSI), kabaca, öldürülen mutantların toplam eşdeğer olmayan mutant sayısına oranıdır. Testlerinizin kodu çalıştırıp çalıştırmadığını değil, değişiklikleri tespit edip etmediğini ölçer.
- Bazı mutantlar eşdeğerdir — gözlemlenebilir davranışı değiştiremezler, bu yüzden hiçbir test onları öldüremez. Bunları başarısızlık olarak saymak dürüst değildir. NextPDF, bunları resmî olmayan biçimde göz ardı etmek yerine kanıtlar ve bir kayıt defterine işler.
- NextPDF, zayıf testleri bulmak ve güçlendirmek için MSI kullanır. Bu bir pazarlama rakamı değil, sürekli entegrasyondaki bir tanı geçididir.
NextPDF buna nasıl yaklaşıyor
“NextPDF buna nasıl yaklaşıyor” başlıklı bölümMutasyon, motora karşı Infection mutatörü ile çalıştırılır. Üretim kaynak ağacı üzerinde aritmetik, mantıksal, koşul-sınırı, eşitlik, dönüş-değeri ve kaldırma mutatör aileleri etkin olacak şekilde yapılandırılmıştır — tam da “çalıştırılmış ama doğrulanmamış” mantığını ortaya çıkaran işleçler. Süreç mekanik olarak ilerler:
- Start green The suite must pass before mutation begins.
- Mutate Apply one small, deliberate change to the source.
- Re-run Run the tests that cover the mutated line.
- Killed A test failed — the behaviour is genuinely asserted.
- Escaped All tests still pass — a weak spot to strengthen.
- Equivalent No test can kill it because behaviour is unchanged — proven and ledgered, not scored as a miss.
İki tasarım tercihi bu sayıyı güvenilir kılar. İlk olarak, puan bir geçit olarak bağlanmıştır. Sürekli entegrasyon, asgari bir MSI (ve asgari bir kapsanan-MSI) zorunlu kılar ve değişen satırlar üzerinde fark-kapsamlı bir varyant çalıştırır. Sonuç olarak, kod ekleyen ama gerçek doğrulamalar eklemeyen bir değişiklik, sonradan keşfedilmek yerine inceleme aşamasında yakalanır. İkinci olarak, NextPDF, sorunlu mutantları sessizce göz ardı etmez. Gerçekten anlamsal olarak eşdeğer olan mutantlar — örneğin katı tipleme her iki işlenenin de aynı tipi paylaştığını garanti ettiğinde !== ile != karşılaştırması — açık bir eşdeğerlik kanıtı testiyle birlikte bir mutasyon kayıt defterine kaydedilir. Sonuç olarak, kaçan mutant sayısı muhasebe oyununu değil, gerçek boşlukları yansıtır. Bu eşdeğerlik kanıtlarını sağlam kılan şey, PHPStan Level 10 ile birlikte strict_types ve tip bildirimli özelliklerdir.
Kanıtların söyledikleri
“Kanıtların söyledikleri” başlıklı bölümEvidence: Test-backed Mutasyon testi, motorda üretim kaynak dizinleri üzerinde davranışı açığa çıkaran mutatör aileleri etkin olacak şekilde yapılandırılmıştır. Asgari bir MSI ve fark-kapsamlı bir varyantla sürekli-entegrasyon geçidi olarak zorunlu kılınır. Bu, sonradan eklenmiş bir ayrıntı değil, bir derleme kontrolüdür.
Evidence: Test-backed Eşdeğer-mutant sorunu dürüst biçimde ele alınır. Anlamsal olarak eşdeğer mutantlar sınıflandırılır ve bir mutasyon kayıt defterindeki özel eşdeğerlik-kanıtı testleriyle desteklenir; her kanıtın sağlamlığı PHPStan Level 10 ile birlikte katı tiplemeye dayanır. Bu nedenle kaçan sayısı, puanı olduğundan kötü gösterecek şekilde şişirilmiş, öldürülemeyen gürültüyü değil, gerçek, tespit edilmemiş davranışı temsil eder.
Evidence: Standard-backed Mutasyon testi kabul görmüş bir tekniktir; NextPDF’e özgü bir icat değildir. Spec: ISO/IEC/IEEE 29119-4, §B.2.4 ISO/IEC/IEEE 29119-4 §B.2.4 test için belirli mutasyonlar türetmek amacıyla bir belirtimin öğelerine genel mutasyonların uygulanmasını tanımlar. Bu tekniğe ihtiyaç duyulmasının temel nedeni, aynı standardın kapsam ölçütlerinin kapsama (subsumes) sıralamasının onları hata-açığa-çıkarma yeteneğine göre sıralamadığını belirtmesidir (ISO/IEC/IEEE 29119-4, §C.2.4).
Evidence: Standard-backed Kapsamın kendisi iyi tanımlıdır ve sınırlıdır. Spec: PHPUnit PHPUnit satır, dal ve yol kapsamını birbirinden ayırır. Satır kapsamı yalnızca yürütülebilir bir satırın çalıştığını kaydeder. Bu tanımı bilmek, onun yetersizliğini açıkça gösterir.
Pratik örnek
“Pratik örnek” başlıklı bölümAsıl mesele komut değildir; kaçan bir mutantın size ne söylediğidir:
<?php
declare(strict_types=1);
final class ByteRange{ // Suppose the production guard is: // if ($offset < 0) { throw new InvalidByteRange(); } public function assertNonNegative(int $offset): void { if ($offset < 0) { throw new InvalidByteRange('offset must be >= 0'); } }}
// A test that EXECUTES this line but does not assert the boundary:// $byteRange->assertNonNegative(5); // no exception expected, none asserted// gives 100% line coverage of assertNonNegative().//// Mutation flips `< 0` to `<= 0`. Behaviour now differs ONLY at $offset === 0.// If no test passes 0 and asserts what happens, every test still passes:// the mutant ESCAPED. Coverage said "tested"; mutation said "the boundary// is unasserted". The fix is a test that pins offset === 0, not a higher// target.//// composer mutation:diff → mutate only changed lines, enforce min MSI// composer mutation:full → full-tree mutation gateKaçan mutantın bütün değeri burada yatar. Bir kapsam raporunun tamamen test edilmiş saydığı gerçek ve belirli bir eksik doğrulamayı ortaya çıkardı.
Yaygın yanlış anlama
“Yaygın yanlış anlama” başlıklı bölümEn yaygın yanlış anlama, mutasyon puanının en üst düzeye çıkarılması gereken bir not olduğudur. Mutantları öldürmek için test yazarak elde edilen çok yüksek bir MSI, doğrulama yapmadan metotları çağırarak elde edilen yüksek kapsam kadar içi boştur. Metrik artık manipüle edilmiştir ve tespiti ölçmemektedir. NextPDF, zayıf testleri bulmak için MSI kullanır. Sonuçta teslim edilen şey daha iyi doğrulamadır; övünmek açıkça amaç değildir.
İkinci yanlış anlama, hayatta kalan her mutantın testlerdeki bir kusur olduğudur. Bazı mutantlar gerçekten eşdeğerdir ve hiçbir test tarafından öldürülemez, çünkü gözlemlenebilir davranışı değiştirmezler. Bunları başarısızlık olarak ele almak, dürüst olmayan, yapay biçimde düşük bir puan üretir ve insanları raporu göz ardı etmeye alıştırır. NextPDF’in yanıtı, eşdeğerliği sessizce bastırmak ya da sayının kötü görünmesini kabullenmek değil, eşdeğerliği açıkça kanıtlamak ve kayıt defterine işlemektir.
Sınırlar ve kısıtlar
“Sınırlar ve kısıtlar” başlıklı bölümMutasyon testi, testlerin enjekte edilen değişiklikleri tespit edip etmediğini ölçer. Kodun doğru olduğunu kanıtlamaz. Performansı veya uygunluğu ölçmez. Gerçekten eşdeğer bir mutantı öldüremez. Güncel mutasyon puanı, yürürlükteki asgari-MSI eşiği, kayıt defterine işlenmiş eşdeğerlerin sayısı ve herhangi bir kapsam rakamı, sürekli-entegrasyon yapıtlarından üretilen ve derlemeyle birlikte yayımlanan canlı kalite sinyalleridir. Bunlar burada bilerek yer almaz, çünkü metne yapıştırılan bir sayı eskir ve küçük bir yalana dönüşür. Bu sayfanın belirttiği tek sabit gerçek PHPStan Level 10’dur ve bu, bir ölçüm değil, eşdeğerlik kanıtlarının dayandığı bir yapılandırma özelliğidir.
Mutatör seçimi, eşikler ve kayıt defteri politikası, motorun mutasyon yapılandırmasına aittir ve zamanla değişebilir. Bu yapılandırma herhangi bir zamanda bu sayfayla çelişirse, yetkili kaynak odur. Burada başka herhangi bir kütüphanenin test etkinliği hakkında hiçbir iddiada bulunulmaz.
İlgili belgeler
“İlgili belgeler” başlıklı bölüm- NextPDF test piramidi — testlerinin mutasyon testi tarafından gerçek hata tespiti açısından denetlendiği beş katman.
- Her yerde katı tipler — PHPStan Level 10 ve katı tiplemenin eşdeğer-mutant kanıtlarını nasıl sağlam kıldığı.
- Altın-dosya testi — tespit gücünün doğrulanmasına mutasyon testinin yardımcı olduğu bir başka katman.
Sözlük
“Sözlük” başlıklı bölüm- Mutant — test paketinin o değişikliği fark edip etmeyeceğini sınamak için kullanılan, kaynakta yapılmış bilinçli, küçük ve tekil bir değişiklik.
- Öldürülen mutant — en az bir testin başarısız olmasına neden olan bir mutant; davranış gerçekten doğrulanmıştır.
- Kaçan mutant — tüm testler geçerken hayatta kalan bir mutant. Davranış çalıştırılmış ama hiç doğrulanmamıştır — düzeltilmesi gereken zayıf bir nokta.
- Eşdeğer mutant — gözlemlenebilir davranışı değiştiremeyen, bu yüzden hiçbir testin öldüremediği bir mutant. NextPDF, bunları kanıtlar ve kayıt defterine işler.
- MSI (Mutation Score Indicator) — kabaca, öldürülen mutantların toplam eşdeğer olmayan mutant sayısına bölünmesi; çalıştırmanın değil, tespitin bir ölçüsü.
- Satır kapsamı — yalnızca yürütülebilir bir satırın test paketi sırasında çalıştığını kaydeden bir metrik; PHPUnit tarafından tanımlanır ve tek başına yetersizdir.