यूनिट परीक्षण C ++: क्या परीक्षण करना है?


20

टी एल; डॉ

अच्छा, उपयोगी परीक्षण लिखना कठिन है, और C ++ में इसकी उच्च लागत है। क्या आप अनुभव कर सकते हैं कि डेवलपर्स आपके औचित्य को क्या और कब परीक्षण करना चाहते हैं?

लम्बी कहानी

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

यह अक्सर यूनिट स्तर पर परीक्षण करने के लिए इतना कठिन होता है कि हमने टीडीडी (घटकों को छोड़कर जहां यह वास्तव में विकास को गति देता है) को करना बंद कर दिया, और इसके बजाय एकीकरण परीक्षण कवरेज को बढ़ाने में अधिक समय लगाया। हालांकि छोटी इकाई परीक्षणों ने कभी कोई वास्तविक बग नहीं पकड़ा और मूल रूप से केवल रखरखाव ओवरहेड थे, एकीकरण परीक्षण वास्तव में प्रयास के लायक हैं।

अब मुझे एक नई परियोजना विरासत में मिली है, और मैं सोच रहा हूं कि इसे कैसे परीक्षण किया जाए। यह एक मूल C ++ / OpenGL एप्लिकेशन है, इसलिए एकीकरण परीक्षण वास्तव में एक विकल्प नहीं हैं। लेकिन C ++ में यूनिट परीक्षण जावा की तुलना में थोड़ा कठिन है (आपको सामान बनाने के लिए विस्फोटक होना चाहिए virtual), और कार्यक्रम भारी वस्तु उन्मुख नहीं है, इसलिए मैं कुछ सामान को मॉक / स्टब नहीं कर सकता।

मैं अलग नहीं करना चाहता और OO-ize को पूरी तरह से लिखने की खातिर कुछ परीक्षण लिखने के लिए। तो मैं आपसे पूछ रहा हूं: यह क्या है जिसके लिए मुझे परीक्षण लिखना चाहिए? उदाहरण के लिए:

  • कार्य / कक्षाएं जिन्हें मैं अक्सर बदलने की उम्मीद करता हूं?
  • कार्य / कक्षाएं जो मैन्युअल रूप से परीक्षण करने के लिए अधिक कठिन हैं?
  • कार्य / कक्षाएं जो पहले से ही परीक्षण करना आसान है?

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

अपडेट करें

मैंने यह लिखने के बाद से इस साइट और वेब पर अपना रास्ता खोज लिया है। कुछ अच्छा सामान मिला:

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

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

इसलिए इस प्रश्न का उत्तर देते समय, कृपया ध्यान रखें कि मुझे परीक्षण लिखने के लिए एक बड़ा निवेश करना होगा।


3
इकाई परीक्षण C ++ में कठिनाई के लिए +1। यदि आपके यूनिट टेस्ट के लिए आपको कोड बदलने की आवश्यकता है, तो न करें।
DPD

2
@DPD: मुझे यकीन नहीं है, क्या होगा अगर कुछ वास्तव में परीक्षण के लायक है? वर्तमान कोड बेस में, मैं शायद ही सिमुलेशन कोड में कुछ भी परीक्षण कर सकता हूं क्योंकि यह सभी ग्राफिक्स फ़ंक्शन को सीधे कॉल करता है, और मैं उन्हें मॉक / मब नहीं कर सकता। अभी मैं सभी परीक्षण कर सकता हूं उपयोगिता कार्य हैं। लेकिन मैं सहमत हूं, इसे "परीक्षण करने योग्य" महसूस करने के लिए कोड को बदलना ... गलत है। टीडीडी प्रस्तावक अक्सर कहते हैं कि इससे आपके सभी कोड सभी कल्पनीय तरीकों से बेहतर होंगे, लेकिन मैं विनम्रतापूर्वक असहमत हूं। सब कुछ एक इंटरफ़ेस और कई कार्यान्वयन की आवश्यकता नहीं है।
फुललिब

मैं आपको एक ताजा उदाहरण देता हूं: मैंने पूरे एक दिन एक सिंगे फंक्शन (C ++ / CLI में लिखा) और टेस्ट टूल MS Test को टेस्ट करने की कोशिश में बिताया। ऐसा लगता था कि सादे सीपीपी संदर्भों के साथ कुछ समस्या थी। इसके बजाय मैंने सिर्फ इसके कॉलिंग फ़ंक्शन के ouptput का परीक्षण किया और यह ठीक काम किया। मैंने पूरा दिन यूटी वन फंक्शन में बर्बाद किया। वह कीमती समय का नुकसान था। इसके अलावा मैं अपनी जरूरतों के लिए उपयुक्त कोई स्टबिंग टूल नहीं प्राप्त कर सका। जहाँ भी संभव हो मैंने मैनुअल स्टबिंग किया।
DPD

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

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

जवाबों:


5

खैर, यूनिट परीक्षण केवल एक हिस्सा है। एकीकरण परीक्षण आपको अपनी टीम की समस्या से निपटने में मदद करते हैं। एकीकरण टेस्ट सभी प्रकार के अनुप्रयोगों के लिए लिखे जा सकते हैं, देशी और ओपनजीएल अनुप्रयोगों के लिए भी। आपको स्टीव फ्रीमैन और नेट प्रिस (उदाहरण के लिए http://www.amazon.com/Growing-Object-Oriented-Ogent-Software-Guided-Signature/dign/0321503627 ) द्वारा "टेस्ट द्वारा विकसित ऑब्जेक्ट ओरिएंटेड सॉफ्टवेयर गाइडेड टेस्ट" देखना चाहिए । यह आपको जीयूआई और नेटवर्क संचार के साथ एक एप्लिकेशन के विकास के माध्यम से कदम दर कदम आगे बढ़ाता है।

परीक्षण सॉफ्टवेयर है कि परीक्षण संचालित नहीं था एक और कहानी है। माइकल फेदर्स की जाँच करें "लिगेसी कोड के साथ प्रभावी ढंग से काम करना" (http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052)।


मुझे दोनों किताबें पता हैं। ये चीजें हैं: 1. हम TDD के साथ नहीं जाना चाहते हैं, क्योंकि यह हमारे साथ अच्छा काम नहीं करता है। हम परीक्षण चाहते हैं, लेकिन धार्मिक रूप से नहीं। 2. मुझे यकीन है कि ओपनजीएल अनुप्रयोगों के लिए एकीकरण परीक्षण किसी भी तरह से संभव हैं, लेकिन यह बहुत अधिक प्रयास करता है। मैं ऐप को बेहतर बनाना चाहता हूं, न कि रिसर्च प्रोजेक्ट शुरू करना चाहता हूं।
फुललिब

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

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

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

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

2

यह शर्म की बात है TDD "आप के लिए अच्छी तरह से काम नहीं किया।" मुझे लगता है कि यह समझने की कुंजी है कि कहां मोड़ना है। फिर से पढ़ें और समझें कि टीडीडी कैसे काम नहीं करता है, आप क्या बेहतर कर सकते हैं, क्यों कठिनाई थी।

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

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

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


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

1
जितना मैं इसके बारे में सोचता हूं, उतना ही मुझे लगता है कि TDD सिर्फ उस विशेष परियोजना की तकनीक को बहुत अच्छी तरह से फिट नहीं करता है: फ्लेक्स / स्विज़। बहुत सी घटनाएं और बाइंडिंग और इंजेक्शन चल रहे हैं जो ऑब्जेक्ट के बीच परस्पर क्रियाओं को जटिल बनाते हैं और यूनिट टेस्ट को लगभग असंभव बना देते हैं। उन वस्तुओं को हटाने से यह बेहतर नहीं होता है, क्योंकि वे पहली जगह में सही काम करते हैं।
फ्यूटलिब

2

मैंने C ++ में TDD नहीं किया है इसलिए मैं उस पर टिप्पणी नहीं कर सकता, लेकिन आपको अपने कोड के अपेक्षित व्यवहार का परीक्षण करना चाहिए। हालांकि कार्यान्वयन बदल सकता है, व्यवहार (आमतौर पर?) ही रहना चाहिए। जावा \ सी # केंद्रित दुनिया में, इसका मतलब होगा कि आप केवल सार्वजनिक तरीकों का परीक्षण करेंगे, अपेक्षित व्यवहार के लिए परीक्षण लिख रहे हैं और कार्यान्वयन से पहले कर रहे हैं (जो आमतौर पर बेहतर किया गया है :))।

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