Birim Testlerindeki rastgele veriler?


136

Alanlarını rastgele verilerle dolduran nesneler için birim testleri yazan bir iş arkadaşım var. Onun nedeni, daha geniş bir test aralığı vermesidir, çünkü birçok farklı değeri test edecektir, normal bir test ise yalnızca tek bir statik değer kullanır.

Ona buna karşı bir dizi farklı sebep verdim, asıl olanlar:

  • rastgele değerler, testin gerçekten tekrarlanamayacağı anlamına gelir (ayrıca test rastgele başarısız olursa, derleme sunucusunda yapabilir ve derlemeyi bozabilir)
  • rastgele bir değer ve test başarısız olursa, a) nesneyi düzeltmemiz ve b) kendimizi bu değeri her seferinde test etmeye zorlamamız gerekir, bu yüzden işe yaradığını biliyoruz, ancak rastgele olduğu için değerin ne olduğunu bilmiyoruz

Başka bir iş arkadaşı ekledi:

  • Bir istisnayı test edersem, rastgele değerler testin beklenen durumda bitmesini sağlamaz
  • rastgele bir veri, ünite testleri için değil, bir sistemi temizlemek ve yük testi için kullanılır

Başka kimse ona bunu durdurmasını sağlamak için verebileceğim başka nedenler ekleyebilir mi?

(Veya alternatif olarak, bu birim testleri yazmak için kabul edilebilir bir yöntemdir ve ben ve diğer iş arkadaşım yanlış mıyım?)


32
"rastgele değerler testin gerçekten tekrarlanamayacağı anlamına gelir" doğru değildir, çünkü testler sahte rastgele sayılar kullanacaktır. Aynı başlangıç ​​tohumunu sağlayın, aynı "rastgele" test dizisini elde edin.
Raedwald

11
Anekdot: Bir keresinde bir CSV ihracat sınıfı yazdım ve rastgele testler, kontrol karakterleri bir hücrenin sonuna yerleştirildiğinde bir hata ortaya çıkardı. Rastgele test olmasaydı bunu bir test durumu olarak eklemeyi düşünmezdim. Her zaman başarısız oldu mu? Hayýr. Mükemmel bir test mi? Hayır. Bir hatayı yakalayıp düzeltmeme yardımcı oldu mu? Evet.
Tyzoid

1
Testler ayrıca kodun ne zaman girdi olarak beklendiğini ve çıktı olarak ne beklendiğini açıklamak için dokümantasyon görevi görebilir. Net keyfi veriler içeren bir teste sahip olmak, rastgele veri üreten koddan daha basit ve daha açıklayıcı olabilir.
splintor

Birim testiniz rastgele oluşturulmuş bir değer nedeniyle başarısız olursa ve bu değer bir iddianın parçası değilse, birim testinizde hata ayıklama konusunda iyi şanslar.
eriksmith200

Yanıtlar:


72

Bir uzlaşma var. İş arkadaşınız aslında bir şey üzerinde, ama bence yanlış yapıyor. Tamamen rastgele testlerin çok yararlı olduğundan emin değilim, ama kesinlikle geçersiz değil.

Bir program (veya birim) belirtimi, onu karşılayan bazı programların var olduğu hipotezidir. Programın kendisi bu hipotezin kanıtıdır. Birim testinin olması gereken, programın spesifikasyona göre çalıştığını çürütmek için karşı kanıt sağlama girişimidir.

Şimdi, birim testlerini elle yazabilirsiniz, ancak bu gerçekten mekanik bir görevdir. Otomatikleştirilebilir. Tek yapmanız gereken spesifikasyonu yazmaktır ve bir makine kodunuzu kırmaya çalışan çok sayıda ve çok sayıda birim testi üretebilir.

Hangi dili kullandığınızı bilmiyorum, ama buraya bakın:

Java http://functionaljava.org/

Scala (veya Java) http://github.com/rickynils/scalacheck

Haskell http://www.cs.chalmers.se/~rjmh/QuickCheck/

.NET: http://blogs.msdn.com/dsyme/archive/2008/08/09/fscheck-0-2.aspx

Bu araçlar, iyi biçimlendirilmiş spesifikasyonunuzu girdi olarak alır ve otomatik olarak oluşturulan verilerle otomatik olarak istediğiniz sayıda birim testi oluşturur. Kodunuzu kırmak ve uç durumları iyi kapsadığından emin olmak için mümkün olan en basit test senaryosunu bulmak için (küçültebileceğiniz) "küçülen" stratejileri kullanırlar.

Mutlu testler!


1
+ 1'leyin. ScalaCheck, minimize edilmiş, rastgele test verilerinin tekrarlanabilir bir şekilde üretilmesi için olağanüstü bir iş çıkarır.
Daniel Spiewak

17
Rastgele değil. Keyfi. Büyük fark :)
Apocalisp

reductiotest.org artık var gibi görünüyor ve Google beni başka bir yere yönlendirmedi. Şimdi nerede olduğu hakkında bir fikrin var mı?
Raedwald

Artık Fonksiyonel Java kütüphanesinin bir parçası. Bağlantı düzenlendi. Ama sadece Java kodunu test etmek için Scalacheck'i kullanırdım.
Apocalisp

ScalaCheck GitHub'a taşındı. Yanıt güncellenmiş bağlantı. Sadece Scala için değil, Java için de yararlıdır. (Eski bağlantı code.google.com/p/scalacheck idi )
RobertB

38

Bu tür testlere Maymun testi denir . Doğru yapıldığında, gerçekten karanlık köşelerden böcekleri içebilir.

Tekrar üretilebilirlik konusundaki endişelerinizi gidermek için: buna yaklaşmanın doğru yolu, başarısız test girişlerini kaydetmek, tüm aile için probları içeren bir birim testi oluşturmaktır. , belirli bir hatanın ; ve üniteye ilk arızaya neden olan belirli bir girişi (rastgele verilerden) dahil edin.


26

Burada, PRNG'nizi bir sabitle tohumlamak olan bazı kullanımları olan yarım yollu bir ev var. Bu, tekrarlanabilir 'rastgele' veriler oluşturmanıza olanak tanır.

Şahsen, testlerde (sabit) rastgele verilerin yararlı olduğu yerler olduğunu düşünüyorum - dikkatlice düşünülmüş tüm köşelerinizi yaptığınızı düşündükten sonra, bir PRNG'den uyaranları kullanmak bazen başka şeyler bulabilir.


4
Bu işi çok fazla kilitleme ve iş parçacığı olan bir sistemde gördüm. 'Rastgele' tohum, her çalıştırmada bir dosyaya yazılmıştır, daha sonra bir çalışma başarısız olursa, kodun izlediği yolu çalıştırabilir ve kaçırdığımız durum için bir el yazılı birim testi yazabiliriz.
Ian Ringrose

PRNG ne anlama geliyor?
systemovich

Yalancı Rasgele Sayı Üreteci
Will Dean

16

Güzel Kod kitabında , İkili Arama algoritması için bir test stratejisinden geçtiği "Güzel Testler" adlı bir bölüm vardır . Bir paragrafa, algoritmayı iyice test etmek için rastgele diziler oluşturduğu "Testlerin Rastgele Eylemleri" denir. Bunların bir kısmını çevrimiçi olarak Google Kitaplar, sayfa 95'de okuyabilirsiniz. , ancak sahip olmaya değer harika bir kitap.

Temel olarak bu sadece test için rastgele veri üretmenin uygun bir seçenek olduğunu göstermektedir.


16

Rastgele testlerden yanayım ve onları yazıyorum. Bununla birlikte, belirli bir yapı ortamında uygun olup olmadıkları ve hangi test paketlerine dahil edilmeleri gerektiği daha nüanslı bir sorudur.

Yerel olarak çalıştırın (örneğin, bir gece geliştirici kutunuzda) randomize testler hataları hem açık hem de belirsiz buldu. Belirsiz olanlar, rastgele testlerin onları temizlemek için gerçekten tek gerçekçi olduğunu düşündüğüm kadar gizlidir. Bir test olarak, randomize testlerle keşfedilen bir bulması zor bir hata aldım ve yarım düzine çatlak geliştiricisinin meydana geldiği işlevi (yaklaşık bir düzine kod satırı) gözden geçirdim. Hiçbiri tespit edemedi.

Rastgele verilere karşı argümanlarınızın çoğu, "test tekrarlanamaz" a lezzetidir. Bununla birlikte, iyi yazılmış bir randomize test, randomize tohumun başlatılması ve başarısızlıkla sonuçlanması için kullanılan tohumu yakalayacaktır. Testi elle tekrarlamanıza izin vermenin yanı sıra, bu test için tohumu kodlayarak belirli bir sorunu test eden önemsiz bir şekilde yeni bir test oluşturmanıza izin verir. Tabii ki, bu durumu kapsayan açık bir testi el ile kodlamak daha iyidir, ancak tembellik erdemleri vardır ve bu da başarısız bir tohumdan yeni test vakalarını otomatik olarak oluşturmanıza izin verir.

Ancak tartışamadığım bir nokta, bunun yapı sistemlerini bozmasıdır. Çoğu derleme ve sürekli entegrasyon testi, testlerin her seferinde aynı şeyi yapmasını bekler. Böylece rastgele başarısız olan bir test kaos yaratacak, rastgele başarısız olacak ve parmakları zararsız olan değişikliklere işaret edecektir.

Daha sonra bir çözüm, hala randomize testlerinizi yapı ve CI testlerinin bir parçası olarak çalıştırmak , ancak sabit sayıda yineleme için sabit bir tohumla çalıştırmaktır . Bu nedenle test her zaman aynı şeyi yapar, ancak yine de bir sürü girdi alanını araştırır (birden fazla yineleme için çalıştırırsanız).

Yerel olarak, örneğin, ilgili sınıfı değiştirirken, daha fazla yineleme veya diğer tohumlarla çalıştırmakta özgürsünüz. Rastgele test daha popüler hale gelirse, rastgele olduğu bilinen, farklı tohumlarla çalıştırılabilen (dolayısıyla zaman içinde artan kapsama alanı ile) ve başarısızlıkların aynı anlama gelmediği belirli bir test paketini bile hayal edebilirsiniz. deterministik CI sistemleri (yani, çalıştırmalar 1: 1 kod değişiklikleri ile ilişkili değildir ve bu yüzden bir şey başarısız olduğunda belirli bir değişikliğe parmağınızı işaret etmezsiniz).

Rastgele testler için söylenecek çok şey var, özellikle iyi yazılmış olanlar, bu yüzden onları reddetmek için çok hızlı olmayın!


14

Eğer TDD yapıyorsanız, rastgele verilerin mükemmel bir yaklaşım olduğunu iddia ediyorum. Testiniz sabitlerle yazılmışsa, kodunuzun yalnızca belirli bir değer için çalışacağını garanti edebilirsiniz. Testiniz oluşturma sunucusunda rastgele başarısız olursa, testin nasıl yazıldığına ilişkin bir sorun olabilir.

Rastgele veriler gelecekteki herhangi bir yeniden düzenleme işleminin sihirli bir sabite bağlı kalmamasını sağlayacaktır. Sonuçta, testleriniz belgelerinizse, sabitlerin varlığı yalnızca bu sabitler için çalışması gerektiği anlamına gelmez mi?

Ben abartılıyorum ama ben "bu değişkenin değeri bu testin sonucunu etkilememesi gerektiğini" bir işareti olarak testime rastgele veri enjekte tercih.

Ben rastgele bir değişken kullanırsanız o zaman testinizi bu değişkene göre çatal, o zaman bu bir koku olduğunu söyleyeceğim.


10

Testlere bakan biri için bir avantaj, keyfi verilerin açıkça önemli olmamasıdır. Düzinelerce veri içeren çok fazla test gördüm ve neyin bu şekilde olması gerektiğini ve bu şekilde ne olacağını söylemek zor olabilir. Örneğin, bir adres doğrulama yöntemi belirli bir posta kodu ile test edilmişse ve diğer tüm veriler rasgele ise, posta kodunun tek önemli kısım olduğundan emin olabilirsiniz.


9
  • rastgele bir değer ve test başarısız olursa, a) nesneyi düzeltmemiz ve b) kendimizi bu değeri her seferinde test etmeye zorlamamız gerekir, bu yüzden işe yaradığını biliyoruz, ancak rastgele olduğu için değerin ne olduğunu bilmiyoruz

Test durumunuz test ettiklerini doğru bir şekilde kaydetmezse, belki de test durumunu yeniden kodlamanız gerekir. Her zaman test durumları için başvurabileceğim günlüklere sahip olmak istiyorum, böylece statik veya rasgele veri kullanarak başarısız olmasına neden olanın tam olarak ne olduğunu biliyorum.


9

İş arkadaşınız bunu bilmese de bulanık test yapıyor . Özellikle sunucu sistemlerinde değerlidir.


2
ama bu birim testlerden temelde farklı bir şey değil mi? ve farklı bir zamanda mı yapıldı?
endolith

1
@endolith sizi belirli zamanlarda belirli testler yapmaya zorlayan bir fizik yasası yok
user253751

1
@immibis Ancak belirli zamanlarda belirli testler yapmak için iyi nedenler vardır. Bir kullanıcı "Tamam" düğmesini her tıkladığında bir birim test gerçekleştirmezsiniz.
endolith

5

Bir kez rastgele veri üretebilir misiniz (yani tam olarak bir kez, test çalışması başına bir kez değil), daha sonra tüm testlerde kullanın?

Hiç düşünmediğiniz vakaları test etmek için rastgele veri oluşturmanın değerini kesinlikle görebiliyorum, ama haklısınız, rastgele geçebilen veya başarısız olabilecek birim testlerine sahip olmak kötü bir şey.


5

Kendinize testinizin amacının ne olduğunu sormalısınız.
Birim testleri mantık, kod akışı ve nesne etkileşimlerini doğrulamakla ilgilidir. Rastgele değerler kullanmak farklı bir hedefe ulaşmaya çalışır, böylece test odağını ve basitliği azaltır. Okunabilirlik nedenleriyle (UUID, kimlikler, anahtarlar vb. Oluşturma) kabul edilebilir.
Özellikle birim testleri için, bu yöntem sorun bulmayı başardıktan sonra bile hatırlayamıyorum. Ancak rastgele değerlerle ve çoğunlukla rastgele tarihlerle akıllı olmaya çalışan birçok determinizm problemi (testlerde) gördüm.
Fuzz testi, entegrasyon testleri ve uçtan uca testler için geçerli bir yaklaşımdır .


Bulanıklaştırma için rasgele girdi kullanmanın, mümkün olduğunda kapsama güdümlü bulanıklaştırma için kötü bir alternatif olduğunu eklerim.
gobenji

1

Testleriniz için rasgele girdi kullanıyorsanız, değerlerin ne olduğunu görebilmeniz için girişleri kaydetmeniz gerekir. Bu şekilde karşılaştığınız bazı kenar durumlar varsa , bunu çoğaltmak test yazmak. Aynı nedenleri rastgele girdiler kullanmadıkları için duydum, ancak bir kez belirli bir test çalıştırması için kullanılan gerçek değerler hakkında fikir sahibi olduktan sonra o kadar da önemli değil.

"Keyfi" veri kavramı da önemli olmayan bir şeyi ifade etmenin bir yolu olarak çok kullanışlıdır . Elimizdeki testle ilgisi olmayan çok fazla gürültü verisinin olduğu durumlarda akla gelen bazı kabul testlerimiz var.


0

Nesnenize / uygulamanıza bağlı olarak, rastgele verilerin yük testinde bir yeri olacaktır. Verilerin sınır koşullarını açıkça test eden verileri kullanmak daha önemli olacaktır.


0

Bugün bununla karşılaştık. Sahte rasgele istedim (bu yüzden boyut açısından sıkıştırılmış ses verisi gibi görünecektir). Ben de deterministik istedim . rand (), OSX'te Linux'tan farklıydı. Ve tekrar tohumlamadığım sürece, her an değişebilir. Bu yüzden onu deterministik fakat yine de psuedo-random olarak değiştirdik: test, hazır verileri kullanmak kadar tekrarlanabilir, ancak daha rahat yazılmıştır.

Bu edilmiş DEĞİL kod yolları ile bazı rasgele kaba kuvvet ile test. Fark bu: hala deterministik, yine tekrarlanabilir, yine de karmaşık mantıkta uç durumlarda ilginç kontroller yapmak için gerçek girdiye benzeyen verileri kullanıyor. Hareketsiz birim testleri.

Bu hala uygun mu rastgele? Bira üzerine konuşalım. :-)


0

Test verisi problemine üç çözüm öngörebilirim:

  • Sabit verilerle test edin
  • Rasgele verilerle test edin
  • Rastgele veriler bir kez oluşturun , ardından sabit verileriniz olarak kullanın

Yukarıdakilerin tümünü yapmayı tavsiye ederim . Yani, beyninizi kullanarak çalıştığınız bazı kenar vakaları ve yalnızca bir kez oluşturduğunuz bazı rastgele verilerle tekrarlanabilir birim testleri yazın. Çalıştırmak olduğunu Ardından randomize bir dizi test yazma yanı .

Rastgele testlerin asla tekrarlanabilir testlerin kaçırdığı bir şeyi yakalaması beklenmemelidir. Her şeyi tekrarlanabilir testlerle kapsamayı hedeflemeli ve randomize testleri bir bonus olarak düşünmelisiniz. Eğer bir şey bulurlarsa, makul bir şekilde tahmin edemeyeceğiniz bir şey olmalıdır; gerçek bir tuhaflık.


-2

Adamınız, düzeltip düzeltmediğini göremediğinde testi tekrar yapabilir mi? Yani testlerin tekrarlanabilirliğini kaybeder.

Muhtemelen testlerde rastgele bir veri yükü atmak için bir değer olduğunu düşünürken, diğer cevaplarda belirtildiği gibi, yük testi başlığı altında her şeyden daha fazla düşer. Bu neredeyse bir "umutla test etme" uygulamasıdır. Bence, gerçekte, adamınız sadece neyi test etmeye çalıştığını düşünmüyor ve rastgele düşünceyi umarak bu düşünce eksikliğini telafi etmek sonunda bazı gizemli hataları yakalayacaktır.

Onunla kullanacağım argümanı tembel olması. Ya da başka bir deyişle, neyi test etmeye çalıştığını anlamak için zaman ayırmazsa, muhtemelen yazdığı kodu gerçekten anlamadığını gösterir.


3
Testin yeniden üretilebilmesi için rastgele verilerin veya rastgele tohumun kaydedilmesi mümkündür.
cbp
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.