कभी-कभी निजी कार्य केवल कार्यक्षमता के आंतरिक निकाले जाने वाले आंतरिक इकाई होते हैं। तो क्यों नहीं उनका परीक्षण किया जाए?


9

कभी-कभी एक मॉड्यूल या वर्ग के निजी कार्य केवल कार्यक्षमता के आंतरिक निकाले जाने वाले आंतरिक इकाई होते हैं, जो अपने स्वयं के परीक्षणों के लायक हो सकते हैं। तो क्यों नहीं उनका परीक्षण किया जाए? हम होगा यदि / जब वे निकाले रहे हैं पर बाद में उन्हें परीक्षण लिखें। तो क्यों नहीं अब परीक्षण लिखें, जब वे अभी भी उसी फ़ाइल का हिस्सा हैं?

प्रदर्शित करना:

यहां छवि विवरण दर्ज करें

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


मान लीजिए कि मेरे पास निम्नलिखित कार्यों के साथ एक मॉड्यूल है (यह एक वर्ग भी हो सकता है):

def public_func(a):
    b = _do_stuff(a)
    return _do_more_stuff(b)

_do_stuffऔर _do_more_stuffमॉड्यूल के 'निजी' कार्य हैं।

मैं इस विचार को समझता हूं कि हमें केवल सार्वजनिक इंटरफ़ेस का परीक्षण करना चाहिए, कार्यान्वयन विवरण नहीं। हालाँकि, यहाँ बात है:

_do_stuffऔर _do_more_stuffमॉड्यूल की कार्यक्षमता के बहुमत में शामिल हैं। उनमें से प्रत्येक एक अलग, 'आंतरिक' मॉड्यूल का सार्वजनिक कार्य हो सकता है। लेकिन वे अभी तक विकसित नहीं हुए हैं और अलग-अलग फ़ाइलों को निकालने के लिए पर्याप्त बड़े हैं।

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



2
"निजी विधियाँ इकाई परीक्षण के लिए लाभदायक होती हैं ..." "... निजी पद्धति से चिपकना मुझे इकाई परीक्षणों में एक उपयोगी, विश्वसनीय वृद्धि लाता है। इसके विपरीत," जांच के लिए पहुँच सीमाओं को कमजोर करना "केवल मुझे एक अस्पष्ट, समझने में मुश्किल देता है। परीक्षण कोड का टुकड़ा, जो कि किसी भी मामूली रिफैक्टरिंग से टूटने के स्थायी जोखिम पर है, स्पष्ट रूप से मुझे तकनीकी ऋण की तरह संदिग्ध लगता है "
gnat

3
"क्या मुझे निजी कार्यों का परीक्षण करना चाहिए?" कभी नहीं, कभी, कभी।
डेविड एर्नो

2
@DavidArno क्यों? आंतरिक परीक्षण का विकल्प क्या है? केवल एकीकरण परीक्षण? या अधिक चीजों को सार्वजनिक कर रहा है? (हालांकि मेरे अनुभव में मैं ज्यादातर आंतरिक विधियों पर सार्वजनिक विधियों का परीक्षण करता हूं, निजी तरीकों का नहीं)
कोडइन्चोस

1
यदि यह पर्याप्त महत्वपूर्ण है कि इसके लिए परीक्षण लिखने की आवश्यकता है, तो यह पहले से ही एक अलग मॉड्यूल में होना चाहिए। यदि यह नहीं है, तो आप सार्वजनिक API का उपयोग करके इसके व्यवहार का परीक्षण करते हैं।
विंसेंट सवार्ड

जवाबों:


14

परीक्षण की आवश्यकता सार्वजनिक होने की आवश्यकता के समान नहीं है।

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

ये परस्पर विरोधी विचार आपको हर कार्य को सार्वजनिक करने के लिए प्रेरित कर सकते हैं या जब तक कि यह सार्वजनिक नहीं होगा, तब तक किसी फ़ंक्शन को कोड आउट करने से मना कर सकते हैं।

इसका जवाब नहीं है। निजी सहायक कार्य करने के लिए तैयार रहें। सार्वजनिक इंटरफ़ेस के माध्यम से उनका परीक्षण करें जो इसका यथासंभव उपयोग करता है।

यदि सार्वजनिक इंटरफ़ेस के माध्यम से परीक्षण निजी फ़ंक्शन का पर्याप्त उपयोग नहीं करता है, तो निजी फ़ंक्शन बहुत की अनुमति देने की कोशिश कर रहा है।

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

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

बेशक अशक्त ठीक हो सकता है। यह यहाँ एक उदाहरण मात्र है। लेकिन अगर आप कुछ उम्मीद करते हैं, तो यह उपयोगी है कि उम्मीद को स्पष्ट करें।

यह आपके मन में परीक्षण का प्रकार नहीं हो सकता है, लेकिन उम्मीद है कि उपयुक्त होने पर आप निजी सहायक कार्य करने के लिए तैयार होंगे।

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

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


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

मैं कहूंगा कि मैं वही बात दूसरे लोगों से पूछ रहा हूं जिन्होंने यहां जवाब दिया :) मैं हर किसी की राय सुनना चाहूंगा।
अवीव कोहन

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

1
"यदि सार्वजनिक इंटरफ़ेस के माध्यम से परीक्षण निजी फ़ंक्शन का पर्याप्त उपयोग नहीं करता है, तो निजी फ़ंक्शन ज़्यादा अनुमति देने की कोशिश कर रहा है।"
क्रिश वेल्श

7

संक्षिप्त उत्तर: नहीं

लंबा उत्तर: हां, लेकिन आपकी कक्षा के सार्वजनिक 'एपीआई' के माध्यम से

एक वर्ग के निजी सदस्यों का पूरा विचार यह है कि वे कार्यक्षमता का प्रतिनिधित्व करते हैं जो कोड की 'इकाई' के बाहर अदृश्य होना चाहिए, हालांकि आप उस इकाई को परिभाषित करना चाहते हैं। ऑब्जेक्ट ओरिएंटेड कोड में वह इकाई अक्सर एक वर्ग होने के नाते समाप्त हो जाती है।

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


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


नमस्ते, आपके उत्तर के लिए धन्यवाद :) कृपया प्रश्न फिर से पढ़ें, मैंने स्पष्ट करने के लिए संपादन किया है।
कोहन

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

मैं कहूंगा कि मैं वही बात दूसरे लोगों से पूछ रहा हूं जिन्होंने यहां जवाब दिया :) मैं हर किसी की राय सुनना चाहूंगा।
अवीव कोहन

5

निजी कार्यों का पूरा बिंदु यह है कि वे सार्वजनिक एपीआई को बदले बिना, कार्यान्वयन में छिपे विवरण को बदल सकते हैं। अपने उदाहरण कोड के लिए:

def public_func(a):
    b = _do_stuff(a)
    return _do_more_stuff(b)

यदि आपके पास परीक्षणों की एक श्रृंखला है जो केवल उपयोग करते हैं public_func, तो यदि आप इसे फिर से लिखते हैं:

def public_func(a):
    b = _do_all_the_new_stuff(a)
    return _do_all_the_old_stuff(b)

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

यह सब एक अच्छी बात है: स्थिर सार्वजनिक एपीआई; अच्छी तरह से समझाया आंतरिक कामकाज; और मजबूत परीक्षण।

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

यह एक बुरी बात है: एक बदलते एपीआई; उजागर भीतरी कामकाज कसकर परीक्षण के लिए युग्मित; और भंगुर परीक्षण जो कार्यान्वयन में परिवर्तन होते ही बदल जाते हैं।

तो नहीं, निजी कार्यों का परीक्षण न करें। कभी।


हैलो डेविड, आपके उत्तर के लिए धन्यवाद। कृपया मेरे प्रश्न को फिर से पढ़ें, मैंने स्पष्ट करने के लिए संपादन किया है।
अवि। कोहन

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

आप वास्तव में बहस कर रहे हैं कि आपके पास निजी कार्य नहीं होने चाहिए।
रॉबर्ट हार्वे

1
@AvivCohn वे वारंट परीक्षण के लिए या तो बड़े हैं, जिस स्थिति में वे अपनी फ़ाइल प्राप्त करने के लिए पर्याप्त बड़े हैं; या वे काफी छोटे हैं कि आपको उन्हें अलग से परीक्षण करने की आवश्यकता नहीं है। तो कौन सा है?
डोभाल

3
@RobertHarvey नहीं, यह तर्क देता है "यदि आवश्यक हो तो बड़े वर्गों को शिथिल-युग्मित घटकों में तोड़ दें"। यदि वे वास्तव में सार्वजनिक नहीं हैं, तो संभवतः पैकेज-निजी दृश्यता के लिए एक अच्छा उपयोग-मामला है।
डोभाल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.