अनुबंध आधारित प्रोग्रामिंग बनाम यूनिट टेस्ट


13

मैं कुछ हद तक रक्षात्मक प्रोग्रामर हूं और माइक्रोसाफ्ट कोड कॉन्ट्रैक्ट्स का बहुत बड़ा प्रशंसक हूं।

अब मैं हमेशा C # का उपयोग नहीं कर सकता और अधिकांश भाषाओं में मेरे पास केवल एक ही उपकरण है। इसलिए मैं आमतौर पर इस तरह कोड के साथ समाप्त होता है:

class
{       
    function()
    {   
         checkInvariants();
         assert(/* requirement */);

         try
         {
             /* implementation */
         }
         catch(...)
         {
              assert(/* exceptional ensures */);                  
         }
         finally
         {
              assert(/* ensures */);
              checkInvariants();
         }
    }

    void checkInvariants()
    {
         assert(/* invariant */);
    }
}

हालाँकि, यह प्रतिमान (या जिसे आप इसे कहते हैं) बहुत कोड अव्यवस्था की ओर ले जाता है।

मुझे आश्चर्य है कि क्या यह वास्तव में प्रयास के लायक है और क्या उचित इकाई परीक्षण पहले से ही इसे कवर करेगा?


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

तो यह मूल रूप से विकास समय, रखरखाव, पठनीयता बनाम बेहतर कोड कवरेज है?
रोनग

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

जवाबों:


14

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


2
मुझे लगता है कि यह परीक्षण करना भी महत्वपूर्ण है कि क्या शर्तें पूरी नहीं होने पर कोड काम करता है (जैसे यह एक अपवाद फेंकता है) ।
svick

6

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

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

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


1

जैसा कि पहले ही उल्लेख किया गया है कि अनुबंध और यूनिट परीक्षणों का अलग-अलग उद्देश्य है।

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

यूनिट परीक्षण यह सुनिश्चित करने के लिए करता है कि कोड भिन्न परिदृश्यों में काम करता है। ये 'दांतों से चश्मा ’की तरह हैं।

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


0

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

मैं @duros से सहमत हूं, इन्हें विशेष या प्रतिस्पर्धी दृष्टिकोण के रूप में नहीं सोचा जाना चाहिए। वास्तव में एक TDD वातावरण में आप यह भी तर्क दे सकते हैं कि 'आवश्यकता' अभिकथन के लिए परीक्षण की आवश्यकता होगी :)।

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

एक परीक्षण संचालित / अच्छी तरह से परीक्षण किए गए समाधान ने आमतौर पर पहले ही सोचा होगा और / या खराब स्रोतों और आउटपुट के कई स्रोतों / कारणों की खोज की है, जबकि बातचीत के घटकों को विकसित करते हुए और पहले से ही समस्या के स्रोत के करीब पहुंच गए हैं।

यदि आपका स्रोत बाहरी है और आपके पास इस पर कोई नियंत्रण नहीं है, तो अन्य कोड समस्याओं से निपटने के लिए अपने कोड को अव्यवस्थित करने से बचने के लिए आप स्रोत और आपके घटक के बीच किसी प्रकार के डेटा-क्लींजिंग / अभिकथन घटक को लागू करने पर विचार कर सकते हैं और अपने चेक वहां डाल सकते हैं। ।

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


0

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

यह हमेशा आसान या संभव नहीं है, लेकिन निश्चित रूप से अपने आप से सवाल पूछने के लायक है, "क्या मैं इस कोड को अधिक मूर्ख बना सकता हूं?"

C # के निर्माता एंडर्स हेजेल्सबर्ग ने कहा कि C # में सबसे बड़ी गलतियों में से एक गैर-शून्य संदर्भ प्रकार शामिल नहीं थी। यह मुख्य कारणों में से एक है इसलिए बहुत आवश्यक गार्ड कोड अव्यवस्था मौजूद है।

फिर भी, केवल अनुभव के लिए आवश्यक और पर्याप्त मात्रा में गार्ड कोड बनाना, मेरे अनुभव से अधिक उपयोगी और रखरखाव योग्य कोड है।

इसके बाकी हिस्सों पर @duros से सहमत हैं।


0

दोनों करें, लेकिन अपने इरादों को स्पष्ट करने के लिए कुछ स्थिर सहायक तरीके बनाएं। यह वही है जो Google ने जावा के लिए किया था, कोड देखें।

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