2011-03-31 10 views
17

में गैर-निर्यातित कक्षाओं का परीक्षण हम विजुअल स्टूडियो 2008 और Boost.Test का उपयोग कर यूनिट परीक्षण का उपयोग कर एक सी ++ एप्लिकेशन विकसित करते हैं। फिलहाल, हमारे पास एक अलग समाधान है जिसमें हमारे यूनिट परीक्षण शामिल हैं।यूनिट परीक्षण डीएलएल

कोर समाधान में हमारी कई परियोजनाएं डीएलएल का उत्पादन करती हैं। हम परीक्षण कवरेज में सीमित हैं क्योंकि हम गैर-निर्यातित वर्गों का परीक्षण नहीं कर सकते हैं।

मैं इन कैसे परीक्षण किया जा सकता है पर दो विचार है:

  1. निर्यात सब कुछ
  2. DLL अंदर परीक्षण (एक ही परियोजना और समाधान) रखो और Boost.Test के बाहरी धावक का उपयोग

मुझे पूरी तरह से यकीन नहीं है कि क्या नुकसान होगा। मॉड्यूल स्तर encapsulation तोड़ने के ऊपर संख्या 1, और संख्या 2 के परिणामस्वरूप एक बड़ा डीएलएल हो सकता है, जब तक कि केवल कुछ विन्यास में परीक्षण कोड शामिल न हो।

तो, क्या उपर्युक्त तरीकों से कोई गंभीर कमी है, या आप अन्य समाधानों के बारे में सोच सकते हैं?

+3

मैं "ऑब्जेक्ट लाइब्रेरीज़" नामक एक सुविधा की पेशकश [सीएमके] (http://www.cmake.org) पर संकेत देना चाहता हूं। ('add_library (foo_obj ऑब्जेक्ट ...) ') मेरी परियोजनाओं में मैं ऑब्जेक्ट लाइब्रेरीज़ में स्रोत बनाता हूं, जिसे मैं * डीएलएल * में जोड़ता हूं (' add_library (foo साझा ... $ ) ') * और * इसके परीक्षण ड्राइवर ('add_executable (foo_test ... $ )')। यह एक अलग निर्माण प्रणाली का उपयोग करके नीचे दिए गए उत्तरों का एक रूप है (यही कारण है कि मैंने इसे एक टिप्पणी के रूप में जोड़ा, जवाब नहीं दिया), लेकिन यह एक ही समस्या को हल कर रहा है। – DevSolar

उत्तर

9

this question के लिए टॉम Quarendon के जवाब में विस्तार करते हुए, मैं साइमन स्टील की प्रतिक्रिया के एक मामूली संस्करण का इस्तेमाल किया है:

  • एक परीक्षण परियोजना बनाएँ (जो कुछ भी परीक्षण ढांचे आप की तरह उपयोग करते हुए, मैं CppUnit उपयोग करें)।
  • आपके test_case.cpp में, #include <header/in/source/project.h>
  • परीक्षण परियोजना गुण में:
    • में Linker-> सामान्य, स्रोत परियोजना के $(IntDir) के लिए अतिरिक्त लाइब्रेरी निर्देशिकाएँ जोड़ें।
    • लिंकर-> इनपुट में, .obj फ़ाइलों को अतिरिक्त निर्भरताओं में जोड़ें।
  • प्रोजेक्ट-> परियोजना निर्भरता में स्रोत प्रोजेक्ट से परीक्षण परियोजना से निर्भरता जोड़ें।

फिर, यूनिट परीक्षणों के लिए एकमात्र रखरखाव ओवरहेड मानक एक है - जो इकाई आप परीक्षण करना चाहते हैं उस पर निर्भरता बनाने के लिए।

+2

इस दृष्टिकोण के बारे में एक और विवरण: यदि आपका डीएलएल परीक्षण के तहत प्री-कंपाइल हेडर का उपयोग करता है, तो परीक्षण के तहत डीएलएल से प्री-कंपाइल हेडर फ़ाइल पर निर्भर करता है कि सभी .obj फ़ाइलों को परीक्षण के तहत डीएलएल का उत्पादन करने के लिए जोड़ा जाता है। टेस्ट प्रोजेक्ट का निर्माण करते समय, इसके परिणामस्वरूप लिंकर त्रुटि LNK2011: प्रीकंपील्ड ऑब्जेक्ट में लिंक नहीं होता है; छवि नहीं चल सकती है। विशिष्ट ऑब्जेक्ट फ़ाइलों के अतिरिक्त आप परीक्षण कर रहे हैं, आपको stdafx.obj जोड़ना होगा (यदि आपकी पीसीएच फ़ाइल stdafx.cpp संकलित करके उत्पन्न होती है)। –

+0

इस दृष्टिकोण पर एक और नोट: यदि आपकी टेस्ट प्रोजेक्ट कई डीएलएस का उपयोग करती है जिसमें समान नाम वाली ऑब्जेक्ट फाइलें हैं जिन्हें परीक्षण करने की आवश्यकता है, तो आप लिंकर-> इनपुट सेटिंग्स, आदि में पूरा पथ निर्दिष्ट कर सकते हैं। '$ (SolutionDir) \ t \ $ (प्लेटफार्म) \ $ (कॉन्फ़िगरेशन) \ .obj' उनके बीच अंतर करने के लिए। – Edward

+0

आपको अभी भी [/FORCE:MULTIPLE] (https://msdn.microsoft.com/en-us/library/70abkas3.aspx) की आवश्यकता हो सकती है जैसा कि मैंने अभी खोजा है। – Rai

3

मैं जिस समाधान का उपयोग करता हूं वह मेरे परीक्षण डीएलएल में भी एक ही गैर-निर्यातित कोड का निर्माण करना है। यह बिल्ड समय बढ़ाता है और इसका मतलब है कि दोनों परियोजनाओं में सबकुछ जोड़ना, लेकिन सबकुछ निर्यात करना या मुख्य उत्पाद कोड में परीक्षण डालना बचाता है।

एक और सकारात्मकता गैर-निर्यातित कोड को एक lib में संकलित करना होगा जिसका उपयोग डीएलएल दोनों निर्यात के साथ किया जाता है, और इकाई परीक्षण परियोजना।

+0

यह छोटी परियोजनाओं के लिए काम कर सकता है, लेकिन हमारे पास बहुत सारे कोड हैं, इसलिए यह दो स्थानों पर बदलाव करने के लिए एक रखरखाव दुःस्वप्न होगा। – Jon

+0

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

+0

यह मेरा पहला दृष्टिकोण था, जो मेरे लिए काम करता था। मैंने इसके साथ एक संभावित समस्या के बारे में सोचा था - कभी-कभी एक डीएलएल परियोजना परीक्षण परियोजना की तुलना में विभिन्न संकलन झंडे का उपयोग करती है।इसलिए, डीएलएल और परीक्षण परियोजनाएं एक ही स्रोत फ़ाइल के लिए अलग-अलग ऑब्जेक्ट फाइलें बना सकती हैं। हालांकि मेरे मामले में मुझे पूरा यकीन था कि वे वही थे, आम तौर पर परीक्षण प्रोजेक्ट बनाने वाली ऑब्जेक्ट फ़ाइलों की बजाय, डीएल प्रोजेक्ट बनाने वाली ऑब्जेक्ट फ़ाइलों का परीक्षण करना सुरक्षित होता है। मैं एक दृष्टिकोण @Rai के लिए अपना दृष्टिकोण स्विचिंग समाप्त हो गया। –

0

कहीं निम्नलिखित के रूप में एक ऐसी परिभाषित करने का प्रयास करें सभी फ़ाइलों में शामिल होंगे:

#define EXPORTTESTING __declspec(dllexport) 

और dllexport के स्थान पर इसका इस्तेमाल करते हैं, इस तरह:

class EXPORTTESTING Foo 
{ 
... 
}; 

तो फिर तुम में सक्षम हो जाएगा एक रिलीज डीएलएल बनाने के लिए ध्वज बंद करें, लेकिन इसे यूनिट-टेस्टेबल डीएलएल के लिए रखें।

+2

सुनिश्चित नहीं है कि ऐसा करने का यह एक अच्छा तरीका है ... परीक्षण करने योग्य कोड को परीक्षण के लिए संशोधित नहीं किया जाना चाहिए। भले ही यह एक साधारण मैक्रो है। – toussa

2

एक समाधान भी खोज रहा था, शायद निम्नलिखित बनाए रखना आसान होगा।

एक नया निर्माण कॉन्फ़िगरेशन उदा। डीएलएल परियोजना में "इकाई परीक्षण डीबग" और कॉन्फ़िगरेशन प्रकार को "स्टेटिक लाइब्रेरी .lib" ("सामान्य" -> "कॉन्फ़िगरेशन प्रकार") में परिवर्तित करें।

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

तो इस समाधान का लाभ हैं:

  • कम maintanability लागत
  • एकल DLL/स्टेटिक पुस्तकालय परियोजना
  • मैन्युअल रूप से जोड़ने के लिए की जरूरत नहीं है फ़ाइलों .obj को

दोष:

  • अतिरिक्त कॉन्फ़िगर राशन प्रोफ़ाइल (रों)
  • ग्रेटर संकलन बार
  • अपने निर्माण पर्यावरण (सीआई) में कुछ बदलाव की आवश्यकता होगी

अद्यतन: हम वास्तव में एक अलग दृष्टिकोण का उपयोग कर समाप्त हो गया।

हम नए "टेस्ट डिबग" जोड़ा/"टेस्ट रिलीज 'हर मौजूदा परियोजना है कि हम के लिए विन्यास।

.exe/.dll परियोजनाओं के लिए हम संकलन से मूल main.cpp अक्षम करें और से बदल दिया एक जो टेस्ट फ्रेमवर्क (उदाहरण के लिए gtest) को चालू करता है और सभी परीक्षण चलाता है, परीक्षण अलग-अलग होते हैं। सीपीपी फाइलें जिन्हें नियमित विन्यास (रिलीज/डीबग) में संकलन से भी बाहर रखा जाता है और केवल टेस्ट कॉन्फ़िगरेशन में सक्षम किया जाता है।

.lib परियोजनाओं में हमारे पास नया "टेस्ट डीबग"/"टेस्ट रिलीज" कॉन्फ़िगरेशन भी है और वहां हम स्थिर लाइब्रेरी को .exe फ़ाइल में परिवर्तित करते हैं और एक main.cpp प्रदान करते हैं जो परीक्षण ढांचे को तुरंत चालू करता है और परीक्षण चलाता है और खुद परीक्षण करता है। टेस्ट से संबंधित फाइलों को रिलीज/डीबग कॉन्फ़िगरेशन पर संकलन से बाहर रखा गया है।