अधिकतम यूनिट टेस्ट दक्षता के लिए C ++ यूनिट टेस्ट कोड कैसे आयोजित किया जाना चाहिए?


47
  • यह सवाल यूनिट टेस्टिंग फ्रेमवर्क के बारे में नहीं है
  • यह सवाल यूनिट टेस्ट लिखने के बारे में नहीं है
  • यह सवाल यह है कि UT कोड को कहां लिखा जाए और कैसे / कब / कहां से इसे संकलित और चलाया जाए।

में परंपरागत कोड के साथ प्रभावी ढंग से काम करते हुए , माइकल पंख का दावा है कि

अच्छा यूनिट परीक्षण ... तेजी से चला

और वह

एक इकाई परीक्षण जो चलाने के लिए एक सेकंड का 1/10 वां भाग लेता है, एक धीमी इकाई परीक्षण है।

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

जाहिर है समस्या C ++ है "रन" करने के लिए है कि अपने यूनिट टेस्ट ( रों ), आप के लिए है:

  1. अपना कोड (उत्पादन या यूनिट टेस्ट संपादित करें, जिसके आधार पर आप "चक्र" में हैं)
  2. संकलन
  3. संपर्क
  4. प्रारंभ यूनिट टेस्ट निष्पादन ( रों )

संपादित करें (अजीब करीबी वोट के बाद) : विवरण में जाने से पहले, मैं यहाँ बिंदु को संक्षेप में बताने की कोशिश करूँगा:

C ++ यूनिट टेस्ट कोड को प्रभावी ढंग से कैसे व्यवस्थित किया जा सकता है, ताकि यह टेस्ट (टेस्ट) कोड को संपादित करने और टेस्ट कोड को चलाने के लिए दोनों कुशल हो?


पहली समस्या तो तय करने के लिए है , जहां कि इतने यूनिट टेस्ट कोड डाल करने के लिए:

  • संबंधित उत्पादन कोड के साथ संयोजन में इसे संपादित करना और देखना "स्वाभाविक" है।
  • आपके वर्तमान में बदल रही इकाई के लिए संकलन चक्र शुरू करना आसान / त्वरित है

दूसरा , संबंधित, समस्या तो है क्या इतना संकलित करने के लिए कि प्रतिक्रिया तात्कालिक है।

चरम विकल्प:

  • प्रत्येक Unit-Test-Test-Unit एक अलग cpp फ़ाइल में रहता है और यह cpp फ़ाइल एक एकल निष्पादन योग्य (अलग-अलग स्रोत कोड यूनिट फ़ाइल परीक्षण के साथ) के साथ संकलित + जुड़ी हुई है जो तब इस एक इकाई परीक्षण को चलाता है।
    • (+) यह एकल परीक्षण इकाई के लिए स्टार्टअप (संकलन + लिंक!) समय को कम करता है।
    • (+) परीक्षण सुपर फास्ट चलाता है, क्योंकि यह केवल एक इकाई का परीक्षण करता है।
    • (-) पूरे सुइट को निष्पादित करने के लिए प्रक्रियाओं का एक bazillion शुरू करना होगा। प्रबंधन करने के लिए एक समस्या हो सकती है।
    • (-) प्रक्रिया की ओवरहेड दिखाई देने लगेगी
  • दूसरा पक्ष होगा - अभी भी - प्रति परीक्षण एक सीपीपी फ़ाइल, लेकिन सभी परीक्षण सीपीपी फाइलें (कोड वे परीक्षण के साथ!) एक निष्पादन योग्य (प्रति मॉड्यूल / प्रति परियोजना / अपनी पसंद चुनें) में जुड़े हुए हैं।
    • (+) संकलन समय अभी भी ठीक होगा, क्योंकि केवल परिवर्तित कोड संकलन करेगा।
    • (+) पूरे सूट को बाहर निकालना आसान है, क्योंकि दौड़ने के लिए सिर्फ एक एक्सई है।
    • (-) सुइट लिंक करने के लिए उम्र लेगा, क्योंकि किसी भी ऑब्जेक्ट का प्रत्येक पुन: संयोजन एक पुनः लिंक को ट्रिगर करेगा।
    • (-) (?) सूट को चलने में अधिक समय लगेगा, हालाँकि यदि सभी यूनिट टेस्ट तेज़ हैं, तो समय ठीक होना चाहिए।

तो, असली दुनिया C ++ यूनिट टेस्ट कैसे संभाला जाता है? अगर मैं केवल उस सामान को रात / घंटे में चलाता हूं, तो दूसरा भाग वास्तव में मायने नहीं रखता है, लेकिन पहला भाग, अर्थात् उत्पादन कोड के लिए यूटी कोड को "युगल" कैसे करें, ताकि डेवलपर्स को दोनों में बनाए रखने के लिए यह "स्वाभाविक" हो। फोकस हमेशा मेरे ख्याल से मायने रखता है। (और अगर डेवलपर्स के पास UT कोड फ़ोकस में है, तो वे इसे चलाना चाहेंगे, जो हमें वापस भाग दो में लाता है।)

वास्तविक दुनिया की कहानियों और अनुभव की सराहना की!

टिप्पणियाँ:

  • यह प्रश्न जानबूझकर अनिर्दिष्ट मंच छोड़ देता है और परियोजना प्रणाली बनाता है।
  • टैग किए गए प्रश्न UT & C ++ शुरू करने के लिए एक शानदार जगह है, लेकिन दुर्भाग्य से बहुत सारे प्रश्न और विशेष रूप से उत्तर, बहुत अधिक विवरण या विशिष्ट रूपरेखाओं पर केंद्रित हैं।
  • कुछ समय पहले, मैंने यूनिट परीक्षण को बढ़ावा देने के लिए संरचना पर एक समान प्रश्न का उत्तर दिया। मुझे लगता है कि इस संरचना में "वास्तविक", तेज यूनिट टेस्ट के लिए कमी है। और मैं दूसरे प्रश्न को भी संकीर्ण पाता हूं, इसलिए यह नया प्रश्न है।

6
समय को संकलित करने के लिए अधिक से अधिक त्रुटियों को स्थानांतरित करने के सी ++ मुहावरे द्वारा एक और जटिलता पेश की जाती है - यूनिट परीक्षणों का एक अच्छा सूट अक्सर परीक्षण करने में सक्षम होने की आवश्यकता होती है कि कुछ उपयोग संकलित करने में विफल रहता है।

3
@ क्‍लोसर्स: क्‍या आप कृपया उन तर्कों को प्रदान कर सकते हैं जिनके कारण आप इस प्रश्न को बंद कर सकते हैं?
ल्यूक टॉरेल

मैं यह नहीं देखता कि इसे बंद क्यों करना पड़ा। :-(यदि आप इस मंच में नहीं हैं तो ऐसे सवालों के जवाब तलाशने के लिए कहां हैं?

2
@ जो: मुझे यह पता लगाने के लिए एक इकाई परीक्षण की आवश्यकता क्यों है कि क्या कुछ संकलित करेगा जब संकलक मुझे बताएगा कि वैसे भी?
डेविड थॉर्नले

2
@ डेविड: क्योंकि आप यह सुनिश्चित करना चाहते हैं कि यह संकलित न हो । त्वरित उदाहरण एक पाइपलाइन ऑब्जेक्ट होगा जो एक इनपुट को स्वीकार करता है और आउटपुट Pipeline<A,B>.connect(Pipeline<B,C>)का संकलन करता है जबकि Pipeline<A,B>.connect(Pipeline<C,D>)संकलन नहीं करना चाहिए: पहले चरण का आउटपुट प्रकार दूसरे चरण के इनपुट प्रकार के साथ असंगत है।
सेबस्टियनजिगर

जवाबों:


6

हमारे पास एक निष्पादन योग्य में सभी इकाई परीक्षण (एक मॉड्यूल के लिए) हैं। परीक्षणों को समूहों में रखा जाता है। मैं परीक्षण धावक की कमांड लाइन पर एक (परीक्षण / समूह) नाम निर्दिष्ट करके एक एकल परीक्षण (या कुछ परीक्षण) या परीक्षणों के एक समूह को निष्पादित कर सकता हूं। बिल्ड सिस्टम समूह "बिल्ड" चला सकता है, परीक्षण विभाग "ऑल" चला सकता है। डेवलपर कुछ परीक्षणों को "BUG1234" जैसे एक समूह में डाल सकता है, जिसमें 1234 उस मामले का मुद्दा ट्रैकर है जिस पर वह काम कर रहा है।


6

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

मुझे एक डाइरेक्टरी ट्री में यूनिट टेस्ट देना पसंद है जो मुख्य ट्री को छाया देता है। तो मेरे पास है /sources/componentA/alpha/foo.ccऔर /objects/componentA/beta/foo.o, तो मैं कुछ ऐसा चाहते हैं /UTest_sources/componentA/alpha/test_foo.ccऔर /UTest_objects/componentA/beta/test_foo.o। मैं स्टब / मॉक ऑब्जेक्ट्स के लिए एक ही छाया के पेड़ का उपयोग करता हूं और अन्य स्रोतों को परीक्षण की आवश्यकता होती है। कुछ किनारे मामले होंगे, लेकिन यह योजना चीजों को सरल बनाती है। एक अच्छा संपादक मैक्रो विषय स्रोत के साथ-साथ परीक्षण स्रोत को सहजता से खींच सकता है। एक अच्छी बिल्ड सिस्टम (उदाहरण के लिए GNUMake) दोनों को संकलित कर सकती है और एक कमांड (जैसे make test_foo) के साथ परीक्षण चला सकती है, और एक bazillion ऐसी प्रक्रियाओं का प्रबंधन कर सकती है - बस जिनके स्रोत पिछले परीक्षण के बाद से बदल गए हैं - काफी आसानी से (मेरे पास हैं) इन प्रक्रियाओं को शुरू करने का ओवरहेड कभी नहीं मिला, यह ओ (एन) है।

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


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