मैं कोड-जनरेटर का परीक्षण कैसे करूं?

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

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

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

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

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

0
ro fr bn
@ जेम्स: वहां कोई आसान जवाब नहीं है ... मैंने अभी इस प्रश्न और प्रतिक्रियाओं को फिर से पढ़ लिया है और उस समय मेरे सभी मुद्दों में बाढ़ आ रही है। मैं आने वाले हफ्तों में यह एक और शॉट दे सकता हूं क्योंकि मैं समय-समय पर विभिन्न प्रतिगमनों के साथ समाप्त हो रहा हूं और इन्हें पहचानने के लिए और अधिक महत्वपूर्ण हो रहा है।
जोड़ा लेखक jkp, स्रोत
यह एक बड़ी भारी स्ट्रिंग तुलना है। एएसटी का उपयोग करना आसान हो सकता है
जोड़ा लेखक Nikos, स्रोत
मैं वास्तव में एक ही समस्या का सामना कर रहा हूं, और नीचे दिए गए उत्तरों में से कोई भी वास्तव में संतोषजनक नहीं है। अनुमोदित, आप इकाई जनरेटर के टुकड़ों का परीक्षण कर सकते हैं। समस्या यह है कि आप कैसे जानते हैं कि जेनरेट कोड सही है, यानी, कोई रिग्रेशन या ऐसा कुछ भी नहीं है, और इसलिए आप जेनरेट कोड के लिए स्वचालित परीक्षण कैसे लिखते हैं (चाहे उन्हें इकाई या एकीकरण परीक्षण कहा जाता है)?
जोड़ा लेखक James Kingsbery, स्रोत

8 उत्तर

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

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

0
जोड़ा

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

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

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

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

Recall that "unit testing" is only one kind of testing. You should be able to unit test the internal pieces of your code generator. What you're really looking at here is system level testing (a.k.a. regression testing). It's not just semantics... there are different mindsets, approaches, expectations, etc. It's certainly more work, but you probably need to bite the bullet and set up an end-to-end regression test suite: fixed C++ files -> SWIG interfaces -> python modules -> known output. You really want to check the known input (fixed C++ code) against expected output (what comes out of the final Python program). Checking the code generator results directly would be like diffing object files...

0
जोड़ा

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

0
जोड़ा

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

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

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

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); 
      } 
    }

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

सृजन से पूरा होने के लिए एक सिस्टम के पास आने के लिए एक चालाक तरीका है, एक अलग के साथ जब व्यवहार के प्रत्येक टुकड़े के लिए विनिर्देशन:

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();
        this._returnB = randomGenerator.Generate();
        this._returnC = randomGenerator.Generate();

        Dep().Stub(b => b.SomeOtherOperation(_input))
                         .Return(this._returnB);
        Dep().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
जोड़ा

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

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

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

Since we're generating it we also generate a nice abstraction in JS we can use to programatically test the app. We followed some ideas outlined here: http://code.tutsplus.com/articles/maintainable-automated-ui-tests--net-35089

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

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

सौभाग्य!

0
जोड़ा
QAIndia
QAIndia
160 प्रतिभागियों की

QA India ! Unite Here we share job postings , prepare for interviews and share tips/techniques in QA. Please follow following guideline while sharing any job ... QA job # location : # title Company : Title : Requirement: Responsibility: Apply: