Varlıklar veya birim testleri daha mı önemli?


51

Hem iddialar hem de birim testleri bir kod temeli için dokümantasyon ve hataları keşfetme aracı olarak işlev görür. Başlıca farklar, varsayımların aklılık kontrolü olarak işlev görmesi ve gerçek girdileri görmesidir; oysa birim testleri belirli benzetilmiş girdilerde çalışır ve iyi tanımlanmış tek bir "doğru cevap" a karşı yapılan testlerdir. Doğruluk doğrulamanın ana aracı olarak assant vs. birim testlerini kullanmanın göreceli değerleri nelerdir? Hangisine daha çok vurgu yapılması gerektiğine inanıyorsunuz?


4
Bu fikri çok beğendim ... bu yüzden, konuyu yazılım testim ve kalite güvence kursum için bir ödev haline getiriyorum. :-)
Macneil

Başka bir soru şudur: Varlıklarınızı test etmeli misiniz? ;)
mojuba

Yanıtlar:


43

Varlıklar size programın iç durumunu anlatmak için kullanışlıdır . Örneğin, veri yapılarınızın geçerli bir durumu olduğu, örneğin bir Timeveri yapısının değerini tutamayacağı 25:61:61. Varlıklar tarafından kontrol edilen koşullar:

  • Arayanın kontratını korumasını sağlayan ön şartlar,

  • Callee'nin sözleşmesini koruduğunu garanti eden post Koşullar, ve

  • Veri yapısının, fonksiyon döndürüldükten sonra daima bir özellik tutmasını sağlayan değişmezler. Bir değişmez, önkoşul ve sonkoşul olan bir durumdur.

Birim testleri , modülün dış davranışını anlatmak için kullanışlıdır . Sizin Stacksonrasında tutarlı bir devlet olabilir push()yöntemi denir, ancak üç kez çağrıldıktan sonra yığının boyutu üçe artmaz eğer, o zaman bu bir hatadır. (Örneğin, yanlış push()uygulamanın yalnızca iddiaları ve çıkışları kontrol ettiği önemsiz durum .)

Açıkça söylemek gerekirse, varsayımlar ve ünite testleri arasındaki en büyük fark, ünite testlerinin test verisine sahip olması (programın çalışmasını sağlayacak değerler) olmasıdır. Yani, ünite testlerinizi otomatik olarak yapabilir, iddialar için de aynı şeyi söyleyemezsiniz. Bu tartışma uğruna, programı üst düzey işlev testleri bağlamında yürütmekten bahsettiğinizi varsaydım (tüm programı yürüten ve birim sınamaları gibi modüller kullanma). "Gerçek girdileri görmek" için otomatik işlev testlerinden bahsetmiyorsanız, değer açıkça otomasyondadır ve böylelikle ünite testleri kazanacaktır. Bu konuda (otomatik) fonksiyon testleri bağlamında konuşuyorsanız, aşağıya bakın.

Test edilmekte olan bazı örtüşme olabilir. Örneğin, bir Stack'' şart koşulu aslında yığın boyutunun bir kat arttığını iddia edebilir. Ancak bu iddiada neler yapılabileceğine dair sınırlamalar var: Ayrıca en üstteki öğenin yeni eklenenler olup olmadığını da kontrol etmeli mi?

Her ikisi için de amaç kaliteyi arttırmaktır. Ünite testi için amaç hataları bulmaktır. İddialar için amaç, geçersiz program durumlarını en kısa sürede gözlemleyerek hata ayıklamayı kolaylaştırmaktır.

Her iki tekniğin de doğruluğunu onaylamadığını unutmayın. Aslında, programın doğru olduğunu doğrulamak amacıyla birim testini gerçekleştirirseniz, işe yarayacağını bildiğiniz ilginç olmayan bir testle karşılaşacaksınız. Bu psikolojik bir etki: hedefinize ulaşmak için ne gerekiyorsa yapacaksınız. Amacınız böcek bulmaksa, faaliyetleriniz bunu yansıtacaktır.

Her ikisi de önemlidir ve kendi amaçları vardır.

[İddialarla ilgili son not: En fazla değeri elde etmek için, bunları birkaç temel işlev yerine, programınızdaki tüm kritik noktalarda kullanmanız gerekir. Aksi halde, sorunun orijinal kaynağı maskelenmiş olabilir ve saatlerce hata ayıklama yapmadan algılaması zor olabilir.]


7

İddialardan bahsederken, onların bir anahtar hareketiyle kapatılabileceğini unutmayın.

Çok kötü bir iddia örneği:

char *c = malloc(1024);
assert(c != NULL);

Bu neden kötü? Çünkü, NDEBUG tanımlandığı gibi bir şey nedeniyle bu iddia atlanırsa hata kontrolü yapılmaz.

Bir birim testi (muhtemelen) sadece yukarıdaki kodda hata yapar. Tabii, size bir şeylerin yanlış gittiğini söyleyerek işini yaptı mı? malloc()Testte başarısız olma olasılığı ne kadardır ?

İddialar, bir programcının “normal” bir olayın iddianın ateşlenmesine yol açmayacağını ima etmesi gerektiğinde hata ayıklama amaçlıdır. malloc()başarısız olmak, aslında normal bir olaydır, bu yüzden asla iddia edilmemelidir.

Yanlış gidebilecek şeyleri uygun şekilde ele almak yerine iddiaların kullanıldığı birçok başka durum vardır. Bu nedenle iddiaların kötü bir üne sahip olması ve Go gibi dillerin neden bunları içermediği.

Birim testleri, değiştirdiğiniz bir şeyin başka bir şeyi ne zaman parçaladığını size söylemek için tasarlanmıştır. Bir derleme yaptığınızda , sizi (çoğu durumda) programın her özelliğinden (ancak sürümler sürümler için önemlidir ) geçmekten kurtarmak için tasarlanmıştır .

İkisi arasında, bir şeylerin yanlış gittiğini söylemekten başka hiçbir farkı yoktur. Üzerinde çalışmakta olduğunuz bir hata ayıklayıcısını kullanmak zorunda kalmayacağınızı, bir hata ayıklayıcı olarak düşünün. Bir şeyi kırdı eğer söyler şey olarak bir birim testinin düşünün değildir üzerinde çalışıyor.


3
Bu yüzden iddiaların her zaman doğru ifadeler olması gerekiyor, hata testi değil.
Dominique McDonnell

@DominicMcDonnell Peki, 'doğru olmalı' ifadeleri. Bazen böyle bir arabası abs () yerleşik olan gcc belirli sürümleri gibi derleyici tuhaflıklar etrafında almak iddia. Hatırlanması gereken önemli şey üretim onları kapalı olmalıdır kurar olduğunu zaten .
Tim Post

Ve burada üretim kodu iddia ihtiyacı yer olduğunu düşünüyorum çoğu size mümkün düşünmüyordu girdileri alacak nereye üretimde, çünkü. Yapım, en zor çıkanları gideren yer.
Frank Shearar

@ Frank Shearar, çok doğru. Üretimde tespit edilen en erken hata durumunda hala çok başarısız olmalısınız. Kullanıcıların şikayet edeceğinden emin olun, ancak hataların giderileceğinden emin olmanın tek yolu budur. Ve bir blah almak için çok daha iyi bir kaç işlev çağrısı sonra sıfırlanmasına izin vermemek için bir bellek istisnasından 0 olmuştu.
Dominique McDonnell

neden olmasınlar diye iddia etmek yerine tipik ancak genellikle nadir görülen (kullanıcının gözünde) sorunları ele almak daha iyi değildir? Bu bilgeliği farkedemiyorum. Elbette, bir ana jeneratörün, hata ayıklama oluşturma işleminde beklenen bir miktar ekstra iş gerektiren bir asal sayı döndürdüğünü iddia edin. Bir dilin doğal olarak test edebileceği bir şeyi iddia etmek sadece, iyi, aptalcadır. Bu testleri, salıverilmesinden birkaç ay sonra, daha da aptalca kapatılabilen başka bir anahtara sarmamak.
Tim Mesaj

5

Her ikisi de, kurduğunuz sistemin genel kalitesini iyileştirmeye yardımcı olmak için kullanılan araçlardır. Çok şey, kullandığınız dile, oluşturduğunuz uygulamanın türüne ve zamanınızın en iyi olduğu yere bağlıdır. Bahsetmiyorum bile, bunun hakkında birkaç düşünce okulun var.

Başlamak için, eğer assertanahtar kelimesiz bir dil kullanıyorsanız , iddiaları kullanamazsınız (en azından burada konuştuğumuz şekilde değil). Uzun süredir, Java bir assertanahtar kelimeye sahip değildi ve hala birçok dilde yoktu. Birim testi daha sonra biraz daha önemli hale gelir. Bazı dillerde iddialar sadece bir bayrak belirlendiğinde çalıştırılır (burada yine Java ile). Korumalar her zaman orada olmadığında, çok kullanışlı bir özellik değildir.

Bir şey "iddia" eğer siz de bir yazabiliriz diyor düşünce bir okul yoktur if/ throwanlamlı istisna blok. Bu düşünce süreci, tüm değerlerin sınırda olduğundan emin olmak için bir yöntemin başına yerleştirilen birçok varsayımdan gelir. Önkoşullarınızı test etmek, önkoşul olması beklenen çok önemli bir parçadır.

Birim testi, yazılması ve bakımı gereken ekstra bir koddur. Çoğu için bu bir dezavantajdır. Bununla birlikte, mevcut birim test çerçevelerinin ekiniyle, nispeten az kodla daha fazla sayıda test koşulu oluşturabilirsiniz. Parametrelenmiş testler ve "teoriler" aynı testi gerçekleştirerek, bazı hataları bulmakta zorlanabilecek çok sayıda veri örneğiyle aynı testi gerçekleştirecektir.

Şahsen, serpme varsayımlarından ziyade birim testiyle daha fazla kilometre alıyorum, ancak bunun nedeni çoğu zaman geliştirdiğim platformlar (Java / C #). Diğer diller daha güçlü bir iddiaya sahiptir ve hatta daha fazla garanti sağlamak için "Sözleşme ile Tasarım" (aşağıya bakınız) bile vardır. Bu dillerden biriyle çalışıyor olsaydım, DBC'yi birim testinden daha fazla kullanabilirdim.

http://en.wikipedia.org/wiki/Design_by_contract#Languages_with_native_support

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.