2008-11-01 8 views
25

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

मुझे लगता है कि शुरुआती चरणों में रिफैक्टरिंग आर्किटेक्चर बहुत आम है जहां डिजाइन अभी भी काम कर रहा है। इंटरफेस बदलते हैं, नई कक्षाएं & हटा दी जाती हैं, यहां तक ​​कि किसी फ़ंक्शन का व्यवहार थोड़ा बदल सकता है (मैंने सोचा कि मुझे ऐसा करने की ज़रूरत है, लेकिन इसे वास्तव में ऐसा करने की ज़रूरत है), आदि ... लेकिन यदि प्रत्येक टेस्ट केस कसकर युग्मित होता है इन अस्थिर वर्गों के लिए, जब भी आप कोई डिज़ाइन बदलते हैं, तो आपको लगातार अपने परीक्षण मामलों को फिर से लिखना नहीं होगा?

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

आखिरकार, टीडीडी और/या इस तरह के मुद्दों को हल करने के लिए रिफैक्टरिंग पर एक अच्छी किताब होगी? यदि हां, तो आप किसकी सिफारिश करेंगे?

+0

मैं एक ही चीज़ के बारे में सोच रहा हूं। एक तरह से, परीक्षणों को DRY का उल्लंघन करने के लिए कहा जा सकता है, क्योंकि कोड के एक टुकड़े का व्यवहार उस कोड में और उस कोड में दोनों परिलक्षित होता है जो परीक्षण करता है। – Boris

उत्तर

8

प्लस ऐसा लगता है कि करने के लगातार बदलते कोड के साथ एक व्यापक टेस्ट स्वीट सिंक्रनाइज़ एक दर्द होगा। मैं समझता हूँ कि इकाई टेस्ट स्वीट रखरखाव के दौरान काफी मदद कर सकता है, एक बार सॉफ्टवेयर बनाया गया है, स्थिर, और कामकाज, लेकिन खेल में देर हो चुकी है कि wheras TDD रूप में अच्छी तरह पर जल्दी मदद करने के लिए माना जाता है।

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

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

अद्यतन (टिप्पणी के आधार पर):

@Cybis मेरी दावा है कि रिफैक्टरिंग परीक्षण नहीं तोड़ चाहिए, क्योंकि रिफैक्टरिंग व्यवहार परिवर्तन नहीं होना चाहिए के लिए एक दिलचस्प आपत्ति उठाया गया है। उनकी आपत्ति यह है कि रीफैक्टरिंग एपीआई बदलती है, और इसलिए "ब्रेक" का परीक्षण करती है।

सबसे पहले, मैं किसी को भी रिफैक्टरिंग पर कैननिकल संदर्भ देखने के लिए प्रोत्साहित करता हूं: Martin Fowler's bliki

  • Is changing an interface refactoring? मार्टिन एक "व्यवहार के संरक्षण" परिवर्तन के रूप में पुनर्रचना के लिए संदर्भित करता है, जो का मतलब है जब इंटरफ़ेस/एपीआई तो सभी को कॉल करने में परिवर्तन: बस अब मैं इसे और नीचे दिए कुछ मुझ पर बाहर कूद की समीक्षा की कि इंटरफ़ेस/एपीआई भी बदलना चाहिए। परीक्षण सहित, मैं कहता हूं।
  • इसका मतलब यह नहीं है कि व्यवहार बदल गया है। दोबारा, फाउलर ने जोर दिया कि रिफैक्टरिंग की परिभाषा यह है कि परिवर्तन व्यवहार को संरक्षित करते हैं।

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

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

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

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

+1

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

+1

मैं टिप्पणियां क्यों संपादित नहीं कर सकता? ARG। मेरा मतलब यह था कि यदि आप इंटरफेस को दोबारा इस्तेमाल करते हैं तो परीक्षण तोड़ते हैं जैसे कि आपको एक ही व्यवहार तक पहुंचने के लिए विभिन्न कार्यों को कॉल करने की आवश्यकता होती है (इस प्रकार का रिफैक्टरिंग पठनीयता में सुधार कर सकती है और इससे बचा नहीं जाना चाहिए)। – Cybis

+0

टिप्पणियों के लिए धन्यवाद @ Cybis, मैंने उनके जवाब में जवाब दिया है। –

4

टीडीडी कहते हैं कि परीक्षण पहले विफल रहा है। परीक्षण यह दिखाने के लिए लिखा गया है कि डेवलपर समझता है कि उपयोग केस/कहानी/परिदृश्य/प्रक्रिया को क्या हासिल करना है।

फिर आप परीक्षण को पूरा करने के लिए कोड लिखते हैं।

यदि आवश्यकता में परिवर्तन या गलत समझा गया है, पहले परीक्षण को संपादित या फिर से लिखना।

रेड-बार, ग्रीन-बार, है ना?

फाउलर की पुनर्रचनापुनर्रचना के लिए संदर्भ, अजीब पर्याप्त है।

में स्कॉट अंबालर की लेखों की श्रृंखला डॉ डॉबब के ('द एजिल एज ??') अभ्यास में टीडीडी की एक बड़ी पैदल यात्रा है।

6

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

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

+1

हालांकि तर्क यह है कि आंशिक टीडीडी टीडीडी नहीं है। बिना किसी परीक्षण के सीधे कोड लिखना पहले पूरे टीडीडी मंत्र को तोड़ देता है। यदि सभी कोड टेस्ट-प्रथम लिखा गया है तो यह अधिक संभव नहीं है? – Cybis

1

केंट बेक की टीडीडी पुस्तक।

पहले परीक्षण करें। S.O.L.I.D ओओपी सिद्धांतों के बाद और एक अच्छा रिफैक्टरिंग टूल का उपयोग करना अनिवार्य है, यदि आवश्यक नहीं है।

+0

एसओएलआईआईडी क्या है? कृपया समझाएँ। – Tilendor

+0

सोल्ड रॉबर्ट मार्टिन्स 'एग्इल सॉफ्टवेयर डेवलपमेंट, प्रिंसिपल, पैटर्न और प्रैक्टिस' से डिजाइन सिद्धांत हैं: एकल उत्तरदायित्व सिद्धांत, ओपन क्लोज़ड सिद्धांत, लिस्कोव प्रतिस्थापन सिद्धांत, इंटरफेस पृथक्करण सिद्धांत और निर्भरता उलटा सिद्धांत। – quamrana

1

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

परीक्षण और चश्मे का बिंदु सिस्टम के सही व्यवहार को परिभाषित करना है। तो, बहुत बस:

if definition of correctness changes 
    change tests/specs 
end 

if definition of correctness does not change 
    # no need to change tests/specs 
    # though you still can for other reasons if you want/need 
end 

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

3

उदाहरण के लिए एक अधिक कुशलता वाला एक एल्गोरिदम बदल रहा है।

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

टीडीडी के मूल्य का हिस्सा यह है कि आपके परीक्षण आपको उस परिणाम को बदलने के तरीके को बदलने के दौरान दृश्य व्यवहार निरंतर रखने में आपकी सहायता करते हैं।

+0

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

10

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

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

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

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

मैंने इसे अभी तक नहीं पढ़ा है, लेकिन मैंने "XUnit टेस्ट पैटर्न - रिफैक्टरिंग टेस्ट कोड" पुस्तक के बारे में अच्छी बातें सुनी हैं।

+0

उन मामलों में आप क्या करते हैं जहां एक एकल एल्गोरिदम में कई सीमाएं होती हैं? एक गैर-तुच्छ बीएनएफ व्याकरण के साथ पाठ को पार करना एक अच्छा उदाहरण है। आपके पास एक अर्ध-अर्द्ध तैयार है, लेकिन फिर व्याकरण को थोड़ा बदलने की जरूरत है। क्योंकि आपका वाक्यविन्यास पेड़ बदलता है, आपका सभी टेस्ट ब्रेक। डॉन 300 चार लीम – Cybis

+0

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

+0

जब आप किसी डिज़ाइन रणनीति के बारे में बात करते हैं, तो आप ** लिखने के बारे में कैसे सोचते हैं ** आपके कोड जैसे कि इसका परीक्षण किया जा सकता है - लेकिन शुरुआत से परीक्षणों को जरूरी नहीं लिखना चाहिए? –

संबंधित मुद्दे