2012-03-30 6 views
5

हमारी परियोजना में हम एक इकाई परीक्षण के लिए QtTestLib का उपयोग कर रहे हैं। कारण यह है कि पूरी परियोजना पहले से ही क्यूटी का उपयोग करती है जब भी यह संभव हो और यह एक जीयूआई एप्लीकेशन है, इसलिए हम जीयूआई इंटरफेस का परीक्षण करने की क्षमता चाहते थे।एक एकल परीक्षण प्रोजेक्ट का उपयोग करते समय सभी QtTestLib इकाई परीक्षणों के परिणामों को एक फ़ाइल में कैसे लिखें?

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

लेकिन ऐसा लगता है कि परीक्षण 'आउटपुट में कोई समस्या है। आप एक ही मुख्य() सभी परीक्षणों के लिए इस्तेमाल करते हैं और केवल प्रत्येक परीक्षा के लिए cmd लाइन तर्क संचारित करती हैं:

#include "MyFirstTest.h" 
#include "MySecondTest.h" 

int main(int argc, char **argv) 
{ 
    int result = 0; 
    MyFirstTest test1; 
    result |= QTest::qExec(&test1, argc, argv); 
    MySecondTest test2; 
    result |= QTest::qExec(&test2, argc, argv); 
    return result; 
} 

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

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

उत्तर

4

इस चाल के साथ आप व्यक्तिगत परीक्षण xml रिपोर्ट अस्थायी बफर/फ़ाइलों को एकत्र कर सकते हैं; सब एक परीक्षण बाइनरी से। एक बाइनरी के भीतर से अलग परीक्षण आउटपुट एकत्र करने के लिए QProcess को नियोजित करने दें; परीक्षण स्वयं संशोधित तर्कों के साथ कॉल करता है। सबसे पहले, हम एक विशेष कमांड लाइन तर्क पेश करते हैं जो सबटेस्ट को उचित बनाता है - अभी भी आपके परीक्षण निष्पादन योग्य के भीतर। हमारी सुविधा के लिए, हम अधिभारित qExec फ़ंक्शन का उपयोग करते हैं जो QStringList स्वीकार करता है। फिर हम अपने "-सबेटेस्ट" तर्क को अधिक आसानी से सम्मिलित/हटा सकते हैं।

// Source code of "Test" 

int 
main(int argc, char** argv) 
{ 
    int result = 0; 

    // The trick is to remove that argument before qExec can see it; As qExec could be 
    // picky about an unknown argument, we have to filter the helper 
    // argument (below called -subtest) from argc/argc; 

    QStringList args; 

    for(int i=0; i < argc; i++) 
    { 
    args << argv[i]; 
    } 

    // Only call tests when -subtest argument is given; that will usually 
    // only happen through callSubtestAndStoreStdout 

    // find and filter our -subtest argument 

    size_t pos = args.indexOf("-subtest"); 

    QString subtestName; 

    if((-1 != pos) && (pos + 1 < args.length())) 
    { 
    subtestName = args.at(pos+1); 

    // remove our special arg, as qExec likely confuses them with test methods 

    args.removeAt(pos); 
    args.removeAt(pos); 

    if(subtestName == "test1") 
    { 
     MyFirstTest test1; 
     result |= QTest::qExec(&test1, args); 
    } 

    if(subtestName == "test2") 
    { 
     MySecondTest test2; 
     result |= QTest::qExec(&test2, args); 
    } 

    return result; 
} 

जिनमें आप स्क्रिप्ट/कमांडलाइन कॉल में:

./Test -subtest test1 -xml ... >test1.xml 
./Test -subtest test2 -xml ... >test2.xml 

और यहां आप कर रहे हैं - हम साधन परीक्षण उत्पादन को अलग करने के लिए है। अब हम आपके लिए stdout एकत्र करने की QProcess की क्षमता का उपयोग जारी रख सकते हैं। बस इन लाइनों को अपने मुख्य में संलग्न करें। विचार, फिर हमारे निष्पादन कॉल करने के लिए करता है, तो कोई स्पष्ट परीक्षण का अनुरोध कर रहे है, लेकिन हमारे विशेष तर्क के साथ:

bool 
callSubtestAndStoreStdout(const String& subtestId, const String& fileNameTestXml, QStringList args) 
{ 
    QProcess proc; 

    args.pop_front(); 

    args.push_front(subtestId); 
    args.push_front("-subtest"); 

    proc.setStandardOutputFile(fileNameTestXml); 

    proc.start("./Test", args); 

    return proc.waitForFinished(30000); // int msecs 
} 

int 
main(int argc, char** argv) 
{ 
    .. copy code from main in box above.. 

    callSubtestAndStoreStdout("test1", "test1.xml", args); 
    callSubtestAndStoreStdout("test2", "test2.xml", args); 

    // ie. insert your code here to join the xml files to a single report 

    return result; 
} 
तो अपनी स्क्रिप्ट/कमांडलाइन कॉल में

:

./Test -xml   # will generate test1.xml, test2.xml 

दरअसल, उम्मीद है कि भविष्य QTestLib संस्करणों यह करना आसान बनाता है।

3

मैं इस गंदे वैकल्पिक हल का उपयोग किया है (जेनकींस के साथ काम करता है):

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 
    int result = 0; 
    freopen("MyAppTests_Test1.xml", "w", stdout); 
    result |= QTest::qExec(new Test1, argc, argv); 
    freopen("MyAppTests_Test2.xml", "w", stdout); 
    result |= QTest::qExec(new Test2, argc, argv); 
    return result; 
} 

फिर जेनकींस में मैं जोड़ दिया है निर्माण कार्रवाई "खोल निष्पादित": ./path_to_MyAppTests -xml

और पोस्ट-बिल्ड क्रियाएं जोड़ा गया "xUnit परीक्षण परिणाम रिपोर्ट प्रकाशित करें" (QTestlib)। QTestlib पैटर्न: MyAppTests *।xml

2

जैसा कि मैं अभी तक टिप्पणी नहीं कर सकता, मैं इसे यहां मुएनलान के उत्तर में जोड़ने के लिए पोस्ट करूंगा। वहाँ रहे हैं कुछ सुधार हैं, कि यह (कम से कम Qt5 के साथ) काम करने के लिए करने के लिए लागू किया जाएगा:

  1. callSubtestAndStoreStdout 3 कीड़े है। सबसे पहले, नए तर्क को धक्का देने से पहले पहले तर्क को सामने से पॉप किया जाना चाहिए (यह तर्क 0 है)। दूसरा, प्रक्रिया को शुरू करने से पहले से पहले आउटपुट को रीडायरेक्ट करना होगा। तीसरा, यह कुछ मान देने के लिए है;)

    QProcess proc; 
    args.pop_front(); 
    args.push_front(subtestId); 
    args.push_front("-subtest"); 
    
    proc.setStandardOutputFile(fileNameTestXml); 
    proc.start("sportSystemTest.exe", args); 
    return proc.waitForFinished(30000); 
    
  2. मुख्य भी कुछ (स्पष्ट) गलतियों है। मुख्य एक अगर बयान में है:

    if ((-1 != pos) && (pos + 1 < args.length())) 
    
मूल एक कभी नहीं होगा के रूप में आग

वैसे भी, समाधान के लिए धन्यवाद, यह मेरा बड़ा सिरदर्द :)

+0

Qt4.8 था, और पूरी तरह से परीक्षण नहीं किया गया था। सिद्धांत दिखाने के लिए चाहता था। धन्यवाद, उपरोक्त उत्तर में फिक्सेस बना दिया है। – muenalan

1

मेरी राय में हल, एक भी निष्पादन का निर्माण करने की है एक बुरा विचार यहाँ की कोशिश कर रहा है: अपने परीक्षणों में से एक हैं दुर्घटनाओं, दूसरों को नहीं होगा कई testcases के साथ एक सूट को चलाने के लिए अब और निष्पादित ...

एक और तरीका है:

  • उच्चस्तरीय पर एक उपनिर्देशिका परियोजना बनाएँ।
  • प्रत्येक टेस्टकेस के लिए स्वयं के साथ एक सबफ़ोल्डर जोड़ें, और इसे उपडिर्स प्रोजेक्ट में जोड़ें।
  • टोपलवेल मेकफ़ाइल पर
  • रन make check से प्रोजेक्ट का निर्माण करें। यह आपके सभी टेस्टकेस को कॉल करेगा। आप पैरामीटर भी पास कर सकते हैं, उदा। अपने एमएसवीसी पर्यावरण के साथ nmake -k check TESTARGS="-o result.xml,xml -v2 -maxwarnings 0" का उपयोग करें। यदि कोई परीक्षण विफल रहता है तो -के स्विच जारी रखने में मदद करता है।
  • उदाहरण के रूप में xunit जेनकिन्स प्लगइन आपके xml फ़ाइलों को खोजने के लिए my_build\*\result.xml जैसे पैटर्न की अनुमति देता है, और इस तरह आप एक ही फ़ाइल में विलय किए बिना सभी जेनरेट की गई फ़ाइलों को पार्स कर सकते हैं।
संबंधित मुद्दे