TDD में आपके बच्चे के बच्चे कैसे हैं?


37

आज हम TDD का प्रशिक्षण ले रहे थे और गलतफहमी के निम्नलिखित बिंदु पाए गए।

कार्य संख्याओं के "1,2" रिटर्न योग के लिए है, जो 3. है जो मैंने लिखा है (सी # में) था:

numbers = input.Split(',');
return int.Parse(numbers[0]) + int.Parse(numbers[1]); //task said we have two numbers and input is correct

लेकिन दूसरे लोग इसे दूसरे तरीके से करना पसंद करते थे। पहला, इनपुट "1,2" के लिए उन्होंने निम्नलिखित कोड जोड़ा:

if (input == "1,2")
   return 3;

फिर उन्होंने इनपुट "4,5" के लिए एक और परीक्षण पेश किया और कार्यान्वयन को बदल दिया:

if (input == "1,2")
   return 3;
else if (input == "4,5")
   return 9;

और इसके बाद उन्होंने कहा "ठीक है, अब हम पैटर्न देखते हैं" और जो मैंने शुरू में किया उसे लागू किया।

मुझे लगता है कि दूसरा दृष्टिकोण टीडीडी परिभाषा को बेहतर मानता है लेकिन ... क्या हमें इसके बारे में इतना सख्त होना चाहिए? मेरे लिए यह ठीक है कि तुच्छ बच्चे के कदमों को छोड़ दें और उन्हें "ट्विनस्टेप्स" में मिला दें, अगर मुझे यकीन है कि मैं कुछ भी नहीं छोड़ूंगा। क्या मै गलत हु?

अद्यतन करें। मैंने यह स्पष्ट करके गलती की है कि यह पहली परीक्षा नहीं थी। पहले से ही कुछ परीक्षण थे इसलिए "रिटर्न 3" वास्तव में आवश्यकता को पूरा करने के लिए सबसे सरल कोड नहीं था।


25
इतना छोटा कि मेरे सहकर्मी "ऊओहह दाज़ो क्यूउउउउउउउउउउउ"
आदिल

6
@Adel: लगभग मेरी नाश्ता पर चोक हो चुके, कीबोर्ड अब पूर्ण या थूक और टुकड़ों
बाइनरी worrier

2
@ एडेल, गैर-देशी वक्ता के रूप में, मेरे लिए इस हास्य को समझना मुश्किल है, लेकिन मुझे लगता है कि आपके सहकर्मी इस प्रश्न की तरह ही हैं :)
साइबेरियाई

8
@ भारत: यह एक सहकर्मी की प्रतिक्रिया को प्रसारित कर रहा है, जब एक चिल्ड को दिखाया गया है पहला कदम "ऊओहह दाज़ो क्यूउउउउतेउत" = "ओह जो बहुत प्यारा है" (एक गायन-गीत में बोला-नहीं-वह-बहुत प्यारा आवाज), उनकी प्रतिक्रिया के साथ जब यूनिट टेस्ट को एडेल द्वारा लिखा जाता है, तो यूनिट टेस्ट के बेबी स्टेप्स को देखकर वे कहते हैं कि "ओह यह बहुत प्यारा है"। एक - वास्तविक - शिशुओं के कदमों की प्रतिक्रिया = इकाई परीक्षणों "बेबी स्टेप्स" पर प्रतिक्रिया।
बाइनरी वॉरियर

3
@ Binaryworrier काश मैं आपको पितृत्व को समझाने के लिए समय निकालने के लिए वास्तविक अंक दे सकता था
एंड्रयू टी फिननेल २२'११

जवाबों:


31

सरलतम कोड लिखें जो परीक्षणों को पास करता है।

आप में से किसी ने भी ऐसा नहीं किया, जहां तक ​​मैं देख सकता हूं।

बेबी स्टेप 1।

परीक्षण: इनपुट "1,2" के लिए अंकों की वापसी राशि जो 3 है

परीक्षण को विफल करें:

throw NotImplementedException();

परीक्षा पास करें:

return 3;

बेबी स्टेप 2।

परीक्षण: संख्याओं के इनपुट "1,2" रिटर्न योग के लिए, जो 3 है

परीक्षण: संख्याओं के इनपुट "4,5" रिटर्न योग के लिए, जो 9 है

दूसरा परीक्षण विफल रहता है, इसलिए इसे पास करें:

numbers = input.Split(',');
return int.Parse(numbers[0]) + int.Parse(numbers[1]);

(अगर की एक सूची की तुलना में आसान तरीका ... वापसी)

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

तर्क यह है कि यदि आप दूसरा परीक्षण नहीं लिखते हैं तो बाद में कुछ चमकीली चिंगारी आ सकती है और पढ़ने के लिए आपका कोड "रिफ्लेक्टर" हो सकता है:

return input.Length; # Still satisfies the first test

और, दोनों कदम उठाए बिना, आपने कभी भी दूसरा परीक्षण लाल नहीं किया (इसका अर्थ है कि परीक्षण स्वयं संदिग्ध है)।


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

@ इडासा - हां, बिल्कुल, और जितना अधिक परीक्षण आप लिखते हैं, कार्यान्वयन उतना ही अधिक पागल होना होगा। input.Lengthऐसा नहीं है कि बहुत दूर है, खासकर अगर विधि का इनपुट कहीं न कहीं किसी फ़ाइल से माप होता है और आप अनजाने में अपनी विधि कहते हैं Size()
पीडीआर

6
+1। टीडीडी सीखने के तरीके के संबंध में, यह सही तरीका है। एक बार जब आप इसे सीख लेते हैं, तो आप कभी-कभी स्पष्ट कार्यान्वयन के लिए सीधे जा सकते हैं, लेकिन टीडीडी के लिए महसूस करने के लिए, यह बहुत बेहतर है।
कार्ल मैनस्टर

1
मेरे पास "परीक्षण" से संबंधित एक प्रश्न है। क्या आप इनपुट "4,5" के लिए एक नया परीक्षण लिखेंगे , या मूल परीक्षण को संशोधित करेंगे?
mxmissile

1
@mxmissile: मैं एक नई परीक्षा लिखूंगा। यह बहुत समय नहीं लेता है और जब आप बाद में रिफैक्टरिंग करते हैं तो आपकी रक्षा के लिए आप दो बार परीक्षण करते हैं।
पीपीआर

50

मुझे लगता है कि दूसरा तरीका है दिमाग सुन्न होना। मुझे छोटे पर्याप्त कदम बनाने में मूल्य दिखाई देता है, लेकिन उन छोटे युग्मन (उन्हें बच्चे भी नहीं कह सकते हैं) को लिखना केवल असिन और समय की बर्बादी है। खासकर यदि आप जो मूल समस्या हल कर रहे हैं वह पहले से ही बहुत छोटी है।

मुझे पता है कि यह प्रशिक्षण है और यह सिद्धांत दिखाने के बारे में अधिक है, लेकिन मुझे लगता है कि ऐसे उदाहरण TDD को अच्छे से अधिक खराब करते हैं। यदि आप बच्चे के चरणों का मूल्य दिखाना चाहते हैं, तो कम से कम एक समस्या का उपयोग करें जहां इसमें कुछ मूल्य है।


+1 और मुझे एक नया शब्द (असिन) देखने और सीखने के लिए धन्यवाद
मार्जन वेनेमा सेप

12
इसे स्तब्ध रूप से बेवकूफ कहने के लिए +1। टीडीडी सभी अच्छा और ऐसा है, लेकिन किसी भी आधुनिक हाइपेड प्रोग्रामिंग तकनीक की तरह आपको इस बात का ध्यान रखना चाहिए कि इसमें खोई नहीं जाए।
7

2
"विशेष रूप से यदि मूल समस्या जिसे आप हल कर रहे हैं वह पहले से ही बहुत छोटी है।" - यदि इनपुट को एक साथ जोड़े जाने के लिए दो ints थे, तो मैं इस बात से सहमत हो जाऊंगा, लेकिन जब "स्ट्रिंग को विभाजित करने, परिणाम से दो inse को विभाजित करने और उन्हें जोड़ने के लिए मैं आश्वस्त नहीं हूं।" वास्तविक दुनिया में अधिकांश विधियाँ इससे अधिक जटिल नहीं हैं। वास्तव में, आने वाले मामलों को कवर करने के लिए और अधिक परीक्षण होने चाहिए, जैसे दो अल्पविराम, गैर-पूर्णांक मान, आदि
pdr

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

1
@ChristopheVanfleteren: जब बेक स्पष्ट कार्यान्वयन का वर्णन करता है, तो वह उदाहरण के रूप में दो ints के योग का उपयोग करता है और फिर भी एक बड़ी नाटकीय चेतावनी में फेंकता है कि आप कैसे शर्म से मरने जा रहे हैं यदि आपकी जोड़ी / समीक्षक सरल कोड के बारे में सोच सकते हैं जो बनाता है परीक्षा उत्तीर्ण। यह एक पूर्ण निश्चितता है यदि आप इस परिदृश्य के लिए केवल एक परीक्षण लिखते हैं। इसके अलावा, मैं इस समस्या को हल करने के कम से कम तीन "स्पष्ट" तरीकों के बारे में सोच सकता हूं: विभाजित करें और जोड़ें, अल्पविराम को + के साथ बदलें और मूल्यांकन करें, या रेगेक्स का उपयोग करें। TDD की बात आपको सही चुनाव के लिए प्रेरित करती है।
पीडीआर

19

केंट बेक ने अपनी पुस्तक, टेस्ट ड्रिवेन डेवलपमेंट: बाय उदाहरण में इसे शामिल किया है।

आपका उदाहरण एक ' स्पष्ट कार्यान्वयन ' को इंगित करता है - आप दो इनपुट मानों को वापस करना चाहते हैं, और यह प्राप्त करने के लिए एक काफी बुनियादी एल्गोरिथ्म है। आपका काउंटर-उदाहरण 'इसे नकली बनाने तक गिरता है जब तक आप इसे नहीं बनाते हैं' (हालाँकि यह बहुत ही साधारण मामला है)।

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

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

पुस्तक से:

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


18

मैं इसे कानून के पत्र के रूप में देखता हूं, लेकिन इसकी भावना नहीं।

आपके बच्चे के कदम होने चाहिए:

जितना संभव हो उतना सरल, लेकिन कोई सरल नहीं।

साथ ही, विधि में क्रिया है sum

if (input == "1,2")
   return 3;

राशि नहीं है, यह विशिष्ट इनपुट के लिए एक परीक्षण है।


4

मेरे लिए यह एक बहुत कम तुच्छ में कई तुच्छ कार्यान्वयन चरणों को संयोजित करने के लिए ठीक लगता है - मैं हर समय ऐसा करता हूं। मुझे नहीं लगता कि किसी को पत्र के लिए हर समय टीडीडी के बाद धार्मिक होने की आवश्यकता है।

OTOH यह केवल उपरोक्त उदाहरण की तरह तुच्छ चरणों के लिए लागू होता है। कुछ और जटिल के लिए, जिसे मैं एक बार में पूरी तरह से अपने दिमाग में नहीं रख सकता / और जहां मैं परिणाम के बारे में 110% सुनिश्चित नहीं हूं, मैं एक बार में एक कदम जाना पसंद करता हूं।


1

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

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

क्या यह वर्ग जो मेरे सिर में है वह वास्तव में काम करने वाला है?

या

कैसे नरक मैं भी इस बात को करने जा रहा हूँ?

The point is that I can switch between big steps and little steps in the blink of an eye. For example if a big step doesn't work and I can't see an obvious way around it I will switch to a smaller step. If that doesn't work I will switch to an even smaller step. Then there are other techniques such as triangulation if I get really stuck.

If like me you are a developer and not a tester then the point of using TDD is not to write tests but to write code. Don't get hung up on writing loads of small tests if they aren’t given you any benefits.

I hope you enjoyed your training an stick with TDD. IMHO if more people were test infected then the world would be a better place :)


1

In a primer about unit testing i read the same approach (steps that look really, really tiny), and as an answer to the question "how tiny should they be" something i liked, which was (paraphrased) like this:

It's about how confident you are that the steps work. You can make real big steps if you want. But, just try it for some time and you will find a lot misguided confidence in places you take it for granted. So, the tests help you to build a fact-based confidence.

So, maybe your collegue is just a little shy :)


1

Isn't the whole point that the implementation of the method is irrelevant, as long as the tests succeed? Extending the tests will fail quicker in the second example, but can be made to fail in both cases.


1
It is irrelevant if you totally don't care about wasting your time
SiberianGuy

1

I'm agreeing with the people saying that neither is the simplest implementation.

The reason the methodology is so strict is that it obliges you to write as many relevant tests as possible. Returning a constant value for one test case and calling it a pass is fine because it forces you to go back and specify what you really want in order to get anything other than nonsense from your program. Using such a trivial case is shooting yourself in the foot in some respects, but the principle is that mistakes creep into the gaps in your specification when you try to do 'too much' and rendering down the requirement to the simplest possible implementation ensures that a test must be written for each unique aspect of behaviour that you actually want.


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