2008-09-15 16 views
16

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

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

कोई भी कुछ बेहतर प्रथाओं को जानता है?

+0

मेरी इच्छा है कि मैं यह एक अपवित्र x 10 कर सकता हूं, यह अब तक मैंने पढ़ा है कि एसओ पर सबसे अच्छे प्रश्न हैं। मैंने उन लोगों की गिनती खो दी है जो अभी हार मानते हैं 'हम परीक्षण नहीं कर सकते .. हमारे पास सी ++ कोड है .. बूहू!' – Gishu

+0

Gishu, और अधिक सहमत नहीं हो सका। मैं यहां वही चर्चा कर रहा हूं जहां मैं काम करता हूं। – Lou

उत्तर

9

अवसाद प्रतिक्रिया में भारी है ... लेकिन डर नहीं है, हम the holy book to exorcise the demons of legacy C++ code मिल गया है। गंभीरता से बस पुस्तक खरीदें यदि आप लीगेसी सी ++ कोड के साथ जौस्टिंग के एक सप्ताह से अधिक समय तक लाइन में हैं।

पेज 127 को बारी: भयानक के मामले निर्भरता शामिल हैं। (अब मैं भी नहीं माइकल पंख के मील के दायरे में, लेकिन यहाँ जवाब के रूप में-कम के रूप में मैं-सकता है-का प्रबंधन कर रहा हूँ ..)

समस्या: C++ में एक ClassA ClassB, के बारे में पता करने की जरूरत है कक्षा बी के घोषणा क्लास की स्रोत फ़ाइल में सीधे उठाई गई/पाठ रूप से शामिल है। और चूंकि हम प्रोग्रामर इसे गलत चरम पर ले जाना पसंद करते हैं, इसलिए एक फ़ाइल दोबारा अन्य लोगों को पारस्परिक रूप से शामिल कर सकती है। बनाता है साल लगते हैं .. लेकिन कम से कम यह बनाता है .. हम इंतजार कर सकते हैं।

अब कहने के लिए 'एक परीक्षण दोहन के तहत ClassA instantiating मुश्किल है' एक ख़ामोश है। (हवाला देते हुए एमएफ के उदाहरण - समयबद्धक deps बहुतायत के साथ हमारे पोस्टर समस्या बच्चा है।)

#include "TestHarness.h" 
#include "Scheduler.h" 
TEST(create, Scheduler)  // your fave C++ test framework macro 
{ 
    Scheduler scheduler("fred"); 
} 

यह बाहर लाना होगा निर्माण त्रुटियों की बाढ़ के साथ अजगर भी शामिल है।
ब्लो # 1 धैर्य-एन-हठ: लो प्रत्येक एक समय में एक में शामिल हैं और अगर हम वास्तव में है कि निर्भरता की जरूरत है तय पर। आइए मान लें कि शेड्यूलर डिस्प्ले उनमें से एक है, जिसका डिस्प्ले एंट्री विधि शेड्यूलर के सीटीआर में बुलाया जाता है।
ब्लो # 2 नकली यह तक में आप मेकअप यह (धन्यवाद RonJ):

#include "TestHarness.h" 
#include "Scheduler.h" 
void SchedulerDisplay::displayEntry(const string& entryDescription) {} 
TEST(create, Scheduler) 
{ 
    Scheduler scheduler("fred"); 
} 

और पॉप निर्भरता चला जाता है और उसके सभी सकर्मक भी शामिल है। आप अपनी टेस्ट फाइलों में शामिल होने के लिए Fakes.h फ़ाइल में इसे एन्सेप्लेट करके नकली विधियों का पुन: उपयोग भी कर सकते हैं।
ब्लो # 3 अभ्यास: यह हमेशा इतना आसान नहीं हो सकता है .. लेकिन आप विचार मिलता है। पहले कुछ duels के बाद, deps तोड़ने की प्रक्रिया आसान-एन-यांत्रिक

चेतावनियां मिल जाएगा (मैं वहाँ चेतावनियां हैं उल्लेख किया था? :)

  • हम में परीक्षण मामलों के लिए एक अलग निर्माण की जरूरत है यह फ़ाइल ; हमारे पास प्रोग्राम में शेड्यूलर डिस्प्ले :: displayEntry विधि के लिए केवल 1 परिभाषा हो सकती है।तो अनुसूचक परीक्षण के लिए एक अलग कार्यक्रम बना सकते हैं।
  • हम कार्यक्रम में किसी भी निर्भरता को तोड़ने नहीं कर रहे हैं, तो हम कोड क्लीनर नहीं कर रहे हैं।
  • जब तक हमें परीक्षण की आवश्यकता होती है तब तक आपको उन नकल को बनाए रखने की आवश्यकता होती है।
  • सौंदर्यशास्त्र के अपने अर्थ थोड़ी देर के लिए नाराज हो सकते हैं .. बस

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

और अधिक .. कृपया पुस्तक पढ़ें। अमूल्य। भाई पर लड़ो!

+0

जबकि मुझे यह एक स्वीकार्य उत्तर माना जाता है, मुझे लगता है कि यह वैकल्पिक कार्य कार्यान्वयन में नकली स्टब्स प्रदान करने और निर्माण प्रक्रिया के दौरान पूर्ववर्ती जादू के बीच प्रक्रिया को वास्तव में चमकता है। – MasD

1

आप विरासत कोड का परीक्षण कर रहे जब से मैं यह सोचते करती हूं कि आप refactor नहीं कहा जा सकता है कोड कम निर्भरता के लिए (जैसे pimpl idiom का उपयोग करके)

है कि आप थोड़ा विकल्प मुझे डर लग रहा साथ छोड़ देता है। हर हैडर है कि एक प्रकार या समारोह के लिए शामिल किया गया था कि प्रकार या सब कुछ संकलन करने के लिए समारोह के लिए एक नकली वस्तु की आवश्यकता होगी, वहाँ थोड़ा आप क्या कर सकते हैं ...

0

तुम क्या कर जोखिम आप स्टब्स/नकली/नकली कोड लिख रखें मुख्य परियोजना पर संकलित होने पर एक वर्ग पर यूनिट परीक्षण जिसमें विभिन्न व्यवहार होते हैं।

लेकिन यदि उनमें शामिल हैं और कोई अतिरिक्त व्यवहार नहीं है तो यह ठीक है।

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

1

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

एक हरी क्षेत्र विकास परियोजना पर एक एक्सपी टीम की अगुवाई करने के बाद मुझे वास्तव में मेरे यूनिट परीक्षण पसंद आया। चीजें हुईं और कुछ साल बाद मैं खुद को एक बड़े विरासत कोड बेस पर काम कर रहा हूं जिसमें बहुत सारी गुणवत्ता की समस्याएं हैं।

  1. आदेश अर्थ पूर्ण इकाई लिखने के लिए में परीक्षण कोड की आवश्यकता होगी:

    मैं आवेदन करने के लिए, लेकिन अंत में सिर्फ एक पकड़ -22 में फंस में इकाइयों परीक्षण जोड़ने के लिए एक रास्ता खोजने की कोशिश की पुनर्संशोधित।

  2. इकाई परीक्षणों के बिना कोड को दोबारा करने के लिए यह बहुत खतरनाक होगा।

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

कभी-कभी कोड पर काम करने के लिए "डिजाइन" करने के तरीके पर काम करना सबसे अच्छा होता है।

0

आप निश्चित रूप से बड़ी निर्भरताओं के साथ विरासत कोड के साथ एक चट्टान और एक कठिन जगह के बीच हैं। इसे हल करने के लिए आपको एक लंबा कठोर स्लोग मिल गया है।

आप जो कहते हैं उससे, ऐसा लगता है कि आप प्रत्येक मॉड्यूल के लिए स्रोत कोड को बरकरार रखने की कोशिश कर रहे हैं, इसे बाह्य निर्भरताओं के साथ परीक्षण परीक्षण में रखकर।यहां मेरा सुझाव निर्भरता (या invert) निर्भरताओं को खत्म करने के लिए कुछ रिफैक्टरिंग करने का प्रयास करने का भी बहादुर कदम उठाना होगा, जो शायद आप जिस चरण से बचने की कोशिश कर रहे हैं, वह संभव है।

मैं इस सुझाव है क्योंकि मेरा अनुमान है कि निर्भरता के रूप में आप परीक्षण लिखने आप को मारने के लिए जा रहे हैं। यदि आप निर्भरताओं को खत्म कर सकते हैं तो आप निश्चित रूप से दीर्घ अवधि में बेहतर रहेंगे।

1

मुझे नहीं पता कि यह आपके प्रोजेक्ट के लिए काम करेगा, लेकिन आप अपने निर्माण के लिंक चरण से समस्या पर हमला करने का प्रयास कर सकते हैं।

यह आपकी # अंतर्निहित समस्या को पूरी तरह खत्म कर देगा। आपको बस इतना करना होगा कि शामिल फ़ाइलों में इंटरफेस को फिर से कार्यान्वित करें जो आप चाहते हैं और फिर उस फ़ाइल में इंटरफ़ेस को लागू करने के लिए बनाई गई नकली ऑब्जेक्ट फ़ाइलों से लिंक करें।

इस विधि का बड़ा नुकसान एक अधिक समेकित निर्माण प्रणाली है।

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