टीडीडी में, यदि मैं एक परीक्षण मामला लिखता हूं जो उत्पादन कोड को संशोधित किए बिना गुजरता है, तो इसका क्या मतलब है?


17

ये TD C. के लिए रॉबर्ट सी। मार्टिन के नियम हैं :

  • आपको किसी भी उत्पादन कोड को लिखने की अनुमति नहीं है जब तक कि यह एक असफल इकाई परीक्षण पास न हो।
  • आपको एक इकाई परीक्षण लिखने की अनुमति नहीं है जो असफल होने के लिए पर्याप्त है; और संकलन विफलताओं विफलताओं हैं।
  • आपको किसी भी अधिक उत्पादन कोड को लिखने की अनुमति नहीं है, एक असफल इकाई परीक्षा पास करने के लिए पर्याप्त है।

जब मैं एक परीक्षण लिखता हूं जो सार्थक लगता है लेकिन उत्पादन कोड को बदले बिना गुजरता है:

  1. क्या इसका मतलब है कि मैंने कुछ गलत किया है?
  2. क्या मुझे भविष्य में इस तरह के परीक्षण लिखने से बचना चाहिए अगर इसमें मदद की जा सके?
  3. क्या मुझे वह टेस्ट वहां छोड़ना चाहिए या उसे हटा देना चाहिए?

नोट: मैं यहाँ यह प्रश्न पूछना चाह रहा था : क्या मैं एक उत्तीर्ण इकाई परीक्षा से शुरू कर सकता हूँ? लेकिन मैं अब तक इस सवाल को अच्छी तरह से स्पष्ट नहीं कर पाया।


"बॉलिंग गेम काटा" जिस लेख में आप उद्धृत करते हैं, वह वास्तव में इसके अंतिम चरण के रूप में एक तत्काल परीक्षा है।
jscs

जवाबों:


21

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

कभी-कभी हम एक सिद्धांत को साबित करने के लिए परीक्षण लिखते हैं। परीक्षा पास हो जाती है और यह हमारे सिद्धांत को खारिज कर देती है। हम परीक्षण को नहीं हटाते हैं। हालांकि, हम यह जान सकते हैं कि हमारे पास स्रोत नियंत्रण का समर्थन है) उत्पादन कोड को तोड़ दें, यह सुनिश्चित करने के लिए कि हम समझते हैं कि जब हम इसकी उम्मीद नहीं करते थे तो यह क्यों बीत गया।

यदि यह एक वैध और सही परीक्षण है, और यह किसी मौजूदा परीक्षण की नकल नहीं कर रहा है, तो इसे वहीं छोड़ दें।


मौजूदा कोड के परीक्षण कवरेज में सुधार एक (उम्मीद है) पासिंग टेस्ट लिखने का एक और पूरी तरह से वैध कारण है।
जैक

13

इसका मतलब है कि या तो:

  1. आपने उत्पादन कोड लिखा था जो परीक्षण को पहले लिखे बिना आप चाहते हैं कि सुविधा को पूरा करता है ("धार्मिक TDD" का उल्लंघन), या
  2. आपको जिस सुविधा की आवश्यकता होती है, वह उत्पादन कोड द्वारा पहले ही पूरी हो जाती है, और आप उस सुविधा को कवर करने के लिए एक और इकाई परीक्षण लिख रहे हैं।

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

public void TestAddMethod()
{
    Assert.IsTrue(Add(2,3) == 5);
}

क्योंकि आपको वास्तव में केवल 2 और 3 का परिणाम एक साथ जोड़ा जाना चाहिए।

आपका कार्यान्वयन तरीका होगा:

public int add(int x, int y)
{
    return x + y;
}

लेकिन मान लीजिए कि मुझे अब 4 और 6 को एक साथ जोड़ने की आवश्यकता है:

public void TestAddMethod2()
{
    Assert.IsTrue(Add(4,6) == 10);
}

मुझे अपने तरीके को फिर से लिखने की ज़रूरत नहीं है, क्योंकि यह पहले से ही दूसरे मामले को कवर करता है।

अब कहते हैं कि मुझे पता चला है कि मेरे ऐड फंक्शन को वास्तव में एक नंबर को वापस करने की आवश्यकता है जिसमें कुछ सीलिंग है, चलो 100 कहते हैं। मैं एक नया तरीका लिख ​​सकता हूं जो यह परीक्षण करता है:

public void TestAddMethod3()
{
    Assert.IsTrue(Add(100,100) == 100);
}

और यह परीक्षण अब विफल हो जाएगा। मुझे अब अपने कार्य को फिर से लिखना होगा

public int add(int x, int y)
{
    var a = x + y;
    return a > 100 ? 100 : a;
}

इसे पास करने के लिए।

सामान्य ज्ञान यह बताता है कि यदि

public void TestAddMethod2()
{
    Assert.IsTrue(Add(4,6) == 10);
}

पास करता है, तो आप जानबूझकर अपनी पद्धति को विफल नहीं बनाते हैं ताकि आपके पास एक असफल परीक्षा हो सके ताकि आप इस परीक्षा को पास करने के लिए नया कोड लिख सकें।


5
यदि आपने मार्टिन के उदाहरणों का पूरी तरह से पालन किया (और वह जरूरी नहीं कि आप ऐसा करने का सुझाव दें), add(2,3)पास करने के लिए , आप सचमुच 5 लौटा देंगे। हार्ड-कोडित। फिर आप उस परीक्षण को लिखेंगे add(4,6)जिसके लिए आपको उत्पादन कोड लिखने के लिए मजबूर करना होगा जो add(2,3)एक ही समय में नहीं टूटने पर इसे पास करता है। आप के साथ समाप्त होगा return x + y, लेकिन आप इसके साथ शुरू नहीं करेंगे। सिद्धांत रूप में। स्वाभाविक रूप से, मार्टिन (या शायद यह कोई और था, मुझे याद नहीं है) शिक्षा के लिए इस तरह के उदाहरण प्रदान करना पसंद करता है, लेकिन आपको उम्मीद नहीं है कि आप वास्तव में इस तरह के तुच्छ कोड लिखेंगे।
एंथनी पेग्राम

1
@tieTYT, आम तौर पर, अगर मैं मार्टिन की पुस्तक (ओं) को सही ढंग से याद करता हूं, तो दूसरा परीक्षण मामला आम तौर पर आपको एक सरल विधि के लिए सामान्य समाधान लिखने के लिए पर्याप्त होगा (और, वास्तव में, आप वास्तव में इसे सिर्फ काम करेंगे। पहली बार)। किसी तीसरे की जरूरत नहीं।
एंथनी पेग्राम

2
@tieTYT, तब तक आप परीक्षण लिखते रहेंगे जब तक आपने नहीं किया। :)
एंथनी पेग्राम

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

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

2

आपका परीक्षा पास है लेकिन आप गलत नहीं हैं। मुझे लगता है, ऐसा इसलिए हुआ क्योंकि प्रोडक्शन कोड शुरू से टीडीडी नहीं है।

मान लीजिए विहित (?) टीडीडी। कोई उत्पादन कोड नहीं है, लेकिन कुछ परीक्षण मामले (जो निश्चित रूप से हमेशा विफल होते हैं)। हम पास करने के लिए उत्पादन कोड जोड़ते हैं। फिर अधिक असफल परीक्षण मामले को जोड़ने के लिए यहां रुकें। फिर से जोड़ने के लिए उत्पादन कोड जोड़ें।

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

मुझे व्यक्तिगत रूप से ऐसे अधिनायकवादी, अमानवीय नियम पसंद नहीं हैं;


2

दरअसल कल रात एक डोज पर भी यही मुद्दा सामने आया था।

मैंने इस पर एक त्वरित शोध किया। मैंने ये ढूंढ निकाला:

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

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

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

यदि आप केवल सख्त TDD का अभ्यास करना चाहते हैं तो आप शुरू से ही कोई अतिरिक्त परीक्षण नहीं लिख सकते हैं। एक उद्यम विकास के माहौल में दूसरी ओर वास्तव में टीडीडी अभ्यास छोड़ देना चाहिए यदि अतिरिक्त परीक्षण उपयोगी लगते हैं।


0

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

जब आप मुसीबत में पड़ते हैं, जब आप समस्या के स्थान को समझने के लिए प्रतिस्थापन के रूप में पहले से ही गुजर रहे परीक्षा लिखते हैं।

हम दो चरम सीमाओं पर कल्पना कर सकते हैं: एक प्रोग्रामर जो बड़ी संख्या में परीक्षण लिखता है "बस के मामले में" एक बग को पकड़ता है; और दूसरा प्रोग्रामर जो न्यूनतम संख्या में परीक्षण लिखने से पहले समस्या स्थान का सावधानीपूर्वक विश्लेषण करता है। मान लें कि दोनों एक निरपेक्ष मान फ़ंक्शन को लागू करने का प्रयास कर रहे हैं।

पहला प्रोग्रामर लिखते हैं:

assert abs(-88888) == 88888
assert abs(-12345) == 12345
assert abs(-5000) == 5000
assert abs(-32) == 32
assert abs(46) == 46
assert abs(50) == 50
assert abs(5001) == 5001
assert abs(999999) == 999999
...

दूसरा प्रोग्रामर लिखते हैं:

assert abs(-1) == 1
assert abs(0) == 0
assert abs(1) == 1

पहले प्रोग्रामर के कार्यान्वयन में परिणाम हो सकता है:

def abs(n):
    if n < 0:
        return -n
    elif n > 0:
        return n

दूसरे प्रोग्रामर के कार्यान्वयन के परिणामस्वरूप हो सकता है:

def abs(n):
    if n < 0:
        return -n
    else:
        return n

सभी परीक्षण पास हो जाते हैं, लेकिन पहले प्रोग्रामर ने न केवल कई निरर्थक परीक्षण लिखे हैं (अनावश्यक रूप से उनके विकास चक्र को धीमा कर रहे हैं), बल्कि एक सीमा मामले का परीक्षण करने में भी विफल रहे हैं (abs(0) ) ।

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


खैर, दूसरा प्रोग्रामर स्पष्ट रूप से परीक्षणों के साथ-साथ लापरवाह था, क्योंकि उसके सहकर्मी को फिर से परिभाषित abs(n) = n*nऔर पारित किया गया था।
Eiko

@ ईको तुम बिल्कुल सही हो। बहुत कम परीक्षण लिखना आपको बुरी तरह से काट सकता है। कम से कम परीक्षण द्वारा दूसरा प्रोग्रामर अत्यधिक कंजूस था abs(-2)। सब कुछ के साथ, मॉडरेशन कुंजी है।
थिंकट्री
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.