क्या हमें इकाई परीक्षण को सक्षम करने के लिए शुरू से ही अपना कोड डिजाइन करना चाहिए?


91

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

विशेष रूप से, हमारे पास एक वेब एपीआई सेवा होगी जो बहुत पतली होगी। इसकी मुख्य जिम्मेदारी वेब अनुरोधों / प्रतिक्रियाओं को मार्शमैलो करना और एक अंतर्निहित एपीआई को कॉल करना होगा जिसमें व्यावसायिक तर्क शामिल हैं।

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

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

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

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


33
मैं इसे दोहराता हूं: आप सहकर्मी नए कोड के लिए यूनिट टेस्ट चाहते हैं, लेकिन वे कोड को एक तरह से लिखने से इनकार करते हैं, यह यूनिट टेस्ट करने योग्य है, हालांकि मौजूदा कुछ भी तोड़ने में कोई जोखिम नहीं है? यदि यह सच है, तो आपको @ KilianFoth के उत्तर को स्वीकार करना चाहिए और उसे अपने उत्तर में पहला वाक्य बोल्ड करने के लिए कहना चाहिए! आपके सहयोगियों को स्पष्ट रूप से एक बहुत बड़ी गलतफहमी है कि उनकी नौकरी क्या है।
डॉक्टर ब्राउन

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

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

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

4
माइकल फेदर्स की पुस्तक की सिफारिश के लिए धन्यवाद, मैं निश्चित रूप से एक प्रति उठाऊंगा।
ली

जवाबों:


204

परीक्षण की खातिर कोड को संशोधित करने की अनिच्छा से पता चलता है कि एक डेवलपर ने परीक्षणों की भूमिका को नहीं समझा है, और निहितार्थ से संगठन में उनकी अपनी भूमिका है।

सॉफ्टवेयर व्यवसाय एक कोड आधार देने के लिए घूमता है जो व्यावसायिक मूल्य बनाता है। हमने लंबे और कड़वे अनुभव के माध्यम से पाया है कि हम परीक्षण के बिना nontrivial आकार के ऐसे कोड आधार नहीं बना सकते हैं। इसलिए, परीक्षण सूट व्यवसाय का एक अभिन्न हिस्सा हैं।

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

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

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


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

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

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

21
@ChristianHackl एक इकाई परीक्षण क्यों टूटना होगा? मैंने पाया है कि मैंने जिस कोड पर काम किया है, अगर परीक्षण को सक्षम करने के लिए अतिरिक्त कार्यक्षमता जोड़ने की आवश्यकता है , तो वास्तविक समस्या यह है कि जिस फ़ंक्शन को आप परीक्षण करना चाहते हैं, वह है रिफैक्टरिंग, इसलिए सभी कार्यक्षमता उसी पर है अमूर्त का स्तर (यह अमूर्त स्तर में अंतर है जो आमतौर पर अतिरिक्त कोड के लिए इस "आवश्यकता" का निर्माण करता है), निचले स्तर के कोड के साथ अपने स्वयं के (परीक्षण योग्य) कार्यों में चले गए।
बाल्ड्रिक

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

75

यह उतना आसान नहीं है जितना आप सोच सकते हैं। चलो इसे तोड़ दो।

  • इकाई परीक्षण लिखना निश्चित रूप से एक अच्छी बात है।

परंतु!

  • आपके कोड में कोई भी बदलाव बग का परिचय दे सकता है। तो एक अच्छा व्यावसायिक कारण के बिना कोड को बदलना अच्छा विचार नहीं है।

  • आपका 'बहुत पतला' वेबपी यूनिट परीक्षण के लिए सबसे बड़ा मामला नहीं लगता है।

  • एक ही समय में कोड और परीक्षण बदलना एक बुरी बात है।

मैं निम्नलिखित दृष्टिकोण का सुझाव दूंगा:

  1. एकीकरण परीक्षण लिखें । इसके लिए किसी कोड परिवर्तन की आवश्यकता नहीं होनी चाहिए। यह आपको आपके मूल परीक्षण के मामले देगा और आपको यह जांचने में सक्षम करेगा कि आपके द्वारा किए गए किसी भी कोड में कोई भी बग न आए।

  2. सुनिश्चित करें कि नया कोड परीक्षण योग्य है और इसमें यूनिट और एकीकरण परीक्षण हैं।

  3. सुनिश्चित करें कि आपकी सीआई श्रृंखला बिल्ड और तैनाती के बाद परीक्षण चलाती है।

जब आपके पास उन चीजों को स्थापित किया जाता है, तभी परीक्षण के लिए विरासत परियोजनाओं को फिर से शुरू करने के बारे में सोचना शुरू करें।

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

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

यह कल्पना करना कठिन है कि यूनिट परीक्षणों से क्या कोड परिवर्तन की आवश्यकता होगी, लेकिन सामान्य अच्छा अभ्यास नहीं होगा जो आप किसी भी मामले में चाहते हैं। संभवतः वास्तविक आपत्तियों की जांच करना समझदारी होगी, संभवतः यह इकाई परीक्षण की शैली है जिस पर आपत्ति की जा रही है।


12
यह एक है बहुत स्वीकार किए जाते हैं एक से बेहतर जवाब। वोटों में असंतुलन निराशाजनक है।
कोनराड रुडोल्फ

4
@Lee एक इकाई परीक्षण एक परीक्षण करना चाहिए कार्यक्षमता की इकाई है, जो या एक वर्ग के अनुरूप नहीं हो सकता है। कार्यक्षमता की एक इकाई को इसके इंटरफ़ेस पर परीक्षण किया जाना चाहिए (जो इस मामले में एपीआई हो सकता है)। परीक्षण से डिजाइन की महक और कुछ अलग / अधिक स्तर लागू करने की आवश्यकता पर प्रकाश डाला जा सकता है। छोटे संयोजक टुकड़ों से अपने सिस्टम का निर्माण करें, वे कारण और परीक्षण करने में आसान होंगे।
वेस टोलेमैन

2
@KonradRudolph: मुझे लगता है कि वह बिंदु चूक गया जहां ओपी ने कहा कि यह प्रश्न नए कोड को डिजाइन करने के बारे में था, मौजूदा परिवर्तन नहीं। इसलिए तोड़ने के लिए कुछ भी नहीं है, जो इस उत्तर के अधिकांश को लागू नहीं करता है।
डॉक्टर ब्राउन

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

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

18

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

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

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


उस समस्या को स्थैतिक कोड विश्लेषण के माध्यम से हल किया जा सकता है - विधियों को चिह्नित करें (जैसे नाम होना चाहिए _ForTest) और गैर-परीक्षण कोड से कॉल के लिए कोडबेस की जांच करें।
रैली

13

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

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

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

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


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

2
@ ली: एक संगठन में परिवर्तन लाने से हमेशा कुछ प्रतिरोध होता है, और नई चीज़ों को अनुकूलित करने के लिए हमेशा कुछ समय की आवश्यकता होती है, यह नई ज्ञान नहीं है। यह लोगों की समस्या है।
डॉक्टर ब्राउन

पूर्ण रूप से। मैं बस चाहता हूं कि हमें और समय दिया जाए!
ली

अक्सर लोगों को यह दिखाने की बात होती है कि ऐसा करने से उनका समय बचेगा (और उम्मीद है कि जल्दी भी)। ऐसा कुछ क्यों करें जिससे आपको फायदा न हो?
Thorbjørn Ravn Andersen

@ ThorbjørnRavnAndersen: टीम ओपी को इसी तरह दिखा सकती है कि उनका दृष्टिकोण समय बचाएगा। कौन जाने? लेकिन मुझे आश्चर्य है कि अगर हम वास्तव में कम तकनीकी प्रकृति की समस्याओं का सामना नहीं कर रहे हैं; ओपी यह बताने के लिए यहां आता रहता है कि उसकी टीम क्या गलत करती है (उसकी राय में), जैसे कि वह अपने कारण के लिए सहयोगी खोजने की कोशिश कर रहा था। यह अधिक फायदेमंद वास्तव में परियोजना पर चर्चा करने हो सकता है एक साथ , टीम के साथ स्टैक एक्सचेंज पर अजनबियों के साथ नहीं।
क्रिश्चियन हैकल

11

मैं आपके (आपके द्वारा किए गए) दावे के साथ मुद्दा लेता हूं:

वेब एपीआई सेवा का परीक्षण करने के लिए हमें इस कारखाने का मजाक उड़ाना होगा

यह जरूरी नहीं कि सच हो। परीक्षण लिखने के लिए बहुत सारे तरीके हैं, और यूनिट परीक्षण लिखने के तरीके हैं जो नकली शामिल नहीं हैं। इससे भी महत्वपूर्ण बात, अन्य प्रकार के परीक्षण हैं, जैसे कि कार्यात्मक या एकीकरण परीक्षण। कई बार एक "इंटरफ़ेस" पर "टेस्ट सीम" ढूंढना संभव है जो ओओपी प्रोग्रामिंग भाषा नहीं है interface

वैकल्पिक परीक्षा सीम खोजने में आपकी सहायता के लिए कुछ प्रश्न, जो अधिक स्वाभाविक हो सकते हैं:

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

आपके बारे में एक और बेबाक बयान डीआई के बारे में है:

हम या तो DI (इसके निर्माता या सेटर के माध्यम से) को स्वीकार करने के लिए Web API कंट्रोलर डिज़ाइन डिज़ाइन करते हैं, जिसका अर्थ है कि हम कंट्रोलर का हिस्सा डिज़ाइन कर रहे हैं ताकि हम DI को अनुमति दे सकें और एक इंटरफ़ेस लागू कर सकें जिसकी हमें ज़रूरत नहीं है, या हम किसी तीसरे पक्ष का उपयोग करते हैं इस तरह से नियंत्रक को डिजाइन करने से बचने के लिए निन्जेक्ट जैसे ढांचे, लेकिन हमें अभी भी एक इंटरफ़ेस बनाना होगा।

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

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


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

9

आप भाग्य में हैं क्योंकि यह एक नई परियोजना है। मैंने पाया है कि अच्छे कोड लिखने के लिए टेस्ट ड्रिवेन डिज़ाइन बहुत अच्छा काम करता है (यही वजह है कि हम इसे पहले स्थान पर करते हैं)।

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

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

गौर किजिए। विशेष रूप से सहकर्मी की समीक्षा के साथ। मेरे अनुभव में समय और प्रयास का निवेश बहुत जल्दी वापस आ जाएगा।


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

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

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

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

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

8

यदि आपको कोड को संशोधित करने की आवश्यकता है, तो वह कोड गंध है।

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

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

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

मैं इसे पूरी तरह से एक परियोजना का पुनर्निर्माण करते हुए टाइप कर रहा हूं जो क्लीनर कोड में एक थकाऊ प्रोटोटाइप होना चाहिए था। यह बेहतर है कि इसे जल्द से जल्द शुरू करें और रिफ्लेक्टर खराब कोड से जल्द से जल्द दूर करें क्योंकि स्क्रीन पर घंटों तक घूरने के बजाय किसी चीज को तोड़ने के डर से कुछ भी छूने से डरते हैं जो आंशिक रूप से काम करता है।


3
"थ्रोवेअव प्रोटोटाइप" - हर एक परियोजना कभी भी उन में से एक के रूप में जीवन शुरू करती है ... चीजों के बारे में सोचने के लिए सबसे अच्छा है कि कभी नहीं। इसे टाइप करते हुए मैं .. अनुमान लगाता हूँ क्या? ... एक थकाऊ प्रोटोटाइप को फिर से तैयार करना जो निकला नहीं;)
एली टेलर

4
यदि आप यह सुनिश्चित करना चाहते हैं कि एक फेंक प्रोटोटाइप को फेंक दिया जाएगा, तो इसे एक प्रोटोटाइप भाषा में लिखें जिसे उत्पादन में कभी भी अनुमति नहीं दी जाएगी। क्लोजर और पायथन अच्छे विकल्प हैं।
Thorbjørn रावन एंडरसन

2
@ ThorbjørnRavnAndersen जिसने मुझे चकित कर दिया। क्या इसका मतलब उन भाषाओं में खुदाई करना था? :)
ली

@Lee। नहीं, केवल उन भाषाओं के उदाहरण जो उत्पादन के लिए स्वीकार्य नहीं हो सकते हैं - आम तौर पर क्योंकि संगठन में कोई भी उन्हें बनाए नहीं रख सकता है क्योंकि वे उनके साथ अपरिचित हैं और उनके सीखने की अवस्था खड़ी है। यदि वे हैं, स्वीकार्य हैं एक और चुनें कि नहीं है।
Thorbjørn रावन एंडरसन

4

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

तुम कहो

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

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

इसके लिए आपको DI या Mocks की जरूरत नहीं है। आपको बस विभिन्न प्रमाणीकरण प्रकारों का समर्थन करने के लिए अपने कारखाने की आवश्यकता है और इसके लिए किसी भी तरह विन्यास योग्य होना चाहिए, जैसे कॉन्फ़िगरेशन फ़ाइल या पर्यावरण चर से।


2

प्रत्येक इंजीनियरिंग अनुशासन में, मैं सभ्य या उच्च स्तर की गुणवत्ता हासिल करने का एक ही तरीका है:

डिजाइन में निरीक्षण / परीक्षण के लिए खाता।

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

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


1

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

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

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


3
आप परीक्षण करने में सक्षम होने के लिए कई अप्रत्यक्ष परतों को पेश करने के लिए लुभाए जा सकते हैं, और फिर उन्हें उम्मीद के मुताबिक कभी भी उपयोग न करें।
Thorbjørn Ravn Andersen

1

संक्षेप में:

या बल्कि, कोड है कि है - परीक्षण योग्य कोड (आमतौर पर) maintainable कोड है कठिन परीक्षण करने के लिए आमतौर पर है कठिन बनाए रखने के लिए। डिजाइनिंग कोड जो परीक्षण करने योग्य नहीं है, एक ऐसी मशीन को डिजाइन करने के लिए एक समान है जो मरम्मत योग्य नहीं है - गरीब शमुक को दया आती है जिसे अंततः इसे ठीक करने के लिए सौंपा जाएगा (यह आप हो सकते हैं)।

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

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


1

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


1
"किया सही" एक समस्या है। मुझे दो परियोजनाओं को बनाए रखना होगा जहां डीआई को गलत किया गया था (हालांकि इसे "सही" करने का लक्ष्य था)। यह कोड सादे को डीआई और यूनिट परीक्षण के बिना विरासत परियोजनाओं की तुलना में भयानक और बहुत खराब बनाता है। DI सही होना आसान नहीं है।
Jan

@ जान दिलचस्प है। उन्होंने यह कैसे गलत किया?
ली

1
@Lee एक परियोजना एक ऐसी सेवा है जिसे एक तेज़ शुरुआत के समय की आवश्यकता होती है, लेकिन शुरुआत में बहुत धीमी गति से होती है क्योंकि सभी वर्ग आरंभीकरण DI फ्रेमवर्क (C # में कैसल विंडसर) द्वारा किया जाता है। एक और समस्या जो मुझे इन परियोजनाओं में दिखाई दे रही है, वह है डीआई को मिलाकर, "नई" के साथ वस्तुओं के निर्माण में। इससे परीक्षण फिर से कठिन हो जाता है और कुछ बुरा दौड़ की स्थिति पैदा हो जाती है।
9

1

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

आइए एक परीक्षण योग्य के बीच अंतर को देखें:

public class MyController : Controller
{
    private readonly IMyDependency _thing;

    public MyController(IMyDependency thing)
    {
        _thing = thing;
    }
}

और गैर-परीक्षण योग्य नियंत्रक:

public class MyController : Controller
{
}

पूर्व विकल्प में शाब्दिक रूप से कोड की 5 अतिरिक्त लाइनें हैं, जिनमें से दो को विजुअल स्टूडियो द्वारा ऑटोजेनर किया जा सकता है। एक बार जब आप IMyDependencyरनटाइम के लिए एक ठोस प्रकार को बदलने के लिए अपनी निर्भरता इंजेक्शन फ्रेमवर्क को सेट करते हैं - जो कि किसी भी सभ्य DI फ्रेमवर्क के लिए, कोड की एक और एकल लाइन है - सब कुछ बस काम करता है, सिवाय इसके कि आप मॉक कर सकते हैं और इस तरह अपने दिल की सामग्री के लिए अपने नियंत्रक का परीक्षण कर सकते हैं। ।

परीक्षण की अनुमति देने के लिए कोड की 6 अतिरिक्त लाइनें ... और आपके सहकर्मी तर्क दे रहे हैं कि "बहुत अधिक काम है"? वह तर्क मेरे साथ नहीं उड़ता, और यह आपके साथ नहीं उड़ना चाहिए।

और आपको परीक्षण के लिए एक इंटरफ़ेस बनाने और कार्यान्वित करने की आवश्यकता नहीं है: Moq , उदाहरण के लिए, आपको यूनिट-परीक्षण उद्देश्यों के लिए एक ठोस प्रकार के व्यवहार का अनुकरण करने की अनुमति देता है। यदि आप उन कक्षाओं में उन प्रकारों को इंजेक्ट नहीं कर सकते हैं जो आप परीक्षण कर रहे हैं।

निर्भरता इंजेक्शन उन चीजों में से एक है जो एक बार जब आप इसे समझते हैं, तो आप आश्चर्य करते हैं कि "मैंने इसके बिना कैसे काम किया?"। यह सरल है, यह प्रभावी है, और यह सिर्फ Sense बनाता है। कृपया, अपने सहयोगियों को अपनी परियोजना को परीक्षण योग्य बनाने के तरीके में नई चीजों की समझ की कमी न होने दें।


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

नियंत्रकों के पास हमेशा एक सार्वजनिक निर्माता होता है, निहित या नहीं, क्योंकि एमवीसी को इसकी आवश्यकता होती है। "जटिल" - शायद, अगर आपको समझ में नहीं आता है कि कैसे निर्माता काम करते हैं। एनकैप्सुलेशन - हाँ कुछ मामलों में, लेकिन DI बनाम एनकैप्सुलेशन डिबेट एक निरंतर, अत्यधिक व्यक्तिपरक है जो यहां मदद नहीं करेगा, और विशेष रूप से अधिकांश अनुप्रयोगों के लिए, डीआई आपको एनकैप्सुलेशन आईएमओ से बेहतर सेवा देने वाला है।
इयान केम्प

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

0

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

शुद्ध कार्यों का उपयोग करने के लिए एक प्रवृत्ति है जितना आप कर सकते हैं (सर्वर रहित ऐप्स)। यूनिट परीक्षण से मुझे राज्य को अलग करने और शुद्ध कार्यों को लिखने में मदद मिलती है।

विशेष रूप से, हमारे पास एक वेब एपीआई सेवा होगी जो बहुत पतली होगी। इसकी मुख्य जिम्मेदारी वेब अनुरोधों / प्रतिक्रियाओं को मार्शमैलो करना और एक अंतर्निहित एपीआई को कॉल करना होगा जिसमें व्यावसायिक तर्क शामिल हैं।

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

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


0

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

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

जाहिर तौर पर कुछ लोगों का इस बारे में एक अलग विचार है। मेरा सुझाव है कि आप इसे पहले ठीक करने का प्रयास करें।

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