Bir IF ifadesinde birden fazla koşulu test eden birim


26

Buna benzeyen bir kod parçası var:

function bool PassesBusinessRules()
{
    bool meetsBusinessRules = false;

    if (PassesBusinessRule1 
         && PassesBusinessRule2
         && PassesBusinessRule3)
    {
         meetsBusinessRules= true;
    }

    return meetsBusinessRules;
}

Bu fonksiyon için dört birim testinin yapılması gerektiğine inanıyorum. If ifadesindeki koşulların her birini test etmek ve yanlış döndürdüğünden emin olmak için üçü. Ve işlevin doğru döndüğünden emin olan başka bir test.

Soru: Bunun yerine on birim test yapılmalı mı? Her olası arıza yolunu kontrol eden dokuz kişi. IE:

  • Yanlış Yanlış Yanlış
  • Yanlış Yanlış Doğru
  • Yanlış Doğru Yanlış

Ve böylece her olası kombinasyon için.

Bence bu aşırı, ama ekibimdeki diğer üyelerin bazıları yok. Bakmamın yolu, BusinessRule1'in başarısız olması durumunda daima yanlışa dönmesidir, ilk önce mi yoksa son mu kontrol edildiğinin önemi yoktur.


Derleyici, && operatörü için açgözlü değerlendirme kullanıyor mu?
suszterpatt

12
10 birim testi yazdıysanız, yöntemlerinizi değil, & & işleçinizi test edeceksiniz.
Mert Akcakaya,

2
Bütün olası kombinasyonları test etsen sadece sekiz test olmaz mıydı? Üç boolean parametre ya açıldı ya da kapandı.
Kris Harper,

3
@Mert: Yalnızca && 'nin daima orada olacağını garanti ederseniz.
Misko

Hickey: Testler yazmak için harcıyorsak, o zaman başka bir şey yapmak için harcamadığımız zamandır. Her birimiz, sonuçlarımızı hem nicelik hem de nitelik olarak en üst düzeye çıkarmak için zamanımızı en iyi şekilde nasıl harcayacağımızı değerlendirmek gerekiyor. Eğer insanlar zamanlarının yüzde ellisini test yazma harcadıklarının sonuçlarını en üst düzeye çıkardığını düşünüyorlarsa - onlar için tamam. Bunun benim için doğru olmadığından eminim - o zaman sorunumu düşünerek geçirmeyi tercih ederim. Benim için bunun zamanımın diğer kullanımlarından daha az hatayla daha iyi çözümler ürettiğinden eminim. Komple bir test paketi ile kötü bir tasarım hala kötü bir tasarımdır.
Meslek

Yanıtlar:


29

Resmen, bu kapsama türlerinin isimleri vardır.

İlk olarak, kestirim kapsamı var : if ifadesini doğrulayan ve yanlış kılan bir test vakasına sahip olmak istiyorsunuz. Bu kapsamın karşılanması muhtemelen iyi bir test paketi için temel bir gereksinimdir.

Sonra orada Durum Kapsamı : Burada, eğer her bir alt-koşulun doğru ve yanlış değerine sahip olduğunu test etmek istiyorsunuz. Bu açıkça daha fazla test yaratır, ancak genellikle daha fazla hata yakalar, bu nedenle vaktiniz varsa test takımınıza dahil etmek genellikle iyi bir fikirdir.

En gelişmiş kapsam kriterleri genellikle Kombinatoryal Koşul Kapsamı olarak adlandırılır : Burada amaç, testinizde olası tüm boole değer kombinasyonlarını içeren bir test senaryosuna sahip olmaktır .

Bu basit yüklem veya durumun kapsamından daha mı iyidir? Elbette kapsama açısından. Ama bedava değil. Test bakımında çok yüksek bir maliyetle geliyor. Bu nedenle çoğu insan tam kombinasyon kapsamı ile uğraşmaz. Genellikle tüm dalları (veya tüm koşulları) test etmek, böcekleri yakalamak için yeterli olacaktır. Kombinasyonel test için ekstra testler eklemek, genellikle daha fazla hata yakalamaz, ancak yaratmak ve sürdürmek için çok çaba gerektirir. Ekstra çaba genellikle bu işi çok küçük bir kazanıma değmez, bu yüzden bunu tavsiye etmem.

Bu kararın bir kısmı, kodun ne kadar riskli olacağını düşündüğünüze dayanmalıdır. Başarısızlığı olacak çok fazla odası varsa test etmeye değer. Biraz kararlıysa ve çok fazla değişmeyecekse, test çalışmalarınızı başka bir yere odaklamayı düşünmelisiniz.


2
Eğer boolean değerler dış kaynaklardan geçiyorsa (yani her zaman doğrulanmadıkları anlamına gelir), o zaman kombinatoryal şartlı kapsam genellikle gereklidir. İlk önce kombinasyonların bir tablosunu yapın. Ardından, her giriş için, o girişin anlamlı bir kullanım durumu olup olmadığını kararlaştırın. Değilse, bu kombinasyonun yürütülmesini önlemek için bir yerde kod (yazılım iddiaları veya doğrulama maddesi) bulunmalıdır. Önemli olan değil tek kombinasyon testte tüm parametreleri götürü için: bölüm parametrelerine denemek gruba birbirlerine yani hisseleri ile etkileşim aynı mantıksal ifade.
rwong

Kalın yazılmış terimlerden ne kadar eminsin? Cevabınız "Kombinatoryal Durum Kapsamı" nın tek oluşumu gibi görünüyor ve bazı kaynaklar "kapsamı öngörme" ve "şartlı kapsamın" aynı şey olduğunu söylüyor.
Stijn

8

Sonuçta, size (takım), yönetmeliğe ve belirli proje ortamına bağlıdır. Evrensel bir kural yoktur. Siz (r ekibi) kodun gerçekten doğru olduğundan emin olmak için ihtiyaç duyduğunuz kadar çok test yazmalısınız . Eğer takım arkadaşlarınız 4 testle ikna olmamışsa, belki daha fazlasına ihtiyacınız vardır.

OTOH birim testleri yazmak için genellikle kıt bir kaynaktır. Bu yüzden sınırlı zaman harcamak için en iyi yolu bulmak için çaba gösterin . Örneğin,% 0 kapsama sahip başka bir önemli yönteminiz varsa, bu yöntem için ekstra testler eklemek yerine, bunu kapsayacak birkaç birim test yazmak daha iyi olabilir. Tabii ki, her birinin uygulanmasının ne kadar hassas olduğuna da bağlı. Öngörülebilir gelecekte bu özel yöntemde birçok değişiklik planlamak, ekstra birim test kapsamını haklı gösterebilir. Yani programın içinde kritik bir yolda olabilir. Bunların hepsi sadece sizin (takım) değerlendirebileceğiniz faktörlerdir.

Şahsen ben genellikle sizin belirlediğiniz 4 testten memnun olurum, yani:

  • doğru yanlış yanlış
  • yanlış doğru yanlış
  • yanlış yanlış doğru
  • doğru doğru doğru

artı belki bir:

  • doğru doğru yanlış

Bir geri dönüş değeri elde etmenin tek yolunun truetüm 3 iş kuralını yerine getirmektir. Fakat sonuçta, eğer takım arkadaşlarınız birleştirici yolları kapatacak konusunda ısrar ederse, bu ekstra testleri eklemek tartışmaya daha uzun süre devam etmekten daha ucuz olabilir. :-)


3

Güvende olmak istiyorsanız, üç değişkenli bir doğruluk tablosu ile gösterilen koşulları kullanarak sekiz birim testine ihtiyacınız olacaktır ( http://teach.valdosta.edu/plmoch/MATH4161/Spring%202004/and_or_if_files/image006.gif ).

İş mantığının her zaman kontrollerin bu sıraya göre yapıldığını şart koşacağından asla emin olamazsınız ve testin mümkün olan en az gerçek uygulama hakkında çok az şey bilmesini istersiniz.


2
Birim test olan beyaz kutu testi.
Péter Török

Peki sipariş önemli olmamalı, && iletişimsel olmalı ya da en azından öyle olmalı
Zachary K

2

Evet, ideal bir dünyada tam kombinasyon olmalı.

Birim testi yaparken, yöntemin nasıl çalıştığını gerçekten görmezden gelmelisiniz . Basitçe 3 giriş sağlayın ve çıkışın doğru olduğunu onaylayın.


1
Birim test olan beyaz kutu testi. Ve biz ideal bir dünyada yaşamıyoruz.
Péter Török

PéterTörök @ - Emin olmak için ideal bir dünyada değil canlı, ama Stack Exchange diğer noktada sizinle aynı fikirde değil. Özellikle TDD için, testler uygulamaya değil şartnamelere göre yazılmıştır. Tüm girdileri (üye değişkenleri dahil) ve tüm çıktıları (yan etkiler dahil) dahil etmek için şahsen 'şartname' alıyorum.
Telastyn,

1
Yığınlaştırılmaması gereken belirli bir vaka hakkında, StackOverflow'taki sadece belirli bir konu. Özellikle şu anki mesaj, zaten yazılı olan test koduyla ilgili.
Péter Török

1

Devlet kötüdür. Aşağıdaki fonksiyon ünite testine ihtiyaç duymaz, çünkü yan etkisi yoktur ve ne yaptığı ve ne yapmadığı iyi anlaşılmıştır. Neden test ettin? Kendi beynine güvenmiyor musun ??? Statik fonksiyonlar harika!

static function bool Foo(bool a, bool b, bool c)
{
    return a && b && c;
}

2
Hayır, kendi beynime güvenmiyorum - Yaptığım şeyi her zaman iki kez kontrol etmenin zor yolunu öğrendim :-) Dolayısıyla, örneğin hiçbir şeyi yanlış yazmadığımdan ve öğleden sonra gitmediğinden emin olmak için birim testlerine ihtiyacım olacaktı. gelecekte kodu kırmak için. Ve a, bve tarafından temsil edilen durumu hesaplayan arayan yöntemini doğrulamak için daha fazla birim testi c. İş mantığını istediğiniz şekilde hareket ettirebilirsiniz, sonunda yine de bir yerde test etmeniz gerekiyor.
Péter Török

@ Péter Török, sınavlarınızda yazım hataları da yapabilir ve böylece yanlış pozitif sonuçlara neden olabilirsiniz, öyleyse nerede duruyorsunuz? Birim testleriniz için birim testleri yazıyor musunuz? Beynime de% 100 güvenmiyorum ama günün sonunda kod yazmak için geçimimi sağladım. Bu fonksiyonun içinde bir hata olması mümkündür, ancak bir hatayı kaynağa kadar kolay izleyebilecek şekilde kod yazmak önemlidir ve böylece bir kez problemi izole edip bir düzeltme yaptıktan sonra daha iyi durumda olursunuz. . İyi yazılmış kodlar çoğu zaman
Job

2
Aslında, testler de hatalı olabilir. (TDD, testlerin önce başarısız olmasını sağlayarak buna hitap eder.) Bununla birlikte, aynı hatayı iki kez yapmak (ve ona bakmak), çok daha düşük bir olasılığa sahiptir. Genel olarak, hiçbir miktar ve test türü , yazılımın hatasız olmadığını ispat edemez , yalnızca hata olasılığını kabul edilebilir bir seviyeye düşürür . Ve kaynak bulma hatalarını takiben IMO hiçbir şey birim testlerini geçemez - hızlı geribildirim kuralı :-)
Péter Török

“Aşağıdaki fonksiyon ünite testine ihtiyaç duymuyor” Bence alaycı olduğunuzu düşünüyorum, ancak belli değil. Kendi beynime güveniyor muyum? YOK HAYIR! Koda değen bir sonraki adamın beynine güveniyor muyum? DAHA FAZLASI HAYIR! Kodun arkasındaki tüm varsayımların bir yıl sonra geçerli olacağına inanıyor muyum? ... driftimi aldın. Ayrıca, statik işlevler OO'yi öldürür ... FP yapmak istiyorsanız, bir FP dili kullanın.
Rob,

1

Bu sorunun oldukça eski olduğunu biliyorum. Ancak soruna başka bir bakış açısı vermek istiyorum.

Öncelikle, birim testlerinizin iki amacı olmalı:

  1. Belirli bir zaman miktar birim testini okuyup anladığınızdan emin olun böylece sonra sizin ve takım arkadaşları için belgeler oluşturun what's the class' intentionvehow the class is doing its work
  2. Geliştirme sırasında, birim testi yazdığımız kodun, aklımızda planlandığı şekilde çalışmasını sağlamasını sağlar.

Böylece problemi özetleyerek, bir test etmek istiyoruz complex if statement, verilen örnek için, 2 ^ 3 olasılık var, bu yazabileceğimiz önemli bir test miktarı.

  • Bu gerçeğe adapte olabilir ve 8 test yazabilir veya parametreli testlerden yararlanabilirsiniz.
  • Ayrıca diğer cevapları takip edebilir ve testlerin niyetiyle açık olması gerektiğini hatırlayın, bu şekilde yakın gelecekte anlaşılmasını zorlaştıracak çok fazla ayrıntıyla uğraşmayacağız. what is doing the code

Öte yandan, testlerinizin uygulamadan daha karmaşık olduğu durumdaysanız, uygulamanın testin kendisinden ziyade yeniden tasarlanması gerektiği (duruma göre daha fazla veya daha az).

Karmaşık if ifadeleri için, örneğin, her işleyiciyi şu şekilde uygulayarak , zincir sorumluluk modelini düşünebilirsiniz :

If some simple business rule apply, derive to the next handler

Karmaşık bir kural yerine, bazı basit kuralları sınamak ne kadar basit olurdu?

Umarım yardımcı olur,


0

Bu, quickcheck gibi bir şeyin ( http://en.wikipedia.org/wiki/QuickCheck ) arkadaşınız olacağı durumlardan biridir. Tüm N vakalarını elle yazmak yerine, bilgisayarın olası tüm test durumlarını (en azından çok sayıda) oluşturmasını ve hepsinin anlamlı bir sonuç verdiğini doğrulamasını sağlayın.

Burada yaşamak için bilgisayarları programlıyoruz, neden bilgisayarı sizin için test vakalarınızı oluşturmak için programlamıyorsunuz?


0

Koşulları koruma koşullarına göre yeniden düzenleyebilirsiniz:

if (! PassesBusinessRule1) {
    return false;
}

if (! PassesBusinessRule2) {
    return false;
}

if (! PassesBusinessRule3) {
    return false;
}

Bunun dava sayısını azalttığını sanmıyorum, ancak benim deneyimim onları bu şekilde çözmenin daha kolay olduğu yönünde.

(Büyük bir "tek çıkış noktası" hayranı olduğumu unutmayın, ancak güvenlik koşulları için bir istisna yapıyorum. Ancak kodu yapılandırmanın başka yolları da var, böylece ayrı ayrı geri dönüşleriniz olmaz.)

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.