2009-06-19 6 views
6

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

runner.addTest(TestClass::suite());

में डाल करने के लिए है कक्षा और परीक्षण की सूची प्राप्त करने के लिए testFactoryRegistry की makeTests() विधि का उपयोग नहीं कर सकते हैं। यदि मैं उन्हें शीर्ष निर्देशिका में सभी को एक साथ संकलित करता हूं तो makeTests() विधि ठीक काम करती है, लेकिन अगर मैं इसकी सहायता कर सकता हूं तो मैं सभी परीक्षण कक्षाओं को एक स्थान पर नहीं रखना चाहता हूं।

CppUnit प्रलेखन निम्नलिखित थोड़ा संकेत

समस्या को लिंक जब हेल्पर मैक्रो का उपयोग कर देता है? CPPUNIT_TEST_SUITE_NAMED_REGISTRATION, CPPUNIT_REGISTRY_ADD और CPPUNIT_REGISTRY_ADD_TO_DEFAULT:

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

runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest() 

);

फ़ाइल में आपके मुख्य() फ़ंक्शन main.cpp में, कोई टेस्ट रन नहीं होगा!

कारण बस उस लिंक मंच, निर्माण प्रक्रिया के कदम से एक है, अंतिम निष्पादन में वस्तु फ़ाइलें (.obj या ओ फ़ाइलें) सम्मिलित नहीं है, तो कोई अपरिभाषित है आपके main.cpp में प्रतीक।

इस तरह, वस्तु कोड जो AutoRegister स्थिर चर इन्स्टेन्शियशन शामिल अंतिम निष्पादन का हिस्सा नहीं है और सक्षम मुख्य() फ़ंक्शन में धावक में अपने आप को सम्मिलित करने के लिए नहीं है।

आप main.cpp में एक अपरिभाषित प्रतीक बनाने के लिए इतना है कि mytest.o फ़ाइल अंतिम निष्पादन में main.o के साथ एकीकृत किया गया है।

चाल

लेकिन मिशेल Nolard द्वारा प्रतिबद्ध कहना नहीं है यह काम करने के लिए कैसे और मैं बस इतना घना अपने आप को यह पता लगाने या ऑन लाइन एक उदाहरण खोजने के लिए सक्षम होने के लिए नहीं कर रहा हूँ।

अब मैं प्रत्येक लाइब्रेरी के लिए एक अलग निष्पादन योग्य परीक्षण कर सकता हूं, और अंत में मैं इस तरह से जा सकता हूं, लेकिन मैं इसे पहले काम करने की कोशिश करना चाहता था इसलिए मेरे पास परीक्षण करने के लिए चलाने के लिए केवल एक एकल परीक्षण कार्यक्रम था पूरी बात। काम करने के लिए इसे कैसे प्राप्त करें के बारे में कोई विचार/उदाहरण?

उत्तर

1

मुख्य के लिए एक अनिर्धारित प्रतीक जोड़कर, इसका मतलब है कि लिंकर को आपके बाहरी पुस्तकालयों को खोजने में मजबूर करने के लिए कोई यादृच्छिक बाहरी प्रतीक बनाएं जिसमें टेस्ट कोड है।

int fredDummyInt = 0; // declare a unique symbol for the linker to resolve 

और barneyTestLib.cpp में, आप एक ऐसी ही लाइन जोड़ेंगे::

उदाहरण के लिए, दो परीक्षण पुस्तकालयों फ्रेड और बार्नी संभालने, fredTestLib.cpp में आप सिर्फ इस लाइन जोड़ेंगे

int barneyDummyInt = 0; // a different unique symbol for the linker to resolve 

आप प्रत्येक लाइब्रेरी को विभिन्न चरणों में अलग से संकलित कर सकते हैं। मुख्य परीक्षण कार्यक्रम में, फिर आप उन्हें हल करने के लिए लिंकर को मजबूर करते हैं। (के अनुसार क्या चाल ऊपर कह रहा है के लेखक)

extern int fredDummyInt; 
extern int barneyDummyInt; 
... 
main() { 
    ... 
    fredDummyInt++; // give the linker some symbols to resolve 
    barneyDummyInt++; 
    ... 

विचार है कि क्योंकि लिंकर पहले से ही fredDummyInt के लिए fredTest.lib खोज कर रहा है, यह भी खोजने के लिए और होगा: तो main.cpp ये पंक्तियां जोड़ें अपने स्वचालित रूप से पंजीकृत परीक्षणों को हल करें।

नोट: मैंने यह देखने की कोशिश नहीं की है कि यह काम करता है या नहीं! मैं सिर्फ बाहरी लोगों के बारे में आपके प्रश्न का उत्तर दे रहा हूं।

विचार करने का एक और तरीका डीएलएल में अपने परीक्षण बनाना होगा, और लोडलाब्रिरी() का उपयोग स्पष्ट रूप से उन्हें चलाने के लिए लाएगा। ओवरकिल के लिए, यदि आप MfcUi :: TestRunner का उपयोग करते हैं, तो आप संभवतः एक छोटी ड्रॉप-डाउन जीयूआई चीज बना सकते हैं जो आपको लाइब्रेरी को लोड करने, लोड करने, फिर उस लाइब्रेरी में चलाने के लिए परीक्षण प्रदर्शित करने देता है, फिर उन्हें चलाता है।

+0

मैं आज रात इसे आजमाउंगा। – dagorym

+0

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

+0

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

0

इस समस्या का समाधान पहले स्टेटसेट के रूप में सरल है (लेकिन यह बहुत ही सुरुचिपूर्ण नहीं हो सकता है)। प्रत्येक TestFixture कि एक बाहरी पुस्तकालय में स्थित है आप मुख्य मॉड्यूल

#include <CppUnitTestFixtureExample.h> 
CppUnitTestFixtureExample Test1; 

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

0

मुझे पता है इस पोस्ट अब काफी पुराना है, लेकिन किसी और के लिए है जो इसे भर आता है: एक तरह से अपने कोड में यह w/बाहर होने के संदर्भ को संबोधित करने के निर्देश देने के लिए (बल) लिंकर पूरे स्थिर पुस्तकालय शामिल करने के लिए है बाइनरी में विवरण क्षेत्र जीसीसी & ld आदमी पृष्ठों से उपलब्ध है, और इस पोस्ट यह भी शामिल किया गया है: How to force gcc to link unreferenced, static C++ objects from a library

प्रति ld के आदमी पेज, यह स्पष्ट रूप से विकल्प को बंद (भी ऊपर दिए गए उदाहरणों में से एक में दिखाया गया है) करने पर विचार करने के लिए महत्वपूर्ण है।

संबंधित मुद्दे