Test: deterministik mi, deterministik mi?


16

Birine sahip olmak daha mı iyi

  • Aynı testlerin başarılı olmasını sağlayan deterministik test takımı
  • Potansiyel olarak daha fazla vakayı kapsayan belirleyici olmayan test paketi

?

Örnek: Bir MVC uygulamasında denetleyici işlevini test etmek için bir test takımı yazarsınız. Denetleyici, test sırasında giriş olarak bir veritabanından uygulama verisi gerektirir. Bunu yapmak için iki seçenek vardır:

  • Test veritabanından hangi satırların giriş olarak seçildiğini sabit kodlarsınız (örneğin 10. ve 412. Satır)
  • Verileri veritabanından (rastgele bir sayı üreteci tarafından seçilen iki satır) sözde rastgele almak için rasgele bir sayı üreteci kullanırsınız

Birincisi deterministiktir: aynı kod revizyonu için testin her çalışması aynı sonucu vermelidir. İkincisi deterministik değildir: test takımının her çalışması farklı bir sonuç verebilir. Ancak rastgele seçilen veriler, veri kenarı vakalarının daha iyi bir temsili olabilir. Kontrolörlerimizi öngörülemeyen verilerle daha iyi besleyen bir kullanıcıyı simüle edebilir mi?

Birini diğerinden seçmenin nedenleri nelerdir?


5
Bu test bazen başarısız oluyor. martinfowler.com/articles/nonDeterminism.html

Bu bağlantı için teşekkürler. Bu makaleyi göz önünde bulundurarak, determinizmin bu test takımı bağlamında ne anlama geldiğini açıklığa kavuşturmam gerektiğini hissettim. Veri bir veritabanından rastgele seçildiğinden, denetleyiciye beslenen tüm veriler varsayılan olarak geçerli verilerdir. Bu, determinizm söz konusu olmadığında test takımında yanlış negatiflerin bulunmadığı anlamına gelir. Bir bakıma, bu rastgelelik bir kullanıcının bir denetleyicide kullanılmak üzere 'rastgele' veri seçmesini simüle eder. Bu, makalenin tartıştığı determinizm ile aynı olmayabilir, değil mi?
DCKing


10
@DCKing: Testiniz başarısız olursa ne olacağını düşünün. Tamam, bir hatan var. Şimdi ne olacak? Hata ayıklama modunda tekrar çalıştırın! Nerede başarılı! Sanki sonraki yüz seferde yaptığı gibi, ve sonra sorunu kozmik bir ışın grevi olarak yazıyorsunuz. Testlerde determinisim kesinlikle işe yaramaz geliyor. Test durumlarınızda daha fazla toprak kaplaması gerektiğini düşünüyorsanız, daha fazla toprak kaplayın. RNG'nizi ayarlanmış bir tohumla başlatın ve sürekli olarak rastgele değerlerle "testi" birkaç yüz kez çalıştırın.
Phoshi

1
(sonunda düzgün bir şekilde twitter arayabileceğim bir makineye vardım - " Bu test bazen başarısız oluyor " Twitter'daki #FiveWordTechHorrors - düzgün kredi vermek istedim)

Yanıtlar:


30

Test paketinin her çalışması size farklı bir sonuç vermenizi sağladığında, test neredeyse tamamen değersizdir - paket size bir hata gösterdiğinde, onu yeniden üretememe şansınız yüksektir ve düzeltmeye çalıştığınızda hata, düzeltmenizin işe yarayıp yaramadığını doğrulayamazsınız.

Bu nedenle, test verilerinizi oluşturmak için bir tür rasgele sayı üreteci kullanmanız gerektiğini düşündüğünüzde, jeneratörü her zaman aynı tohumla başlattığınızdan emin olun veya rastgele test verilerinizi testinize vermeden önce bir dosyada saklayın, böylece testi önceki çalıştırmadan tamamen aynı verilerle tekrar çalıştırabilirsiniz. Bu şekilde, deterministik olmayan herhangi bir testi deterministik bir teste dönüştürebilirsiniz.

DÜZENLEME: Bazı test verilerini almak için rasgele bir sayı üreteci kullanmak IMHO bazen iyi test verilerini seçmek konusunda çok tembel olmak için bir işarettir . 100.000 rastgele seçilen test değerlerini atmak yerine, bunun şans eseri tüm ciddi hataları keşfetmek, beyninizi daha iyi kullanmak, 10 ila 20 "ilginç" vaka seçmek ve bunları test paketi için kullanmak için yeterli olacağını umuyoruz. Bu sadece testlerinizin daha kaliteli olmasını sağlamakla kalmaz, aynı zamanda paketin çok daha yüksek performansıyla da sonuçlanır.


Cevabınız için teşekkürler. Soruma yaptığım yorum hakkında ne düşünüyorsun?
DCKing

1
@DCKing: Rastgele bir oluşturucunun sizden iyi test senaryoları seçmede gerçekten daha iyi olacağını düşünüyorsanız (şüpheliyim), programınızın başarısız olduğu test verilerinin kombinasyonlarını bulmak için bir kez kullanın ve bu kombinasyonları "sabit kodlu" kısma koyun test takımınızın.
Doc Brown

Tekrar teşekkürler. Cevabım sadece MVC uygulamalarına uygulanmayacak şekilde güncellendi.
DCKing

1
Rastgele tuş girişi üreten test programlarına sahip bazı UI bağlamlarında (örneğin, denetleyici girdisi alan oyunlar) stres testi için yararlı olabilir. Kasıtlı girdi ile bulunması zor kusurları ortaya çıkarabilirler.
Robot Gort

@StevenBurnap: Evet, soruyu anlama şeklimde, OP'nin akılda daha geleneksel regresyon testi olduğunu düşünüyorum. Tabii ki, katılıyorum, stres testi de donanıma bağlı olabilecek ve rastgele bir jeneratör kullanmasanız bile belirleyici olmayan davranışlarla sonuçlanabilecek özel bir durumdur. Bu, sorunun altındaki ilk yorumda MichaelT tarafından bağlantılı makalede açıklanan bir şey. Ve rastgele girdi ile stres testinde bile, en azından tanımlanmış bir rastgele tohum kullanarak davranışı daha belirleyici hale getirmeye çalışılabilir.
Doc Brown

4

Hem deterministik hem de deterministik olmayanların bir yeri vardır

Onları şu şekilde bölebilirim:

Birim testleri.

Bunlar her seferinde aynı verilerle belirleyici, tekrarlanabilir testlere sahip olmalıdır. Birim testleri belirli, ayrı ayrı kod bölümlerine eşlik eder ve bunları deterministik bir şekilde test etmelidir.

Fonksiyonel ve giriş gerilme testleri.

Bunlar, aşağıdaki uyarılarla deterministik olmayan yaklaşımı kullanabilir:

  • bu gerçek açıkça tanımlanmış ve çağrılmıştır
  • seçilen rastgele değerler günlüğe kaydedilir ve manuel olarak tekrar denenebilir

3

Her ikisi de.

Deterministik ve belirsiz olmayan testler, süitiniz için farklı kullanım durumlarına ve farklı değerlere sahiptir. Genel olarak belirsiz olmayan, yavaş yavaş "belirsiz olmayan test hiçbir değer sağlamaz" haline gelen deterministik test ile aynı hassasiyeti sağlayamaz. Bu yanlış. Daha az hassas olabilirler, ancak kendi yararları olan çok daha geniş olabilirler.

Bir örnek verelim: tamsayıların listesini sıralayan bir işlev yazıyorsunuz. Yararlı bulacağınız deterministik birim testlerden bazıları ne olurdu?

  • Boş bir liste
  • Yalnızca bir öğeye sahip bir liste
  • Aynı öğenin tümünü içeren bir liste
  • Birden fazla benzersiz öğeye sahip bir liste
  • Bazıları yinelenen birden çok öğeye sahip bir liste
  • Bir liste ile NaN, INT_MINveINT_MAX
  • Kısmen sıralanmış bir liste
  • 10.000.000 öğeden oluşan bir liste

Ve bu sadece bir sıralama işlevi! Elbette, bunlardan bazılarının gereksiz olduğunu veya bazılarının gayri resmi akıl yürütme ile dışlanabileceğini iddia edebilirsiniz. Ama biz mühendisiz ve gayri resmi akıl yürütmenin yüzümüzde patladığını gördük. İnşa ettiğimiz sistemleri tamamen anlayabilecek kadar akıllı olmadığımızı veya karmaşıklığı tamamen kafamızda tuttuğumuzu biliyoruz. Bu yüzden ilk etapta testler yazıyoruz. Belirsiz testler eklemek, tüm iyi testleri bir a priori'yi tanımaya yetecek kadar akıllı olamayacağımızı söylüyor. Yarı rastgele verileri işlevinize atayarak, kaçırdığınız bir kenar durumu bulma olasılığınız çok daha yüksektir.

Tabii ki, bu deterministik testi de dışlamaz. Belirsiz testler, programın büyük alanlarındaki hataları bulmanıza yardımcı olur. Ancak hataları bulduğunuzda, düzelttiğinizi göstermek için yeniden üretilebilir bir yola ihtiyacınız vardır. Yani:

  • Kodunuzdaki hataları bulmak için belirsiz olmayan testleri kullanın .
  • Kodunuzdaki düzeltmeleri doğrulamak için deterministik testleri kullanın .

Bunun, birim testleri hakkında çok sayıda sağlam tavsiyenin, belirsiz olmayan testler için geçerli olmadığı anlamına geldiğini unutmayın. Örneğin, hızlı olmaları gerekir. Düşük seviyeli özellik testleri hızlı olmalı, ancak "web sitenizdeki düğmeleri rastgele tıklayan bir kullanıcıyı simüle et ve asla 500 hatası almadığınızdan emin olun" gibi belirsiz olmayan bir test, hız üzerinde kapsamlılığı desteklemelidir. Yapım sürecinizden bağımsız olarak böyle bir test yapın, böylece gelişimi yavaşlatmaz. Örneğin, kendi özel sahneleme kutusunda çalıştırın.


-1

Gerçekten deterministik ve deterministik olmak istemezsiniz.

İsteyebileceğiniz şey "her zaman aynıdır" vs. "her zaman aynı değildir".

Örneğin, her derlemeyle birlikte artan bir derleme numaranız olabilir ve bazı rasgele sayılar istediğinizde, derleme numarasını tohum olarak içeren rastgele bir sayı üreteci başlatabilirsiniz. Böylece her derleme, testlerinizi farklı değerlerle yaparsınız, size hata bulma şansı verir.

Ancak bir hata bulunduğunda, tek yapmanız gereken testi aynı yapı numarasıyla çalıştırmaktır ve tekrarlanabilir.


1
Ya da kullanılacak bir yapı numaranız yoksa, tohumun başlangıç ​​değerini test çalışmasının çıktısına yerleştirin, böylece testleri aynı tohumla tekrar çalıştırabilirsiniz.
RemcoGerlich
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.