2008-08-14 26 views
22

यह एक कठिन और खुला अंत प्रश्न है जो मुझे पता है, लेकिन मैंने सोचा कि मैं इसे फर्श पर फेंक दूंगा और देख सकता हूं कि किसी के पास कोई दिलचस्प सुझाव है या नहीं।मैं कोड-जनरेटर का परीक्षण कैसे करूं?

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

समस्या यह है कि मैं कोड को संशोधित करने में डर रहा हूं। वह और तथ्य यह है कि इकाई स्वयं परीक्षण करती है: जटिल, और बी: भंगुर।

तो मैं इस समस्या के वैकल्पिक दृष्टिकोणों के बारे में सोचने की कोशिश कर रहा हूं, और यह मुझे मारता है मैं शायद इसे गलत तरीके से निपट रहा हूं। हो सकता है कि मुझे परिणाम पर अधिक ध्यान केंद्रित करने की आवश्यकता हो, आईई: क्या मैं जो कोड उत्पन्न करता हूं वह वास्तव में चलता है और जो मैं चाहता हूं वह करता हूं, कोड को जिस तरीके से मैं चाहता हूं उसे देखता हूं।

क्या किसी को इस तरह के किसी भी अनुभव का कोई अनुभव मिला है, जिसे वे साझा करना चाहते हैं?

+0

मुझे वास्तव में एक ही समस्या का सामना करना पड़ रहा है, और नीचे दिए गए उत्तरों में से कोई भी वास्तव में संतोषजनक नहीं है। अनुमोदित, आप इकाई जनरेटर के टुकड़ों का परीक्षण कर सकते हैं। समस्या यह है कि आप कैसे जानते हैं कि जेनरेट कोड सही है, यानी, कोई रिग्रेशन या ऐसा कुछ भी नहीं है, और इसलिए आप जेनरेट कोड के लिए स्वचालित परीक्षण कैसे लिखते हैं (चाहे उन्हें इकाई या एकीकरण परीक्षण कहा जाता है)? –

+1

@ जेम्स: वहां कोई आसान जवाब नहीं है ... मैंने अभी इस प्रश्न और प्रतिक्रियाओं को फिर से पढ़ लिया है और उस समय मेरे सभी मुद्दों में बाढ़ आ रही है। मैं आने वाले हफ्तों में यह एक और शॉट दे सकता हूं क्योंकि मैं समय-समय पर विभिन्न प्रतिगमनों के साथ समाप्त हो रहा हूं और इन्हें पहचानने के लिए और अधिक महत्वपूर्ण हो रहा है। – jkp

+0

इसकी एक बड़ी भारी स्ट्रिंग तुलना। एएसटी – Nikos

उत्तर

12

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

समस्या यह है कि परीक्षण करना मुश्किल है, जेनरेट कोड वास्तव में इकाई परीक्षण प्रणाली के वातावरण में चलाने के लिए उपयुक्त नहीं हो सकता है, और आप अपेक्षित परिणामों को कैसे एन्कोड करते हैं?

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

+0

का उपयोग करना आसान हो सकता है हाँ, एक दूसरे के साथ एक बड़े पैमाने पर स्ट्रिंग की तुलना करने की तरह, सामानों से निपटने के लिए: अपेक्षित मूल्य बराबर: ** "{\" विकल्प \ ": ** लेकिन ** {" विकल्प ": ** – Nikos

0

हां, परिणाम केवल एक चीज है जो मायने रखती है। असली कोर एक ढांचा लिख ​​रहा है जो आपके जेनरेट कोड को स्वतंत्र रूप से चलाने की अनुमति देता है ... अपना समय वहां व्यतीत करें।

0

यदि आप * नक्स पर चल रहे हैं तो आप बैश स्क्रिप्ट या मेकफ़ाइल के पक्ष में अनजान ढांचे को डंप करने पर विचार कर सकते हैं। विंडोज़ पर आप एक शेल ऐप/फ़ंक्शन बनाने पर विचार कर सकते हैं जो जेनरेटर चलाता है और फिर कोड (अन्य प्रक्रिया के रूप में) का उपयोग करता है और उसे बेकार करता है।

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

4

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

0

बस का कहना है कि आप अभी भी सुक्ष्म परीक्षण प्राप्त कर सकते हैं, जबकि परिणाम की पुष्टि करने के लिए चाहते थे

int x = 0; 
GENERATED_CODE 
assert(x == 100); 

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

0

यूनिट परीक्षण केवल एक विशिष्ट इकाई का परीक्षण करना है। तो अगर आप वर्ग एक के लिए एक विनिर्देश लिख रहे हैं, यह अगर वर्ग एक

ठीक है मैं बाद में देखा इस प्रश्न के लिए टैग सी ++/अजगर शामिल वर्ग बी और सी के वास्तविक ठोस संस्करण नहीं है आदर्श है, लेकिन सिद्धांतों में एक ही कर रहे हैं:

public class A : InterfaceA 
    { 
     InterfaceB b; 

     InterfaceC c; 

     public A(InterfaceB b, InterfaceC c) { 
      this._b = b; 
      this._c = c; } 

     public string SomeOperation(string input) 
     { 
      return this._b.SomeOtherOperation(input) 
       + this._c.EvenAnotherOperation(input); 
     } 
    } 

उपरोक्त सिस्टम एक सिस्टम बी और सी के लिए इंटरफेस injects, आप इकाई परीक्षण बस प्रणाली ए, वास्तविक कार्यक्षमता बिना किसी अन्य सिस्टम द्वारा निष्पादित किया जा रहा सकता है। यह इकाई परीक्षण है। ,

public class When_system_A_has_some_operation_called_with_valid_input : SystemASpecification 
{ 
    private string _actualString; 

    private string _expectedString; 

    private string _input; 

    private string _returnB; 

    private string _returnC; 

    [It] 
    public void Should_return_the_expected_string() 
    { 
     _actualString.Should().Be.EqualTo(this._expectedString); 
    } 

    public override void GivenThat() 
    { 
     var randomGenerator = new RandomGenerator(); 
     this._input = randomGenerator.Generate<string>(); 
     this._returnB = randomGenerator.Generate<string>(); 
     this._returnC = randomGenerator.Generate<string>(); 

     Dep<InterfaceB>().Stub(b => b.SomeOtherOperation(_input)) 
         .Return(this._returnB); 
     Dep<InterfaceC>().Stub(c => c.EvenAnotherOperation(_input)) 
         .Return(this._returnC); 

     this._expectedString = this._returnB + this._returnC; 
    } 

    public override void WhenIRun() 
    { 
     this._actualString = Sut.SomeOperation(this._input); 
    } 
} 

तो निष्कर्ष में, एक एकल इकाई/विनिर्देश कई व्यवहार हो सकता है:

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

0

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

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

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

0

मुझे लगता है कि आपको यह जांचने की ज़रूरत है कि आप इसे उत्पन्न करने के तरीके से अधिक उत्पन्न कर रहे हैं।

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

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

चूंकि हम इसे उत्पन्न कर रहे हैं, हम जेएस में एक अच्छा अमूर्त भी उत्पन्न करते हैं जिसे हम ऐप को प्रोग्रामेटिक रूप से जांचने के लिए उपयोग कर सकते हैं। हमने यहां उल्लिखित कुछ विचारों का पालन किया: http://code.tutsplus.com/articles/maintainable-automated-ui-tests--net-35089

सबसे अच्छा हिस्सा यह है कि यह वास्तव में आपके सिस्टम को अंत तक अंत तक जांचता है, कोड जनरेशन से जो वास्तव में आप उत्पन्न कर रहे हैं। एक बार परीक्षण विफल हो जाने पर, जनरेटर को तोड़ने के लिए इसे वापस ट्रैक करना आसान होता है।

यह बहुत प्यारा है।

गुड लक!

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