आपको टीडीडी को याहत्ज़ी खेल कैसे करना चाहिए?


36

मान लीजिए कि आप एक Yahtzee खेल TDD शैली लिख रहे हैं। आप उस कोड के भाग का परीक्षण करना चाहते हैं जो यह निर्धारित करता है कि पांच मर रोल का एक सेट एक पूर्ण घर है या नहीं। जहां तक ​​मुझे पता है, टीडीडी करते समय आप इन सिद्धांतों का पालन करते हैं:

  • पहले परीक्षण लिखें
  • संभव है कि सबसे सरल बात लिखें
  • रिफाइन और रिफ्लेक्टर

तो एक प्रारंभिक परीक्षा कुछ इस तरह दिख सकती है:

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);
}

"सबसे सरल बात यह है कि काम करता है संभव लिखें" का पालन करते हुए, आपको अब IsFullHouseइस तरह की विधि लिखनी चाहिए :

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;
}

यह एक हरे रंग की परीक्षा में परिणाम देता है लेकिन कार्यान्वयन अपूर्ण है।

क्या आपको पूर्ण घर के लिए हर संभव वैध संयोजन (मूल्यों और स्थिति दोनों) का परीक्षण करना चाहिए? यह देखने का एकमात्र तरीका है कि यह सुनिश्चित किया जाए कि आपका IsFullHouseकोड पूरी तरह से परीक्षण और सही है, लेकिन ऐसा करने के लिए यह काफी पागल भी लगता है।

आप यूनिट को कुछ इस तरह कैसे परखेंगे?

अद्यतन करें

एरिक और किलियन बताते हैं कि एक ग्रीन टेस्ट पाने के लिए शुरुआती कार्यान्वयन में शाब्दिक का उपयोग करना सबसे अच्छा विचार नहीं हो सकता है। मैं यह बताना चाहता हूं कि मैंने ऐसा क्यों किया और यह स्पष्टीकरण एक टिप्पणी में फिट नहीं है।

यूनिट परीक्षण (विशेषकर टीडीडी दृष्टिकोण का उपयोग करके) के साथ मेरा व्यावहारिक अनुभव बहुत सीमित है। मुझे याद है कि टेकपब पर रॉय ओशेरोव के टीडीडी मास्टरक्लास की रिकॉर्डिंग देख रहा हूं। एक एपिसोड में वह एक स्ट्रिंग कैलकुलेटर टीडीडी स्टाइल बनाता है। स्ट्रिंग कैलकुलेटर का पूरा विवरण यहां पाया जा सकता है: http://osherove.com/tdd-kata-1

वह इस तरह एक परीक्षण के साथ शुरू होता है:

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

    Assert.AreEqual(0, result);
}

इस Addविधि के पहले कार्यान्वयन में यह परिणाम है :

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

फिर यह परीक्षण जोड़ा जाता है:

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

    Assert.AreEqual(1, result);
}

और Addविधि फिर से बनाई गई है:

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

    return 1;
}

प्रत्येक चरण के बाद रॉय कहते हैं "सबसे सरल बात लिखो जो काम करेगा"।

इसलिए मैंने सोचा कि मैं इस दृष्टिकोण को एक टीडीडी-शैली यात्ज़ेई खेल करने की कोशिश करूँगा।


8
"सबसे सरल बात यह है कि काम करता है लिखें" वास्तव में एक संक्षिप्त नाम है; सही सलाह है "सरलतम बात लिखो जो पूरी तरह से साहसी नहीं है और स्पष्ट रूप से गलत है जो काम करता है"। तो, नहीं, आपको नहीं लिखना चाहिएif (roll1 == 1 && roll2 == 1 && roll3 == 1 && roll4 == 2 && roll5 == 2)
Carson63000

3
एरिक के उत्तर को सारांशित करने के लिए धन्यवाद, कम तर्कपूर्ण या सभ्य तरीके से हो।
क्रिस्टोफ़ ने दावा किया

1
@ कार्सन 63000 की तरह "सबसे सरल काम जो लिखता है", वास्तव में एक सरलीकरण है। वास्तव में ऐसा सोचना खतरनाक है; यह कुख्यात सुडोकू TDD पराजय की ओर जाता है (इसे गूगल करें)। जब आँख बंद करके पालन किया जाता है, तो टीडीडी वास्तव में ब्रिंडेड होता है: आप आँख बंद करके "सबसे सरल काम करता है" करके एक गैर-तुच्छ एल्गोरिथ्म को सामान्य नहीं कर सकते हैं ... आपको वास्तव में सोचना होगा! दुर्भाग्य से, यहां तक ​​कि XP ​​और TDD के कथित स्वामी भी कभी-कभी इसे आंख मूंदकर अनुसरण करते हैं ...
Andres F.

1
@AndresF। ध्यान दें कि आपकी टिप्पणी तीन दिनों से भी कम समय के बाद "सोदुको टीडीडी पराजय" के बारे में की गई टिप्पणियों की तुलना में Google खोजों में अधिक दिखाई दी है। फिर भी कैसे एक सुडोकू को हल नहीं करना है, इसे संक्षेप में प्रस्तुत करें: टीडीडी गुणवत्ता के लिए है, शुद्धता नहीं। कोडिंग शुरू करने से पहले आपको एल्गोरिदम को हल करना होगा, खासकर टीडीडी के साथ। (ऐसा नहीं है कि मैं एक कोड पहले प्रोग्रामर भी नहीं हूँ।)
मार्क हर्ड

1
pvv.org/~oma/TDDinC_Yahtzee_27oct2011.pdf ब्याज की हो सकती है।

जवाबों:


40

इस सवाल के पहले से ही बहुत सारे अच्छे उत्तर हैं, और मैंने उनमें से कई पर टिप्पणी की और उतारा। फिर भी, मैं कुछ विचार जोड़ना चाहूंगा।

लचीलेपन नौसिखियों के लिए नहीं है

ओपी स्पष्ट रूप से बताता है कि वह टीडीडी के साथ अनुभवी नहीं है, और मुझे लगता है कि एक अच्छा जवाब को ध्यान में रखना चाहिए। कौशल अधिग्रहण के ड्रेफस मॉडल की शब्दावली में , वह शायद एक नौसिखिया है । नौसिखिया होने के साथ कुछ भी गलत नहीं है - जब हम कुछ नया सीखना शुरू करते हैं तो हम सभी नौसिखिए होते हैं। हालांकि, ड्रेफस मॉडल क्या बताता है कि नौसिखियों की विशेषता है

  • सिखाया नियमों या योजनाओं का कठोर पालन
  • विवेकाधीन निर्णय का कोई अभ्यास नहीं

यह एक व्यक्तित्व की कमी का विवरण नहीं है, इसलिए इसमें शर्मिंदा होने का कोई कारण नहीं है - यह एक ऐसा चरण है जिसके लिए हम सभी को कुछ नया सीखने की जरूरत है।

यह टीडीडी के लिए भी सही है।

जबकि मैं यहां कई अन्य उत्तरों से सहमत हूं कि टीडीडी को हठधर्मी होने की ज़रूरत नहीं है, और यह कि कभी-कभी वैकल्पिक तरीके से काम करना अधिक फायदेमंद हो सकता है, जो किसी को भी बस शुरू करने में मदद नहीं करता है। जब आपके पास कोई अनुभव नहीं है तो आप विवेकपूर्ण निर्णय कैसे ले सकते हैं?

यदि कोई नौसिखिया सलाह स्वीकार करता है कि कभी-कभी यह टीडीडी नहीं करना ठीक है, तो वह कैसे या वह निर्धारित कर सकता है जब टीडीडी को छोड़ना ठीक है?

बिना किसी अनुभव या मार्गदर्शन के, केवल एक नौसिखिया ही कर सकता है जो हर बार टीडीडी से बाहर निकलना मुश्किल हो जाता है। यह मानव स्वभाव है, लेकिन सीखने का एक अच्छा तरीका नहीं है।

परीक्षण सुनें

किसी भी समय टीडीडी से बाहर निकलना कठिन हो जाता है क्योंकि टीडीडी के सबसे महत्वपूर्ण लाभों में से एक को याद करना है। टेस्ट SUT के एपीआई के बारे में शुरुआती प्रतिक्रिया प्रदान करते हैं। यदि परीक्षण लिखना कठिन है, तो यह एक महत्वपूर्ण संकेत है कि SUT का उपयोग करना कठिन है।

यही कारण है कि GOOS के सबसे महत्वपूर्ण संदेशों में से एक है: अपने परीक्षणों को सुनो!

इस प्रश्न के मामले में, याहत्ज़ी खेल के प्रस्तावित एपीआई को देखते समय मेरी पहली प्रतिक्रिया, और इस पृष्ठ पर पाए जाने वाले संयोजन के बारे में चर्चा यह थी कि यह एपीआई के बारे में महत्वपूर्ण प्रतिक्रिया है।

क्या एपीआई को पूर्णांक के क्रम के रूप में पासा रोल का प्रतिनिधित्व करना है? मेरे लिए, कि आदिम जुनून की गंध । इसीलिए मैं एक Rollवर्ग के परिचय का सुझाव देते हुए तालसथ के उत्तर को देखकर खुश था । मुझे लगता है कि यह एक उत्कृष्ट सुझाव है।

हालाँकि, मुझे लगता है कि उस उत्तर के लिए कुछ टिप्पणियां गलत हैं। इसके बाद टीडीडी जो सुझाव देता है वह यह है कि एक बार जब आपको यह विचार आता है कि एक Rollवर्ग एक अच्छा विचार होगा, तो आप मूल SUT पर काम को स्थगित कर देंगे और TDD'ing Rollकक्षा पर काम करना शुरू कर देंगे ।

जबकि मैं मानता हूं कि व्यापक परीक्षण के उद्देश्य से टीडीडी 'खुश मार्ग' पर अधिक लक्षित है, फिर भी यह प्रणाली को प्रबंधनीय इकाइयों में तोड़ने में मदद करता है। एक Rollकक्षा कुछ ऐसा लगता है जिसे आप टीडीडी को आसानी से पूरा कर सकते हैं।

फिर, एक बार जब Rollकक्षा पर्याप्त रूप से विकसित हो जाती है, तो क्या आप मूल SUT पर वापस जाएंगे और Rollइनपुट के संदर्भ में इसे बाहर निकाल देंगे ।

टेस्ट हेल्पर का सुझाव अनिवार्य रूप से यादृच्छिकता का मतलब नहीं है - यह परीक्षा को अधिक पठनीय बनाने का एक तरीका है।

Rollउदाहरण के लिए दृष्टिकोण और मॉडल इनपुट का एक और तरीका एक टेस्ट डेटा बिल्डर को पेश करना होगा ।

Red / Green / Refactor एक तीन चरण की प्रक्रिया है

हालांकि मैं सामान्य भावना से सहमत हूं कि (यदि आप TDD में पर्याप्त रूप से अनुभवी हैं), तो आपको TDD से सख्ती से चिपके रहने की आवश्यकता नहीं है, मुझे लगता है कि यह याहज़ी व्यायाम के मामले में बहुत खराब सलाह है। हालाँकि मुझे यात्ज़ी नियमों का विवरण नहीं पता है, फिर भी मुझे यहाँ कोई ठोस तर्क दिखाई नहीं देता है कि आप लाल / हरी / रिफ्लेक्टर प्रक्रिया के साथ सख्ती से नहीं टिक सकते हैं और फिर भी उचित परिणाम पर पहुँच सकते हैं।

यहाँ जो लोग भूल जाते हैं, वह रेड / ग्रीन / रिफैक्टर प्रक्रिया का तीसरा चरण है। पहले आप टेस्ट लिखिए। फिर आप सबसे सरल कार्यान्वयन लिखते हैं जो सभी परीक्षण पास करता है। फिर आप रिफ्लेक्टर करें।

यह यहां है, इस तीसरे राज्य में, कि आप अपने सभी पेशेवर कौशल को सहन करने के लिए ला सकते हैं। यह वह जगह है जहां आपको कोड को प्रतिबिंबित करने की अनुमति है।

हालांकि, मुझे लगता है कि यह कहना है कि आपको केवल "सबसे सरल बात लिखना चाहिए जो पूरी तरह से साहसी नहीं है और स्पष्ट रूप से गलत है जो काम करता है"। यदि आप (आप को लगता है) पहले से लागू होने के बारे में पर्याप्त जानते हैं, तो पूर्ण समाधान की कमी से सब कुछ स्पष्ट रूप से गलत होने वाला है । जहां तक ​​सलाह जाती है, तब, यह एक नौसिखिया के लिए बहुत बेकार है।

वास्तव में क्या होना चाहिए, यदि आप स्पष्ट रूप से गलत कार्यान्वयन के साथ सभी परीक्षणों को पास कर सकते हैं , तो यह प्रतिक्रिया है कि आपको एक और परीक्षण लिखना चाहिए

यह आश्चर्य की बात है कि अक्सर ऐसा करने से आप पहले की तुलना में पूरी तरह से अलग कार्यान्वयन की ओर अग्रसर हो जाते हैं। कभी-कभी, जो विकल्प बढ़ता है, वह आपकी मूल योजना से बेहतर हो सकता है।

कठोरता एक शिक्षण उपकरण है

जब तक कोई सीख रहा है तब तक रेड / ग्रीन / रिफ्लेक्टर जैसी कठोर प्रक्रियाओं के साथ रहना बहुत मायने रखता है। यह सीखने वाले को टीडीडी के साथ अनुभव प्राप्त करने के लिए मजबूर करता है न केवल जब यह आसान होता है, बल्कि जब यह कठिन होता है।

केवल तभी जब आपने सभी कठिन भागों में महारत हासिल की हो, आप 'सच्चा' पथ से विचलन करने के बारे में एक सूचित निर्णय लेने की स्थिति में हैं। तभी आप अपना रास्ता खुद बनाना शुरू करते हैं।


यहाँ टीडीडी नौसिखिया, इसे कोशिश करने के बारे में सभी सामान्य गलतफहमी के साथ। दिलचस्प है कि अगर आप सभी परीक्षणों को स्पष्ट रूप से गलत कार्यान्वयन के साथ पास कर सकते हैं, तो यह प्रतिक्रिया है कि आपको एक और परीक्षण लिखना चाहिए। इस धारणा से निपटने के लिए एक अच्छे तरीके की तरह लगता है कि "ब्रेइंड" कार्यान्वयन का परीक्षण करना अनावश्यक व्यस्तता है।
शंबुलेटर 12

1
वाह धन्यवाद। मैं टीडीडी (या किसी भी अनुशासन) में शुरुआती लोगों को "नियमों के बारे में चिंता न करने की प्रवृत्ति से बताने के लिए वास्तव में डरता हूं, बस वही करें जो सबसे अच्छा लगता है"। जब आपको कोई ज्ञान या अनुभव नहीं है तो आप कैसे जान सकते हैं कि सबसे अच्छा क्या लगता है? मैं भी परिवर्तन प्राथमिकता सिद्धांत का उल्लेख करना चाहूंगा, या वह कोड अधिक सामान्य हो जाना चाहिए क्योंकि परीक्षण अधिक विशिष्ट हो जाते हैं। चाचा बॉब की तरह सबसे ज्यादा मरने वाले टीडीडी समर्थकों की धारणा "अपने परीक्षण के लिए एक नया अगर-बयान जोड़ें" के पीछे नहीं होगी।
सारा

41

डिस्क्लेमर के रूप में, यह टीडीडी है जैसा कि मैं इसका अभ्यास करता हूं और, जैसा कि काइली उपयुक्त रूप से बताते हैं, मैं किसी से भी सावधान रहूंगा, जिसने सुझाव दिया कि इसका अभ्यास करने का एक सही तरीका है। लेकिन शायद यह आपकी मदद करेगा ...

सबसे पहले, अपनी परीक्षा पास करने के लिए आप जो सबसे आसान काम कर सकते हैं वह यह होगा:

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

यह महत्वपूर्ण है क्योंकि कुछ टीडीडी अभ्यास के कारण नहीं, लेकिन क्योंकि उन सभी शाब्दिक अर्थों में हार्ड-कोरिंग वास्तव में एक अच्छा विचार नहीं है। टीडीडी के साथ अपने सिर को लपेटने के लिए सबसे कठिन चीजों में से एक यह है कि यह एक व्यापक परीक्षण रणनीति नहीं है - यह कोड को सरल रखते हुए प्रतिगमन और मार्क प्रगति के खिलाफ रक्षा करने का एक तरीका है। यह एक विकास रणनीति है और परीक्षण रणनीति नहीं है।

इस भेद का उल्लेख करने का कारण यह है कि यह मार्गदर्शन करने में मदद करता है कि आपको कौन से परीक्षण लिखने चाहिए। "मुझे क्या परीक्षण लिखना चाहिए?" "जो भी परीक्षण आपको कोड चाहिए जिस तरह से आप चाहते हैं।" TDD के बारे में सोचें जो आपको एल्गोरिदम को छेड़ने में मदद करता है और आपके कोड के बारे में कारण बताता है। तो आपके परीक्षण और मेरे "सरल ग्रीन" कार्यान्वयन को देखते हुए, आगे क्या परीक्षण आता है? ठीक है, आपने कुछ ऐसा स्थापित किया है जो एक पूर्ण घर है, इसलिए यह पूर्ण घर नहीं है?

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);
}

अब आपको दो परीक्षण मामलों के बीच अंतर करने के लिए कुछ तरीके निकालने होंगे जो कि सार्थक हो । मैं व्यक्तिगत रूप से "परीक्षा पास करने के लिए सबसे सरल काम करता हूँ" और "कहना है कि परीक्षण को पास करने के लिए सबसे सरल काम करते हैं कि आपके क्रियान्वयन को आसान बनाता है।" कोड को बदलने के लिए असफल परीक्षण लिखना आपका बहाना है, इसलिए जब आप प्रत्येक परीक्षण लिखने के लिए जाते हैं, तो आपको खुद से पूछना चाहिए "मेरा कोड क्या नहीं करता है कि मैं यह करना चाहता हूं और मैं उस कमी को कैसे उजागर कर सकता हूं?" यह आपके कोड को मजबूत बनाने और किनारे के मामलों को संभालने में भी आपकी मदद कर सकता है। यदि एक कॉलर इनपुट बकवास करता है तो आप क्या करते हैं?

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....
}

योग करने के लिए, यदि आप मूल्यों के हर संयोजन का परीक्षण कर रहे हैं, तो आप लगभग निश्चित रूप से इसे गलत कर रहे हैं (और सशर्त के दहनशील विस्फोट के साथ हवा की संभावना है)। जब यह TDD की बात आती है, तो आपको अपने इच्छित एल्गोरिथ्म को प्राप्त करने के लिए आवश्यक न्यूनतम परीक्षण परीक्षणों को लिखना चाहिए। आगे आप जो भी परीक्षण लिखेंगे वह हरे रंग का होने लगेगा और इस प्रकार दस्तावेजीकरण हो जाएगा, संक्षेप में, और टीडीडी प्रक्रिया का कड़ाई से हिस्सा नहीं। आवश्यकताओं को बदलने या बग सामने आने पर आप केवल TDD परीक्षण मामलों को लिखेंगे, जिस स्थिति में आप परीक्षण के साथ कमी का दस्तावेजीकरण करेंगे और फिर उसे पास करेंगे।

अद्यतन करें:

मैंने इसे आपके अपडेट के जवाब में एक टिप्पणी के रूप में शुरू किया था, लेकिन यह बहुत लंबा होने लगा ...

मैं कहता हूं कि समस्या शाब्दिक रूप से अस्तित्व में नहीं है, अवधि, लेकिन 'सरलतम' चीज के साथ 5-भाग सशर्त है। जब आप इसके बारे में सोचते हैं, तो 5-हिस्सा सशर्त वास्तव में बहुत जटिल होता है। रेड-टू-ग्रीन चरण के दौरान शाब्दिक का उपयोग करना और फिर उन्हें रिफ्लेक्टर चरण में स्थिरांक के लिए अमल करना सामान्य होगा या बाद के परीक्षण में उन्हें सामान्यीकृत किया जाएगा।

टीडीडी के साथ अपनी खुद की यात्रा के दौरान, मुझे एहसास हुआ कि बनाया जाने वाला एक महत्वपूर्ण अंतर है - "सरल" और "ओबट्यूज़" को भ्रमित करना अच्छा नहीं है। यही है, जब मैंने शुरुआत की, तो मैंने देखा कि लोग टीडीडी करते हैं और मैंने सोचा कि "वे परीक्षण पास करने के लिए सिर्फ सबसे कठिन काम कर रहे हैं" और मैंने थोड़ी देर के लिए नकल की, जब तक मुझे एहसास नहीं हुआ कि "सरल" सूक्ष्म रूप से अलग था की तुलना में "obtuse"। कभी-कभी वे ओवरलैप करते हैं, लेकिन अक्सर नहीं।

इसलिए, अगर मुझे लगता है कि माफी देना शाब्दिक अस्तित्व की समस्या थी - यह नहीं है। मैं कहता हूँ कि 5 खंडों के साथ सशर्त की जटिलता समस्या है। आपका पहला लाल-से-हरा बस "वापसी सच" हो सकता है क्योंकि यह वास्तव में सरल है (और संयोग से)। अगला परीक्षण मामला, (1, 2, 3, 4, 5) के साथ गलत वापस लौटना होगा, और यहीं से आप "पीछे हटना" शुरू करते हैं। आपको खुद से पूछना होगा "क्यों (1, 1, 1, 2, 2) एक पूर्ण घर है और (1, 2, 3, 4, 5) नहीं है?" सबसे सरल बात आप के साथ आ सकता है कि एक अंतिम अनुक्रम तत्व 5 या दूसरा अनुक्रम तत्व 2 है और दूसरा नहीं है। वे सरल हैं, लेकिन वे भी (अनावश्यक) अप्रिय हैं। क्या आप वास्तव में ड्राइव करना चाहते हैं, "उनके पास कितनी संख्या है?" तो आपको यह देखने के लिए कि क्या कोई रिपीट है या नहीं, यह देखने के लिए पास करके दूसरा टेस्ट पास कर सकते हैं। एक दोहराने के साथ, आपके पास एक पूर्ण घर है, और दूसरे में आप नहीं हैं। अब टेस्ट पास हो गया है, और आप एक और टेस्ट केस लिखते हैं जिसमें एक रिपीट होता है लेकिन अपने एल्गोरिथ्म को और अधिक परिष्कृत करने के लिए एक पूर्ण घर नहीं है।

जैसा कि आप जाते हैं, आप शाब्दिक रूप से ऐसा कर सकते हैं या नहीं कर सकते हैं, और यदि आप करते हैं तो यह ठीक है। लेकिन सामान्य विचार आपके एल्गोरिथ्म को 'संगठित' रूप से बढ़ा रहा है क्योंकि आप अधिक मामले जोड़ते हैं।


मैंने अपने प्रश्न को अपडेट किया है कि मैं शाब्दिक दृष्टिकोण के साथ क्यों शुरू किया गया था।
क्रिस्टोफ

9
यह एक बेहतरीन जवाब है।
19

1
आपके विचारशील और सुविचारित उत्तर के लिए आपका बहुत-बहुत धन्यवाद। यह वास्तव में बहुत मायने रखता है अब मैं इसके बारे में सोचता हूं।
क्रिस्टोफ ने

1
पूरी तरह से परीक्षण का मतलब हर संयोजन का परीक्षण करना नहीं है ... यह मूर्खतापूर्ण है। इस विशेष मामले के लिए, एक विशेष पूर्ण घर या दो और गैर पूर्ण घरों के एक जोड़े को लें। इसके अलावा कोई विशेष संयोजन जो परेशानी पैदा कर सकता है (यानी, एक तरह का 5)।
स्लेइस

3
+1। इस उत्तर के पीछे के सिद्धांतों का वर्णन रॉबर्ट सी। मार्टिन के परिवर्तन द्वारा किया गया है। प्रायोरिटी प्रीमेयर्स cleancoder.posterous.com/the-transformation-priority-premise
मार्क सेमन

5

एक विशेष संयोजन में पांच विशेष शाब्दिक मूल्यों के लिए परीक्षण मेरे बुखार वाले मस्तिष्क के लिए "सरलतम" नहीं है। यदि किसी समस्या का समाधान वास्तव में स्पष्ट है (गणना करें कि क्या आपके पास वास्तव में तीन और बिल्कुल किसी भी मूल्य के दो हैं ), तो हर तरह से उस समाधान को आगे बढ़ाएं और कुछ परीक्षण लिखें, जो बहुत ही आकस्मिक रूप से संतुष्ट होने की संभावना नहीं है आपके द्वारा लिखे गए कोड की मात्रा (यानी अलग-अलग शाब्दिक और अलग-अलग आदेशों के तीन और युगल)।

टीडीडी मैक्सिम वास्तव में उपकरण हैं, न कि धार्मिक विश्वास। उनका कहना है कि आपको सही, अच्छी तरह से फैक्टर कोड लिखना है। अगर एक मैक्सिम स्पष्ट रूप से उस रास्ते में खड़ा है, तो बस आगे कदम बढ़ाएं। नहीं होगा बहुत अपनी परियोजना में गैर स्पष्ट बिट्स जहां आप इसे लागू कर सकते हैं के।


5

एरिक का जवाब बहुत अच्छा है, लेकिन मैंने सोचा कि मैं परीक्षण लेखन में एक चाल साझा कर सकता हूं।

इस परीक्षण से शुरू करें:

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

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

यह परीक्षा और भी बेहतर हो जाती है यदि आप Roll5 पारमों को पास करने के बजाय एक वर्ग बनाते हैं :

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

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

यह इसे लागू करता है:

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

फिर यह परीक्षण लिखें:

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

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

एक बार जो बीत रहा है, उसे लिखें:

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

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

उसके बाद, मुझे यकीन है कि आपको कोई और लिखने की ज़रूरत नहीं है (शायद दो जोड़े, या शायद याहटज़ी, अगर आपको लगता है कि यह एक पूर्ण घर नहीं है)।

जाहिर है, यादृच्छिक रोल वापस करने के लिए अपने क्रिटेरिया से मिलने वाले किसी भी तरीके को लागू करें।

इस दृष्टिकोण के कुछ लाभ हैं:

  • आपको एक परीक्षण लिखने की आवश्यकता नहीं है जिसका एकमात्र उद्देश्य आपको विशिष्ट मूल्यों पर अटकने से रोकना है
  • परीक्षण आपके इरादे को वास्तव में अच्छी तरह से संवाद करते हैं (पहले परीक्षण का कोड "किसी भी पूर्ण घर में सच होता है" चिल्लाता है)
  • यह आपको समस्या के मांस पर काम करने के बिंदु पर जल्दी से ले जाता है
  • कभी-कभी यह उन मामलों को नोटिस करेगा जिनके बारे में आपने नहीं सोचा था

यदि आप यह दृष्टिकोण करते हैं तो आपको अपने Assert.That वक्तव्यों में अपने लॉग संदेशों में सुधार करना होगा। डेवलपर को यह देखने की जरूरत है कि किस इनपुट के कारण विफलता हुई।
Bringer128

क्या इससे चिकन-या-अंडे की दुविधा पैदा नहीं होती है? जब आप AnyFullHouse (TDD का उपयोग करके) लागू करते हैं, तो आपको इसकी शुद्धता को सत्यापित करने के लिए IsFullHouse की आवश्यकता नहीं होगी? विशेष रूप से, अगर AnyFullHouse में बग है, तो उस बग को IsFullHouse में दोहराया जा सकता है।
मोम

AnyFullHouse () एक परीक्षण मामले में एक विधि है। क्या आप आमतौर पर अपने परीक्षण मामलों को टीडीडी करते हैं? इसके अलावा, यह एक पूर्ण घर (या किसी भी अन्य रोल) के यादृच्छिक अनुकरण बनाने के लिए बहुत सरल है, क्योंकि यह अस्तित्व में है। बेशक, यदि आपके परीक्षण में बग है, तो इसे उत्पादन कोड में दोहराया जा सकता है। यह हालांकि हर परीक्षण का सच है।
talleth

AnyFullHouse एक परीक्षण के मामले में एक "सहायक" विधि है। यदि वे सामान्य रूप से पर्याप्त सहायक हैं तो उनका परीक्षण भी किया जाता है!
मार्क हर्ड

चाहिए IsFullHouseवास्तव में वापसी trueकरता है, तो pairNum == trioNum ?
recursion.ninja

2

मैं दो प्रमुख तरीकों के बारे में सोच सकता हूँ जो मैं इस पर परीक्षण करते समय विचार करूँगा;

  1. वैध पूर्ण-गृह सेटों के "कुछ" अधिक परीक्षण मामले (~ 5) जोड़ें, और अपेक्षित फ़ॉल्स की समान राशि ({1, 1, 2, 3, 3} एक अच्छा है। याद रखें कि उदाहरण के लिए 5 वाले हो सकते हैं। एक गलत कार्यान्वयन द्वारा "एक ही प्लस एक जोड़ी के 3" के रूप में मान्यता प्राप्त)। यह विधि मानती है कि डेवलपर न केवल परीक्षणों को पारित करने की कोशिश कर रहा है, बल्कि वास्तव में इसे सही तरीके से लागू करता है।

  2. पासा के सभी संभावित सेटों का परीक्षण करें (केवल 252 अलग-अलग हैं)। यह निश्चित रूप से मान लिया गया है कि आपके पास यह जानने का कोई तरीका है कि अपेक्षित उत्तर क्या है (परीक्षण में यह एक के रूप में जाना जाता है oracle।) यह उसी फ़ंक्शन, या एक इंसान का संदर्भ कार्यान्वयन हो सकता है। यदि आप वास्तव में कठोर होना चाहते हैं, तो प्रत्येक अपेक्षित परिणाम को मैन्युअल रूप से कोड करने के लिए इसके लायक हो सकता है।

जैसा कि ऐसा होता है, मैंने एक बार याहत्ज़ी एआई लिखा है, जिसमें से निश्चित रूप से नियमों को जानना था। आप स्कोर का आकलन भाग के लिए कोड प्राप्त कर सकते हैं यहां , कृपया ध्यान दें स्कैंडिनेवियाई संस्करण (डाइस) के लिए है कि कार्यान्वयन, और हमारे कार्यान्वयन मान लिया गया पासा क्रमबद्ध क्रम में दिया जाता है।


मिलियन डॉलर का सवाल है, क्या आपने शुद्ध टीडीडी का उपयोग करके यात्ज़ी एआई को प्राप्त किया है? मेरी शर्त है कि तुम नहीं कर सकते; आप है , डोमेन ज्ञान का उपयोग करने के लिए जो परिभाषा से अंधा नहीं है :)
एन्ड्रेस एफ

हाँ, मुझे लगता है कि तुम सही हो। यह टीडीडी के साथ एक सामान्य समस्या है, कि जब तक आप केवल अनपेक्षित क्रैश और बिना किसी अपवाद के परीक्षण नहीं करना चाहते हैं, तब तक परीक्षण के मामलों में अपेक्षित आउटपुट की आवश्यकता होती है।
ansjob

0

यह उदाहरण वास्तव में इस बिंदु को याद करता है। हम यहाँ एक एकल कार्य के बारे में बात कर रहे हैं एक सॉफ्टवेयर डिज़ाइन नहीं। क्या यह थोड़ा जटिल है? हां, तो आप इसे तोड़ दें। और आप बिल्कुल 1, 1, 1, 1, 1 से 6, 6, 6, 6, 6, 6 से हर संभव इनपुट का परीक्षण नहीं करते हैं। विचाराधीन फ़ंक्शन को ऑर्डर की आवश्यकता नहीं है, बस एक संयोजन, अर्थात् AAABB।

आपको 200 अलग तर्क परीक्षणों की आवश्यकता नहीं है। आप उदाहरण के लिए एक सेट का उपयोग कर सकते हैं। लगभग किसी भी प्रोग्रामिंग भाषा में एक बनाया गया है:

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;

और यदि आपको एक इनपुट मिलता है जो वैध याहती रोल नहीं है, तो आपको ऐसे फेंक देना चाहिए जैसे कल नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.