2012-03-30 11 views
5

在我們的項目中,我們使用QtTestLib進行單元測試。原因是整個項目只要有可能就已經使用Qt,並且它是一個GUI應用程序,所以我們希望能夠測試GUI界面。如何在使用單個測試項目的同時將所有QtTestLib單元測試結果合併到單個文件中?

我們的項目是由MSVC編譯的,所以我們不希望每個測試都有一個單獨的項目文件,因爲它會混淆解決方案。因此我們爲所有測試創建了一個單獨的項目。所有測試都應該在CIS(持續集成)上實現自動化,因此我們嘗試使用一些XSLT轉換通過XML格式的輸出文件將測試插入到Hudson中。

但是看起來測試的輸出有問題。如果你使用一個main()的所有測試和發射只是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多次。所以如果你想用輸出文件(例如xml)稍微自動化一下,你只會得到最後一個結果。所有其他將被覆蓋。

我們已經嘗試過這種方法,它不能讓您使用像Hudson這樣的一些持續集成系統。所以我的問題是:是否有機會在一個輸出文件中附加結果?當然,我們可以使用一些解決方法,比如通過QTest :: qExec()運行每個測試,並使用修改的參數將結果寫入單獨的文件中,但似乎並不是最好的方法。理想情況下,我想讓一個結果文件與CIS一起使用。

回答

4

有了這個技巧,您可以收集單個測試xml報告到臨時緩衝區/文件;全部來自單個測試二進制文件。讓我們使用QProcess從一個二進制內收集單獨的測試輸出;測試使用修改的參數調用自己。首先,我們介紹一個特殊的命令行參數,這個命令行參數可以幫助您正確使用子測試 - 所有這些參數仍然在測試可執行文件中。爲了方便起見,我們使用接受QStringList的重載qExec函數。然後我們可以更容易地插入/刪除我們的「-subtest」參數。

// 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 

和你在這裏 - 我們要測試輸出分離的手段。現在我們可以繼續使用QProcess爲您收集stdout的能力。只需將這些行添加到主文件中即可。這樣做是爲了再次撥打我們的可執行文件,如果要求沒有明確的測試,但用我們的特殊參數:

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

然後在詹金斯我添加構建行動 「執行shell」:./path_to_MyAppTests-XML

和添加後構建操作「發佈xUnit測試結果報告」(QTestlib)。 QTestlib模式:MyAppTests *。xml

2

由於我還沒有在這裏發表評論,所以我會在這裏發表,以補充muenalan的回答。 有是有一些修正被應用到它的工作(與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. main也有一些(明顯的)錯誤。其中主要的一個是在如果聲明:

    if ((-1 != pos) && (pos + 1 < args.length())) 
    

與原永遠不會火。

無論如何,感謝的解決方案,它解決了我的大傷腦筋:)

+0

是Qt4.8,還沒有完全測試。想要顯示原理。謝謝,已修復上述答案。 – muenalan 2016-03-23 00:44:14

1

在我看來,這裏試圖建立一個單一的可執行文件是一個壞主意:如果你的一個測試崩潰了,其他人也不會執行了...

另一種方式與多個測試用例運行一套:

  • 創建的頂層一個子目錄項目。
  • 爲每個測試用例添加一個帶有自己.pro的子文件夾,並將其添加到子項目中。
  • 從頂級文件夾構建項目
  • 在頂級makefile上運行make check。這將調用所有的測試用例。您也可以傳遞參數,例如與您的MSVC環境一起使用nmake -k check TESTARGS="-o result.xml,xml -v2 -maxwarnings 0"。如果一個測試失敗,-k開關有助於繼續。
  • 作爲一個例子,xunit Jenkins插件允許像my_build\*\result.xml這樣的模式搜索你的xml文件,這樣你就可以解析所有生成的文件而不需要合併到一個文件中。
相關問題