कार्यान्वयन लिखने के बाद परीक्षण में एक गलती को कैसे सुधारें


21

टीडीडी में कार्रवाई का सबसे अच्छा कोर्स क्या है यदि, तर्क को सही ढंग से लागू करने के बाद, परीक्षण अभी भी विफल रहता है (क्योंकि परीक्षण में कोई गलती है)?

उदाहरण के लिए, मान लें कि आप निम्नलिखित फ़ंक्शन को विकसित करना चाहते हैं:

int add(int a, int b) {
    return a + b;
}

मान लीजिए कि हम इसे निम्नलिखित चरणों में विकसित करते हैं:

  1. परीक्षण लिखें (अभी तक कोई कार्य नहीं):

    // test1
    Assert.assertEquals(5, add(2, 3));
    

    संकलन त्रुटि में परिणाम।

  2. डमी फ़ंक्शन कार्यान्वयन लिखें:

    int add(int a, int b) {
        return 5;
    }
    

    परिणाम: test1गुजरता है।

  3. एक और परीक्षण मामला जोड़ें:

    // test2 -- notice the wrong expected value (should be 11)!
    Assert.assertEquals(12, add(5, 6));
    

    परिणाम: test2विफल रहता है, test1अभी भी गुजरता है।

  4. वास्तविक कार्यान्वयन लिखें:

    int add(int a, int b) {
        return a + b;
    }
    

    परिणाम: test1अभी भी गुजरता है, test2अभी भी विफल रहता है (तब से 11 != 12)।

इस विशेष मामले में: क्या यह बेहतर होगा:

  1. सही test2, और देखें कि यह अब गुजरता है, या
  2. कार्यान्वयन के नए हिस्से को हटाएं (यानी # चरण 2 से ऊपर जाएं), सही करें test2और इसे विफल होने दें, और फिर सही कार्यान्वयन (चरण # 4। ऊपर) को फिर से शुरू करें।

या कोई और, चतुर तरीका है?

जब मैं समझता हूं कि उदाहरण की समस्या बल्कि तुच्छ है, तो मुझे दिलचस्पी है कि मैं जेनेरिक मामले में क्या करूं, जो दो संख्याओं के जोड़ से अधिक जटिल हो सकता है।

EDIT (@Thomas Junk के जवाब के लिए):

इस सवाल का फोकस वही है जो इस तरह के मामले में टीडीडी सुझाव देता है, न कि अच्छे कोड या परीक्षण प्राप्त करने के लिए "सार्वभौमिक सार्वभौमिक अभ्यास" जो (टीडीडी-वे की तुलना में भिन्न हो सकता है)।


3
लाल पट्टी के खिलाफ एक प्रासंगिक अवधारणा है।
रबरडक

5
स्पष्ट रूप से, आपको अपने TDD पर TDD करने की आवश्यकता है।
ब्लरफ्ल

17
अगर कोई मुझसे कभी पूछता है कि मुझे टीडीडी से संदेह क्यों है तो मैं उन्हें इस सवाल का संकेत दूंगा। यह कफकेस्क है।
Traubenfuchs

@Brfl कि Xibit हमें क्या कहता है »मैंने TDD में TDD डाला ताकि आप TDD करते समय TDD कर सके«: D
थॉमस जोड़

3
@Traubenfuchs मैं स्वीकार करता हूं कि यह प्रश्न पहली नजर में मूर्खतापूर्ण लगता है और मैं "हर समय TDD करना" का हिमायती नहीं हूं, लेकिन मेरा मानना ​​है कि टेस्ट फेल देखने का एक मजबूत लाभ है, फिर कोड लिखें जो टेस्ट पास करता है (जो यह प्रश्न वास्तव में है, आखिरकार है)।
विन्सेन्ट सेवार्ड

जवाबों:


31

बिल्कुल महत्वपूर्ण बात यह है कि आप परीक्षा पास और फेल दोनों देखते हैं।

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

परीक्षण को देखना और पास होना दोनों ही विफल हैं कि आप परीक्षा कैसे देते हैं। कभी भी उस परीक्षा पर भरोसा न करें जिसे आपने कभी नहीं देखा है।


रेड बार के खिलाफ फिर से काम करना हमें एक कार्यशील परीक्षण को फिर से तैयार करने के लिए औपचारिक कदम देता है:

  • परीक्षण चलाएं
    • हरे रंग की पट्टी पर ध्यान दें
    • परीक्षण किया जा रहा कोड को तोड़ें
  • परीक्षण चलाएं
    • लाल पट्टी पर ध्यान दें
    • परीक्षण को रिफलेक्टर करें
  • परीक्षण चलाएं
    • लाल पट्टी पर ध्यान दें
    • परीक्षण किए जा रहे कोड को अन-ब्रेक करें
  • परीक्षण चलाएं
    • हरे रंग की पट्टी पर ध्यान दें

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

यदि ऐसा नहीं होता है, और कोड को कवर करने वाले अन्य परीक्षणों के कारण कोड कवरेज चिंता का विषय नहीं है, तो आप परीक्षण को बदल सकते हैं और इसे हरे परीक्षण के रूप में पेश कर सकते हैं।

यहां, कोड को वापस भी रोल किया जा रहा है, लेकिन परीक्षण को विफल करने के लिए पर्याप्त है। यदि केवल बगिया परीक्षण द्वारा कवर किए गए सभी कोड को कवर करने के लिए पर्याप्त नहीं है, तो हमें एक बड़ा कोड रोल बैक और अधिक परीक्षण की आवश्यकता है।

एक हरे रंग की परीक्षा का परिचय दें

  • परीक्षण चलाएं
    • हरे रंग की पट्टी पर ध्यान दें
    • परीक्षण किया जा रहा कोड को तोड़ें
  • परीक्षण चलाएं
    • लाल पट्टी पर ध्यान दें
    • परीक्षण किए जा रहे कोड को अन-ब्रेक करें
  • परीक्षण चलाएं
    • हरे रंग की पट्टी पर ध्यान दें

कोड को तोड़ना कोड बाहर टिप्पणी कर सकता है या इसे कहीं और स्थानांतरित कर सकता है केवल इसे बाद में पेस्ट करने के लिए। यह हमें टेस्ट कवर के कोड की गुंजाइश दिखाता है।

इन अंतिम दो रनों के लिए आप सामान्य लाल हरे चक्र में वापस आ गए हैं। कोड को अन-ब्रेक करने और टेस्ट पास करने के बजाय आप केवल पेस्ट कर रहे हैं। इसलिए सुनिश्चित करें कि आप परीक्षा पास करने के लिए केवल पर्याप्त रूप से चिपका रहे हैं।

यहां समग्र पैटर्न परीक्षण के रंग को देखने का तरीका है जिससे हम उम्मीद करते हैं। ध्यान दें कि यह एक ऐसी स्थिति बनाता है जहां आप संक्षेप में एक गैर-विश्वसनीय ग्रीन परीक्षण करते हैं। इन चरणों में आप कहाँ हैं और यह भूल जाने के बारे में सावधान रहें।

मेरे धन्यवाद RubberDuck के लिए गले लगाते लाल बार लिंक।


2
मुझे यह उत्तर सबसे अच्छा लगता है: परीक्षण को गलत कोड के साथ विफल देखना महत्वपूर्ण है, इसलिए मैं कोड को हटा / टिप्पणी करूंगा, परीक्षणों को सही करूंगा और उन्हें विफल देखूंगा, कोड को वापस रख सकता हूं (शायद परीक्षण को डालने के लिए एक जानबूझकर त्रुटि का परिचय दें परीक्षण) और इसे काम करने के लिए कोड करने के लिए सही है। इसे पूरी तरह से हटाने और इसे फिर से लिखने के लिए बहुत XP है, लेकिन कभी-कभी आपको बस व्यावहारिक होना चाहिए। ;)
गोएल्ज़ट्रॉल २

@GolezTrol मुझे लगता है कि मेरा जवाब एक ही बात कहता है, इसलिए मुझे लगता है कि स्पष्ट नहीं था कि आप किसी भी प्रतिक्रिया की सराहना करेंगे।
जोनरशेप

@jonrsharpe आपका उत्तर भी अच्छा है, और मैंने इसे पढ़ने से पहले ही इसे बदल दिया। लेकिन जहां आप कोड को वापस करने में बहुत सख्त हैं, CandiedOrange एक अधिक व्यावहारिक दृष्टिकोण का सुझाव देता है जो मेरे लिए और अधिक अपील करता है।
GolezTrol

@GolezTrol मैंने यह नहीं कहा कि कोड को वापस कैसे लाया जाए; इसे टिप्पणी करें, काटें और पेस्ट करें, इसे स्टैश करें, अपने आईडीई के इतिहास का उपयोग करें; यह वास्तव में कोई फर्क नहीं पड़ता। महत्वपूर्ण बात यह है कि आप ऐसा क्यों करते हैं: ताकि आप जांच सकें कि आपको सही विफलता मिल रही है । मैंने संपादित किया है, स्पष्ट रूप से स्पष्ट करने के लिए।
जोंशरशिप

10

समग्र लक्ष्य क्या है , आप हासिल करना चाहते हैं?

  • अच्छा परीक्षण कर रहे हैं?

  • बनाना सही कार्यान्वयन?

  • टीटीडी धार्मिक रूप से सही है ?

  • इनमे से कोई भी नहीं?

शायद आप परीक्षण और परीक्षण के लिए अपने रिश्ते को खत्म कर देते हैं।

परीक्षण कार्यान्वयन की शुद्धता के बारे में कोई गारंटी नहीं देते हैं । सभी परीक्षणों के पास होने के बारे में कुछ भी नहीं कहा गया है, चाहे आपका सॉफ़्टवेयर वही करे जो उसे करना चाहिए; यह आपके सॉफ़्टवेयर के बारे में कोई आवश्यक बयान नहीं देता है ।

अपना उदाहरण लेते हुए:

जोड़ का "सही" कार्यान्वयन कोड के बराबर होगा a+b। और जब तक आपका कोड ऐसा करता है, आप कहेंगे कि एल्गोरिथ्म सही है कि यह क्या करता है और सही तरीके से लागू होता है।

int add(int a, int b) {
    return a + b;
}

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

लेकिन क्या हम वास्तव में कर रहे हैं कह रहा है नहीं, कि इस कोड है के कार्यान्वयन additionयह केवल एक निश्चित सीमा तक बर्ताव करता है एक की तरह: के बारे में सोच पूर्णांक अतिप्रवाह

कोड में अतिरंजना होती है, लेकिन अवधारणा में नहीं addition। तो: आपका कोड एक निश्चित सीमा तक व्यवहार करता है जैसे की अवधारणा addition, लेकिन ऐसा नहीं है addition

इसके बजाय दार्शनिक दृष्टिकोण के कई परिणाम हैं।

और एक यह है कि आप कह सकते हैं, परीक्षण आपके कोड के अपेक्षित व्यवहार की धारणाओं से अधिक कुछ नहीं हैं । अपने कोड का परीक्षण में, आप कर सके (शायद) कभी नहीं यकीन है कि, अपने बनाने के कार्यान्वयन है सही , सबसे अच्छा आप कह सकते हैं, कि क्या परिणाम आपके कोड थे भेजती है या नहीं मिले थे पर अपनी उम्मीदों; ऐसा हो, कि आपका कोड गलत हो, ऐसा हो, कि आपका परीक्षण गलत हो या ऐसा हो, कि दोनों गलत हों।

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

जब आप गलत धारणाएं बनाते हैं, तो यह मदद नहीं करता है; लेकिन नमसते! कम से कम यह स्किज़ोफ्रेनिया को रोकता है: विभिन्न परिणामों की अपेक्षा करना जब कोई नहीं होना चाहिए।


tl; डॉ

टीडीडी में कार्रवाई का सबसे अच्छा कोर्स क्या है यदि, तर्क को सही ढंग से लागू करने के बाद, परीक्षण अभी भी विफल रहता है (क्योंकि परीक्षण में कोई गलती है)?

आपके परीक्षण कोड के व्यवहार के बारे में धारणाएं हैं। यदि आपको लगता है कि आपका कार्यान्वयन सही है, तो परीक्षण को ठीक करें और देखें कि क्या धारणा है।


1
मुझे लगता है कि समग्र लक्ष्यों के बारे में सवाल काफी महत्वपूर्ण है, इसे लाने के लिए धन्यवाद। मेरे लिए, सर्वोच्च प्रियो निम्नलिखित है: 1. सही कार्यान्वयन 2. "अच्छा" परीक्षण (या, मैं बल्कि कहूंगा, "उपयोगी" / "अच्छा डिज़ाइन किया गया" परीक्षण)। मैं उन दो लक्ष्यों को प्राप्त करने के लिए टीडीडी को एक संभावित उपकरण के रूप में देखता हूं। इसलिए, जब मैं आवश्यक रूप से धार्मिक रूप से टीडीडी का पालन नहीं करना चाहता, तो इस सवाल के संदर्भ में, मैं ज्यादातर टीडीडी के परिप्रेक्ष्य में दिलचस्पी रखता हूं। मैं इसे स्पष्ट करने के लिए प्रश्न को संपादित करूँगा।
एटिलियो

तो, क्या आप एक ऐसा परीक्षण लिखेंगे जो अतिप्रवाह के लिए परीक्षण करता है और जब यह होता है तब गुजरता है या क्या आप इसे विफल कर देंगे जब ऐसा होता है क्योंकि एल्गोरिथ्म इसके अलावा है और अतिप्रवाह गलत उत्तर का उत्पादन करता है?
जेरी यिर्मयाह

1
@JerryJeremiah मेरी बात है: आपके परीक्षणों को कवर करना चाहिए जो आपके उपयोग के मामले पर निर्भर है। एक उपयोग के मामले में जहां आप एकल अंकों का एक गुच्छा जोड़ते हैं, एल्गोरिथ्म काफी अच्छा है । यदि आप जानते हैं, कि यह बहुत संभावना है कि आप "बड़ी संख्या" जोड़ते हैं, तो datatypeस्पष्ट रूप से गलत विकल्प है। एक परीक्षण से पता चलता है कि: आपकी अपेक्षा »बड़ी संख्याओं के लिए काम करती है« और कई मामलों में नहीं मिली है। फिर सवाल यह होगा कि उन मामलों से कैसे निपटा जाए। क्या वे कोने के मामले हैं? जब हाँ, उनसे कैसे निपटें? शायद कुछ क्वार्ड क्लॉस अधिक गड़बड़ को रोकने में मदद करते हैं। इसका उत्तर संदर्भ बाध्य है।
थॉमस जं।

7

आपको यह जानना आवश्यक है कि यदि कार्यान्वयन गलत है, तो परीक्षण विफल हो रहा है, जो कार्यान्वयन के सही होने पर पास होने के समान नहीं है। इसलिए आपको कोड को एक ऐसी स्थिति में वापस रखना चाहिए जहां आप उम्मीद करते हैं कि यह परीक्षण को सही करने से पहले विफल हो जाएगा , और सुनिश्चित करें कि यह आपके द्वारा अपेक्षित (यानी 5 != 12) कारण के लिए विफल हो जाता है , बजाय इसके कि आप भविष्यवाणी नहीं करते।


हम यह कैसे जाँच सकते हैं कि परीक्षण उस कारण के लिए असफल हो रहा है जिसकी हम अपेक्षा करते हैं?
बसिलेव्स

2
@ बिसिलेव्स आप: 1. एक परिकल्पना करें कि विफलता का कारण क्या होना चाहिए; 2. परीक्षण चलाने; और 3. परिणामी विफलता संदेश पढ़ें और तुलना करें। कभी-कभी यह भी सुझाव देता है कि आप परीक्षण को फिर से लिख सकते हैं ताकि आपको अधिक सार्थक त्रुटि मिल सके (उदाहरण के लिए, दोनों एक ही चीज़ का परीक्षण करने पर भी assertTrue(5 == add(2, 3))कम उपयोगी आउटपुट देता assertEqual(5, add(2, 3))है)।
जोनरशेप

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

1
@ बिसिलेव्स क्या? चरण 3 पर आपकी परिकल्पना "परीक्षा में विफल हो जाएगी क्योंकि 5 12 के बराबर नहीं है" । परीक्षण चलाना आपको यह दिखाएगा कि क्या परीक्षण उस कारण से विफल हो जाता है, जिस स्थिति में आप आगे बढ़ते हैं, या किसी अन्य कारण से, जिस स्थिति में आप ऐसा करते हैं। शायद यह एक भाषा की समस्या है, लेकिन यह मेरे लिए स्पष्ट नहीं है कि आप क्या सुझाव दे रहे हैं।
जोंशरशिप

5

इस विशेष मामले में, यदि आप 12 को 11 में बदलते हैं, और परीक्षण अब पास हो जाता है, तो मुझे लगता है कि आपने परीक्षण के साथ-साथ कार्यान्वयन का भी अच्छा काम किया है, इसलिए अतिरिक्त हुप्स से गुजरने की बहुत आवश्यकता नहीं है।

हालाँकि, एक ही समस्या अधिक जटिल स्थितियों में आ सकती है, जैसे कि जब आपके सेटअप कोड में कोई गलती हो। उस मामले में, अपने परीक्षण को ठीक करने के बाद, आपको संभवतः अपने कार्यान्वयन को इस तरह से बदलने की कोशिश करनी चाहिए ताकि उस विशेष परीक्षण को विफल कर दिया जा सके, और फिर उत्परिवर्तन को वापस कर दिया जाए। यदि कार्यान्वयन को पुनः प्राप्त करना ऐसा करने का सबसे आसान तरीका है, तो यह ठीक है। अपने उदाहरण में, आप उत्परिवर्तित हो सकता है a + bकरने के लिए a + aया a * b

वैकल्पिक रूप से, यदि आप दावे को थोड़ा बदल सकते हैं और परीक्षण को विफल देख सकते हैं, तो यह परीक्षण का परीक्षण करने में बहुत प्रभावी हो सकता है।


0

मैं कहूंगा, यह आपके पसंदीदा संस्करण नियंत्रण प्रणाली के लिए एक मामला है:

  1. परीक्षण के सुधार को चरणबद्ध करें, अपने कोड को अपनी कार्यशील निर्देशिका में बदलते रहें।
    एक संगत संदेश के साथ प्रतिबद्ध Fixed test ... to expect correct output

    इसके साथ git, git add -pयदि परीक्षण और कार्यान्वयन एक ही फ़ाइल में हैं, तो इसके उपयोग की आवश्यकता हो सकती है , अन्यथा आप स्पष्ट रूप से दो फ़ाइलों को अलग-अलग चरण में ला सकते हैं।

  2. कार्यान्वयन कोड प्रतिबद्ध करें।

  3. चरण 1 में किए गए प्रतिबद्ध का परीक्षण करने के लिए समय पर वापस जाएं, यह सुनिश्चित करते हुए कि परीक्षण वास्तव में विफल रहता है

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

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