Yahtzee oyununu nasıl TDD yapmalısınız?


36

Diyelim ki Yahtzee oyunu TDD stili yazıyorsunuz. Beş kalıp rulosunun dolu bir ev olup olmadığını belirleyen kodun bir kısmını test etmek istiyorsunuz. Bildiğim kadarıyla, TDD yaparken, şu ilkeleri takip ediyorsunuz:

  • Önce testleri yaz
  • İşe yarayan en basit şeyi yaz
  • Rafine ve refactor

Öyleyse, ilk test böyle bir şeye benzeyebilir:

public void Returns_true_when_roll_is_full_house()
{
    FullHouseTester sut = new FullHouseTester();
    var actual = sut.IsFullHouse(1, 1, 1, 2, 2);

    Assert.IsTrue(actual);
}

"İşe IsFullHouseyarayan en basit şeyi yaz" yazısını takip ederken, şu şekilde yöntemi yazmalısınız :

public bool IsFullHouse(int roll1, int roll2, int roll3, int roll4, int roll5)
{
    if (roll1 == 1 && roll2 == 1 && roll3 == 1 && roll4 == 2 && roll5 == 2)
    {
        return true;
    }

    return false;
}

Bu yeşil bir testle sonuçlanır ancak uygulama eksiktir.

Tam bir ev için mümkün olan her geçerli kombinasyonu (hem değerleri hem de konumları) test etmeli misiniz? IsFullHouseKodunuzun tamamen test edilmiş ve doğru olduğundan kesinlikle emin olmanın tek yolu gibi gözüküyor , ama aynı zamanda bunu yapmak da delice geliyor.

Böyle bir şeyi nasıl test edersiniz?

Güncelleştirme

Erik ve Kilian, ilk uygulamada değişmezleri yeşil bir test almak için kullanmanın en iyi fikir olmadığını belirtmişlerdir. Bunu neden yaptığımı ve bu açıklamanın bir yorumda yer almadığını açıklamak istiyorum.

Ünite testi ile ilgili pratik deneyimim (özellikle bir TDD yaklaşımı kullanmak) çok sınırlı. Roy Osherove'in TDD Masterclass'in Tekpub'ta bir kaydını izlediğimi hatırlıyorum. Bölümlerden birinde, bir String Calculator TDD stili oluşturuyor. Dize Hesap Makinesinin tam özelliklerini burada bulabilirsiniz: http://osherove.com/tdd-kata-1/

Böyle bir testle başlar:

public void Add_with_empty_string_should_return_zero()
{
    StringCalculator sut = new StringCalculator();
    int result = sut.Add("");

    Assert.AreEqual(0, result);
}

Bu, Addyöntemin bu ilk uygulanmasında sonuçlanır :

public int Add(string input)
{
    return 0;
}

Sonra bu test eklenir:

public void Add_with_one_number_string_should_return_number()
{
    StringCalculator sut = new StringCalculator();
    int result = sut.Add("1");

    Assert.AreEqual(1, result);
}

Ve Addyöntem yeniden düzenlendi:

public int Add(string input)
{
    if (input.Length == 0)
    {
        return 0;
    }

    return 1;
}

Her adımdan sonra Roy "İşe yarayacak en basit şeyi yaz" diyor.

Bu yüzden TDD tarzı bir Yahtzee oyunu yapmaya çalışırken bu yaklaşımı deneyeceğimi düşündüm.


8
"İşe yarayan en basit şeyi yaz" aslında bir kısaltmadır; Doğru tavsiye " Tamamen zekice olmayan ve işe yaraması açıkça yanlış olan en basit şeyi yaz" dır . Yani, hayır, if (roll1 == 1 && roll2 == 1 && roll3 == 1 && roll4 == 2 && roll5 == 2)
yazmamalısınız

3
Erik'in cevabını özetlediğiniz için teşekkür ederim, daha az tartışmacı veya medeni bir şekilde.
Kristof Claes,

1
"İşe yarayan en basit şeyi yaz" gibi, @ Carson63000, aslında bir basitleştirme. Böyle düşünmek aslında tehlikeli; rezil Sudoku TDD çöküşüne (google it) yol açar. Körel olarak takip edildiğinde TDD gerçekten de güçlüdür: "işe yaramaz en basit şeyi" körü körüne yaparak önemsiz olmayan bir algoritmayı genelleştiremezsiniz. Ne yazık ki, XP ve TDD'nin ustaları bile bazen kör olarak takip ediyorlar ...
Andres F.

1
@AndresF. Yorumunuzun Google aramalarında, üç günden kısa bir süre sonra "Soduko TDD debacle" hakkındaki yorumdan çok daha yüksek göründüğünü unutmayın. Bununla birlikte, bir Sudoku nasıl çözülmez özetlenmiştir: TDD kalite içindir, doğruluk değildir. Özellikle TDD ile kodlamaya başlamadan önce algoritmayı çözmeniz gerekir. (Ben de ilk programcı da bir kod değilim.)
Mark Hurd

Yanıtlar:


40

Zaten bu soruya çok sayıda iyi cevap var, ve yorumda bulundum ve birkaç tanesini geri aldım. Yine de, bazı düşünceler eklemek istiyorum.

Esneklik acemiler için değil

OP , TDD konusunda tecrübeli olmadığını açıkça ifade ediyor ve bence iyi bir cevap bunu dikkate almalı. Dreyfus yetenek kazanım modelinin terminolojisinde muhtemelen acemidir . Acemi olmanın yanlış bir tarafı yoktur - yeni bir şeyler öğrenmeye başladığımızda hepimiz acemi oluruz. Ancak, Dreyfus modelinin açıkladığı şey, acemilerin

  • öğretilen kurallara veya planlara katı bir şekilde bağlılık
  • isteğe bağlı hüküm kullanmamak

Bu bir kişilik eksikliğinin tanımı değil, bundan utanmak için bir neden yok - bu yeni bir şeyler öğrenmek için hepimizin geçirmesi gereken bir aşama.

Bu TDD için de geçerlidir.

Buradaki diğer cevapların birçoğuna TDD'nin dogmatik olmak zorunda olmadığı ve bazen alternatif bir şekilde çalışmanın daha faydalı olabileceği konusunda hemfikir olmayarak hemfikir olduğuma katılıyorum. Deneyiminiz olmadığında isteğe bağlı yargılamayı nasıl uygulayabilirsiniz?

Bir aceminin TDD'yi yapmamanın bazen doğru olduğu tavsiyesini kabul etmesi durumunda, TDD yapmayı atlamanın doğru olup olmadığını nasıl belirleyebilir?

Tecrübe ya da rehberlik olmadan, bir aceminin yapabileceği tek şey, her zorlaştığında TDD'den atlamaktır. Bu insan doğası, ama öğrenmenin iyi bir yolu değil.

Testleri dinle

TDD'den çıkmak zorlaştığında, TDD'nin en önemli avantajlarından birini kaçırmak gerekir. Testler, SUT'nin API'si hakkında erken geribildirim sağlar. Testin zor yazılması, SUT'un kullanımının zor olduğunun önemli bir işaretidir.

GOOS’un en önemli mesajlarından birinin olmasının nedeni budur : testlerinizi dinleyin!

Bu soru söz konusu olduğunda, Yahtzee oyununun önerilen API'sini görünce ilk tepkim ve bu sayfada bulunabilecek birleştirme hakkında tartışma, bunun API hakkında önemli geri bildirim olduğu yönündedir.

API, zar rulolarını sıralı bir tam sayı dizisi olarak göstermek zorunda mı? Bana göre, ilkel takıntı kokusu . Bu yüzden bir Rollsınıfın girişini öneren tallseth'in cevabını gördüğüm için mutlu oldum . Bence bu mükemmel bir öneri.

Ancak, bu cevaba yapılan yorumların bir kısmının yanlış anladığını düşünüyorum. TDD'nin önerdiği şey, bir Rollsınıfın iyi bir fikir olacağı fikrini elde ettiğinizde, orijinal SUT üzerinde çalışmayı askıya alın ve TDD'leri Rollsınıfta çalışmaya başlamalısınız .

TDD'nin kapsamlı testlere nazaran daha 'mutlu yola' yönelik olduğunu kabul etmeme rağmen, sistemi hala yönetilebilir birimlere ayırmaya yardımcı olmaktadır. Bir Rollsınıf, TDD'nin daha kolay tamamlayabileceği bir şeye benziyor.

Daha sonra, Rollsınıf yeterince geliştikten sonra, orijinal SUT'a geri dönüp, Rollgirdiler açısından onu tüketirsiniz .

Bir Test Yardımcısı'nın önerisi mutlaka rastlantısallık anlamına gelmez - testi daha okunaklı hale getirmenin bir yoludur.

RollÖrnekler açısından girdilere yaklaşmanın ve modellemenin bir başka yolu, bir Test Veri Oluşturucusu'nu tanıtmak olacaktır .

Kırmızı / Yeşil / Refaktör üç aşamalı bir süreçtir

(TDD'de yeterince tecrübeli iseniz), TDD'ye sıkı sıkıya bağlı kalmanıza gerek olmadığını genel olarak kabul ederken, Yahtzee tatbikatı için oldukça zayıf bir tavsiye olduğunu düşünüyorum. Yahtzee kurallarının detaylarını bilmeme rağmen, burada Red / Green / Refactor sürecine sıkı sıkıya bağlı kalamayacağınız ve hala uygun bir sonuca varamayacağınıza dair ikna edici bir tartışma görmüyorum.

Buradaki çoğu insanın unutmuş göründüğü şey, Kırmızı / Yeşil / Refaktör sürecinin üçüncü aşamasıdır. İlk önce testi yaz. Sonra tüm testleri geçen en basit uygulamayı yazarsınız. O zaman refactor.

Burada, bu üçüncü durumda, tüm mesleki becerilerinizi üstlenmeye getirebilirsiniz. Bu, kodu yansıtmanıza izin verilen yerdir.

Ancak, bence sadece " Tamamen zekice olan ve işe yarayacak kadar yanlış olmayan en basit şeyi yaz" demelisin . Eğer önceden (uygulama hakkında) yeterince bilginiz varsa, o zaman tam çözümün dışındaki her şey açıkça yanlış olacaktır . Tavsiyelerin ilerleyişine gelince, bu acemiler için oldukça işe yaramaz.

Gerçekten yapılması gereken, tüm testlerin açıkça yanlış bir uygulama ile yapılmasını sağlayabiliyorsanız , bu başka bir test yazmanızın geri bildirimidir .

Bunu yapmanın sizi ilk önce düşündüğünüzden tamamen farklı bir uygulamaya yönlendirmesi ne kadar şaşırtıcıdır. Bazen, bu şekilde büyüyen alternatif, orijinal planınızdan daha iyi olabilir.

Titreşim bir öğrenme aracıdır

Red / Green / Refactor gibi titiz süreçlere bağlı kalmak, öğrendiği sürece çok anlamlıdır. Öğrenciyi sadece kolay olduğu zaman değil, zor olduğu zamanlarda da TDD ile tecrübe kazanmaya zorlar.

Sadece tüm zor kısımlara hakim olduğunuzda, 'doğru' yoldan ne zaman sapacağınız konusunda bilinçli bir karar verebilecek konumdasınız. İşte o zaman kendi yolunu oluşturmaya başla.


'TDD acemi burada değil, denemeye ilişkin tüm olağandışı endişelerle. Açıkça yanlış bir uygulama ile tüm testleri geçebiliyorsanız ilginç bir şey olabilir, bu da başka bir test yazmanız gerektiğini bildiren bir geri bildirimdir. "Braindead" uygulamalarını test etmenin gereksiz bir iş olduğu algısı ile başa çıkmak için iyi bir yol gibi görünüyor.
shambulator

1
Vay, teşekkür ederim. İnsanların TDD'deki (veya herhangi bir disiplindeki) yeni başlayanlara “kurallar hakkında endişelenme, sadece en iyi olanı yapma” deme eğiliminden gerçekten korkuyorum. Hiçbir bilginiz veya deneyiminiz yoksa, neyin en iyi hissettirdiğini nasıl bilebilirsin? Ayrıca dönüşüm önceliği ilkesinden bahsetmek isterim, yoksa testler daha belirgin hale geldikçe, bu kod daha genel hale gelmelidir. Bob Amca gibi en sert TDD destekçileri “her test için yeni bir if-ifadesi ekle” kavramının arkasında duramazlardı.
sara

41

Feragatname olarak, bu benim uygulamamla TDD ve Kilian'ın açıkça işaret ettiği gibi, uygulamanın tek bir doğru yolu olduğunu söyleyen herkese karşı dikkatli olacağım. Ama belki sana yardım eder ...

Her şeyden önce, sınavınızı geçmek için yapabileceğiniz en basit şey şudur:

public bool IsFullHouse(int roll1, int roll2, int roll3, int roll4, int roll5)
{
    return true;
}

Bu önemlidir, çünkü bazı TDD uygulamaları nedeniyle değil, fakat tüm bu hazır kelimelere sert bir şekilde yazmak gerçekten iyi bir fikir değildir. TDD ile başınızı sarmak için en zor şeylerden biri, kapsamlı bir test stratejisi olmamasıdır - bu, kodu basit tutarken gerilemelere karşı korunmanın ve ilerlemeyi işaretlemenin bir yoludur. Bu bir geliştirme stratejisidir, test stratejisi değildir.

Bu ayrımdan bahsetmemin nedeni, hangi testleri yazmanız gerektiğini yönlendirmesine yardımcı olmasıdır. Cevabı "Hangi testleri yazmalıyım?" "kodu istediğiniz gibi almanız için ne tür testler yapmanız gerekiyorsa." TDD'yi, algoritmalar ve kodunuzla ilgili nedenleri açıklamanıza yardımcı olacak bir yol olarak düşünün. Testiniz ve "basit yeşil" uygulamam göz önüne alındığında, sonraki test ne olacak? Dolu bir ev inşa ettin, ne zaman tam bir ev değil?

public void Returns_true_when_roll_is_full_house()
{
    FullHouseTester sut = new FullHouseTester();
    var actual = sut.IsFullHouse(1, 2, 3, 4, 5);

    Assert.IsFalse(actual);
}

Şimdi anlamlı iki test durumu arasında ayrım yapmanın bir yolunu bulmalısın . Şahsen, "testin geçmesi için en basit şeyi yap" ve "uygulamanın ilerlemesini sağlayan testin geçmesi için en basit olanı yap" diyerek biraz bilgi vereceğim. Başarısız olan testler yazmak, kodu değiştirme bahanenizdir, bu yüzden her testi yazmaya başladığınızda kendinize “kodum ne yapmamı istediğimi yapmıyor ve bu eksikliği nasıl ortaya çıkarabilirim?” Diye sormalısınız. Ayrıca, kodunuzu sağlam hale getirmenize ve son durumları ele almanıza yardımcı olabilir. Arayan bir saçmalık girerse ne yaparsınız?

public void Returns_true_when_roll_is_full_house()
{
    FullHouseTester sut = new FullHouseTester();
    var actual = sut.IsFullHouse(-1, -2, -3, -4, -5);

    //I dunno - throw exception, return false, etc, whatever you think it should do....
}

Özetle, eğer her bir değer kombinasyonunu test ediyorsanız, neredeyse kesinlikle yanlış bir şekilde yapıyorsunuzdur (ve muhtemelen şartlı kombinasyonların patlamasıyla sonuçlanacaktır). TDD'ye gelince, istediğiniz algoritmayı elde etmek için gereken minimum test vakasını yazmalısınız. Yazdığınız diğer tüm testler yeşil renkte başlayacak ve dolayısıyla TDD sürecinin bir parçası değil, özünde belgelendirilecektir. Sadece TDD test durumlarını sadece gereksinimler değişirse veya bir hata ortaya çıkarsa yazabilirsiniz, bu durumda eksikliği bir testle belgeleyip geçersiniz.

Güncelleştirme:

Bunu, güncellemenize cevaben bir yorum olarak başlattım, ancak oldukça uzamaya başladı ...

Sorunun, değişmezlerin, dönemin varlığına bağlı olmadığını, ancak 'en basit' şeyin 5 parçalı şartlı olduğunu söyleyebilirim. Bunu düşündüğünüzde, 5 bölüm şartlı aslında oldukça karmaşık. Kırmızı-yeşili adım sırasında değişmezleri kullanmak ve daha sonra bunları yeniden ateşleme adımındaki sabitlere soyutlamak veya daha sonraki bir testte bunları genelleştirmek yaygın olacaktır.

TDD ile olan kendi yolculuğum sırasında, yapılacak önemli bir ayrımın olduğunu fark ettim - "basit" ve "geniş" kelimelerin birbirine karıştırılması iyi değil. Yani, başladığımda, insanların TDD yaptığını izledim ve "testlerin geçmesi için mümkün olan en aptalca şeyi yaptıklarını" düşündüm ve bir süre için "basit" in incelikle farklı olduğunu fark edene kadar bunu taklit ettim. "geniş" den. Bazen üst üste binerler ama çoğu zaman değil.

Öyleyse, değişmezlerin varlığının sorun olduğu izlenimini verdiysem özür dilerim - öyle değil. Şartın 5 fıkra ile karmaşıklığı sorunu olduğunu söyleyebilirim. İlk kırmızıdan yeşile, sadece "geri dönüş" olabilir, çünkü bu gerçekten basittir (ve geniş, tesadüf eseri). Bir sonraki test davası, (1, 2, 3, 4, 5 ile) false döndürmek zorunda kalacak ve işte o zaman "geniş" bırakmaya başlıyorsunuz. Kendine şunu sormalısın "neden (1, 1, 1, 2, 2) tam bir ev ve (1, 2, 3, 4, 5) değil?" Bulabileceğiniz en basit şey, birinin son dizi elemanına 5 veya ikinci dizi elemanına 2 sahip olması ve diğerinin olmaması olabilir. Bunlar basit, ama aynı zamanda (gereksiz yere) genişler. Gerçekten kullanmak istediğin şey "aynı sayıdan kaç tanesini var?" Böylece bir tekrar olup olmadığını kontrol ederek ikinci testi geçebilirsiniz. Birinde tekrar olan, dolu bir evin var, diğeri de yok. Şimdi test geçiyor ve algoritması daha da geliştirmek için tekrarı olan ancak tam bir ev olmayan başka bir test durumu yazıyorsunuz.

Bunu, gittiğinizde değişmezler ile yapabilirsiniz veya olmayabilir, ve yaparsanız sorun değil. Ancak genel fikir, daha fazla vaka ekledikçe algoritmanızı 'organik olarak' büyütmektir.


Neden değişmez yaklaşıma başladığımla ilgili daha fazla bilgi eklemek için sorumu güncelledim.
Kristof Claes,

9
Bu harika bir cevap.
Taleseth

1
Düşünceli ve iyi açıklanmış cevabınız için çok teşekkür ederim. Aslında şimdi düşündüğüm için çok mantıklı geliyor.
Kristof Claes,

1
Kapsamlı testler her kombinasyonun test edilmesi anlamına gelmez ... Bu çok saçma. Bu özel durum için, bir ya da iki evi doldurun ya da iki tane ya da birkaç tane dolu ev alın. Ayrıca sorun çıkarabilecek herhangi bir özel kombinasyon (yani, bir tür 5).
Schleis,

3
+1 Bu cevabın arkasındaki prensipler Robert C. Martin'in Dönüşüm Önceliği Premise cleancoder.posterous.com/the-transformation-priority-premise
Mark Seemann

5

Belirli bir kombinasyonda beş belirli değişmez değeri test etmek ateşli beynime "basit" değildir. Bir sorunun çözümü gerçekten açıksa ( herhangi bir değerin tam olarak üç ve tam olarak iki değerinin olup olmadığını sayın ), o zaman elbette devam edin ve bu çözümü kodlayın ve çok iyi bir şekilde yanlışlıkla karşılaması muhtemel olabilecek bazı testler yazın yazdığınız kodun miktarı (yani, farklı hazır değerler ve üçlü ve çiftlerin farklı sıraları).

TDD maksimikleri gerçekten dini inançlar değil araçlardır. Amaçları, hızlı ve doğru bir şekilde doğru kodlu kod yazmanızı sağlamaktır. Bir maxim açıkça bunun önünde duruyorsa, sadece bir sonraki adıma geçin. Orada olacak bol bunu uygulayabilirsiniz projenizde olmayan bariz bit.


5

Erik'in cevabı harika, ama sınav yazarken bir numara paylaşabileceğimi düşündüm.

Bu testle başla:

[Test]
public void FullHouseReturnsTrue()
{
    var pairNum = AnyDiceValue();
    var trioNum = AnyDiceValue();

    Assert.That(sut.IsFullHouse(trioNum, pairNum, trioNum, pairNum, trioNum));
}

Roll5 paragraftan geçmek yerine bir sınıf oluşturursanız, bu test daha da iyi olur :

[Test]
public void FullHouseReturnsTrue()
{
    var roll = AnyFullHouse();

    Assert.That(sut.IsFullHouse(roll));
}

Bu bu uygulamayı verir:

public bool IsFullHouse(Roll toCheck)
{
    return true;
}

O zaman bu testi yazın:

[Test]
public void StraightReturnsFalse()
{
    var roll = AnyStraight();

    Assert.That(sut.IsFullHouse(roll), Is.False);
}

Bu geçtikten sonra şunu yazın:

[Test]
public void ThreeOfAKindReturnsFalse()
{
    var roll = AnyStraight();

    Assert.That(sut.IsFullHouse(roll), Is.False);
}

Ondan sonra, bahse girerim daha fazla yazmanıza gerek kalmaz (tam bir ev olmadığını düşünüyorsanız belki iki çift veya belki de yahtzee).

Açıkçası, kriterlerinize uyan rastgele Rolls döndürmek için Any yöntemlerinizi uygulayın.

Bu yaklaşımın birkaç faydası vardır:

  • Tek amacı belirli değerlere takılmanızı engellemek için bir test yazmanıza gerek yok
  • Testler amacınızı gerçekten güzel bir şekilde iletiyor (ilk testin kodu "herhangi bir tam ev gerçek oluyor" diye bağırıyor)
  • sizi sorunun etini üzerinde çalışma noktasına çabucak götürür
  • Bazen aklınıza gelmeyen davaları fark eder

Bu yaklaşımı yaparsanız, günlük mesajlarınızı Assert.That ifadelerinizde geliştirmeniz gerekir. Geliştiricinin hangi girişin hataya neden olduğunu görmesi gerekir.
Bringer128

Bu bir Tavuk veya yumurta ikilemi yaratmaz mı? AnyFullHouse'u (TDD'yi kullanarak) uyguladığınızda, doğruluğunu doğrulamak için IsFullHouse'a ihtiyacınız olmaz mı? Özellikle, AnyFullHouse'da bir hata varsa, bu hata IsFullHouse'da çoğaltılabilir.
waxwing

AnyFullHouse () bir test senaryosunda bir yöntemdir. Tipik olarak test durumlarınızı TDD misiniz? Hayır. Ayrıca, bir evin (veya başka bir yuvarlağın) rastgele bir örneğini oluşturmak, varlığını test etmekten daha basittir. Elbette, testinizde bir hata varsa, üretim kodunda çoğaltılabilir. Bu her test için geçerli.
tallseth

AnyFullHouse, bir test durumundaki "yardımcı" bir yöntemdir. Bunlar yeterince genelse, yardımcı yöntemler de test edilir!
Mark Hurd

Should IsFullHousegerçekten dönmek trueeğer pairNum == trioNum ?
recursion.ninja

2

Bunu test ederken dikkate alacağım iki ana yolu düşünebilirim;

  1. Geçerli tam ev setlerinin "bazı" test örneklerini (~ 5) ve beklenen miktarda sahte ({1, 1, 2, 3, 3} aynı miktarda iyi bir tane olduğunu ekleyiniz). yanlış bir uygulama tarafından "aynı olanın 3'ü artı bir çift" olarak tanındı). Bu yöntem, geliştiricinin yalnızca testleri geçmeye çalışmakla kalmayıp, doğru bir şekilde uyguladığını varsayar.

  2. Tüm olası zar setlerini test et (sadece 252 tane var). Bu, elbette, beklenen cevabın ne olduğunu bilmek için bir yolunuz olduğunu varsayar (bunun test olarak an olarak bilinir oracle.) Bu, aynı işlevin veya bir insanın referans uygulaması olabilir. Gerçekten titiz olmak istiyorsanız, beklenen her sonucu manuel olarak kodlamakta fayda olabilir.

Olduğu gibi, elbette kuralları bilmek zorunda olan bir Yahtzee AI yazdım. Puan değerlendirme bölümünün kodunu burada bulabilirsiniz , uygulamanın İskandinav versiyonu (Yatzy) için olduğunu ve uygulamamızın zarların sıralı olarak verildiğini varsaydığını lütfen unutmayın.


Milyon dolarlık soru, Yahtzee AI'yi saf TDD kullanarak türetmiş misiniz? Benim iddiaya göre yapamazsın; Eğer var :) kör değil tanımı gereği olan bölge bilgisini kullanmak
Andres F.

Evet, haklısın galiba. Bu, TDD ile ilgili genel bir sorundur, yalnızca beklenmedik çarpışmalar ve işlenmeyen istisnalar için test etmek istemediğiniz sürece, test senaryolarının beklenen çıktılara ihtiyacı vardır.
ansjob

0

Bu örnek gerçekten noktayı özlüyor. Burada bir yazılım tasarımı değil, basit bir fonksiyondan bahsediyoruz. Biraz karışık mı? evet, yani onu parçalara ayırıyorsun. Ve kesinlikle 1, 1, 1, 1, 1, 6, 6, 6, 6, 6, 6'dan mümkün olan her bir girişi test etmiyorsunuz. Söz konusu fonksiyonun sadece bir kombinasyon, yani AAABB olması şart değil.

200 ayrı mantık testine ihtiyacınız yok. Örneğin bir set kullanabilirsiniz. Neredeyse herhangi bir programlama dili yerleşik bir dilde:

Set set;
set.add(a);
set.add(b);
set.add(c);
set.add(d);
set.add(e);

if(set.size() == 2) { // means we *must* be of the form AAAAB or AAABB.
    if(a==b==c==d) // eliminate AAAAB
        return false;
    else
        return true;
}
return false;

Ve geçerli bir Yahtzee rulosu olmayan bir giriş alırsanız, yarın yokmuş gibi atmalısınız.

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.