2010-08-23 50 views
11

如何使用UnitTest ++運行單個測試?如何使用UnitTest ++運行單個測試?

我正在運行UnitTest ++。我main功能看起來像:

int main() 
{ 
    printf("diamond test v0.1 %s\n\n",TIMESTAMP); 
    diamond::startup(); 
    UnitTest::RunAllTests(); 
    diamond::shutdown(); 
    printf("press any key to continue..."); 
    getc(stdin); 
} 

爲了調試,我想寫點東西像UnitTest::RunSingleTests("MyNewUnitTest");而不是UnitTest::RunAllTests();。 UnitTest ++是否提供這樣的功能?如果是這樣,語法是什麼?

+1

您需要更多地介紹一下你的環境,你已經嘗試和失敗等 – 2010-08-23 09:04:19

+0

所以你已經知道如何運行兩個測試然後? – 2010-08-23 09:08:40

+0

我正在運行UnitTest ++。我的主要功能如下: int main(){ \t \t printf(「diamond test v0.1%s \ n \ n」,__ TIMESTAMP__); \t diamond :: startup(); \t \t UnitTest :: RunAllTests(); \t \t diamond :: shutdown(); \t \t printf(「按任意鍵繼續...」); \t getc(stdin); \t \t } 調試我會像寫 \t單元測試:: RunSingleTests( 「MyNewUnitTest」); 而不是 \t UnitTest :: RunAllTests(); 。我想知道是否有這種類型的函數,如果是,語法如何。 – Arno 2010-08-23 09:08:52

回答

12

試試這個作爲你的main()for unittest(我實際上把它放在一個文件中並添加到單元測試庫中,這樣當鏈接到庫時可執行文件自動使用這個main(),非常方便。)

int main(int argc, char** argv) 
{ 
    if(argc > 1) 
    { 
     //if first arg is "suite", we search for suite names instead of test names 
    const bool bSuite = strcmp("suite", argv[ 1 ]) == 0; 

     //walk list of all tests, add those with a name that 
     //matches one of the arguments to a new TestList 
    const TestList& allTests(Test::GetTestList()); 
    TestList selectedTests; 
    Test* p = allTests.GetHead(); 
    while(p) 
    { 
     for(int i = 1 ; i < argc ; ++i) 
     if(strcmp(bSuite ? p->m_details.suiteName 
          : p->m_details.testName, argv[ i ]) == 0) 
      selectedTests.Add(p); 
     p = p->next; 
    } 

     //run selected test(s) only 
    TestReporterStdout reporter; 
    TestRunner runner(reporter); 
    return runner.RunTestsIf(selectedTests, 0, True(), 0); 
    } 
    else 
    { 
    return RunAllTests(); 
    } 
} 

帶有參數調用到運行單個測試:

> myexe MyTestName 

或單套件

> myexe suite MySuite 
+0

這就是我正在尋找的東西。非常感謝。我會馬上試一試。 – Arno 2010-08-23 10:42:27

+0

完美的作品!非常感謝 ! – Arno 2010-08-23 10:48:35

6

這幾乎是正確的。 「測試」實際上是作爲鏈接列表中的節點使用的,因此當您將其添加到新列表時,必須更正指針以避免包含比您期望的更多的測試。

所以你需要更換

p = p->next; 

Test* q = p; 
    p = p->next; 
    q->next = NULL; 

傑弗裏

+0

謝謝傑弗裏!!!這個附錄確實是必須的。如果沒有這個,stijn解決方案不起作用。 – Tarrasch 2011-06-17 14:33:15

+0

這個解決方案不能有效地解除UniTest ++測試列表的鏈接。 UnitTest ++是否使用其他方法進行清理? – AngelGabriel 2017-11-05 09:57:08

2

如果你告訴它的名字RunTestsIf只能運行一間套房。

class MyTrue 
{ 
    public: 
     MyTrue(const std::string & suiteName, const std::string & testName) 
       : suite(suiteName), test(testName) {} 

     bool operator()(const UnitTest::Test* const testCase) const 
     { 
      return suite.compare(testCase->m_details.suiteName) == 0 && 
         test.compare(testCase->m_details.testName) == 0; 
     } 
    private: 
     std::string suite; 
     std::string test; 
}; 

int main (...) { 
    bool isSuite = false; 
    std::string suiteName = "suite01"; 
    std::string testName = "test01"; 

    UnitTest::TestReporterStdout reporter; 
    UnitTest::TestRunner runner(reporter); 
    if (isSuite) { 
     runner.RunTestsIf(UnitTest::Test::GetTestList(), 
      NULL, MyTrue(suiteName, testName), 0); 
    } else { 
     runner.RunTestsIf(UnitTest::Test::GetTestList(), 
      NULL, UnitTest::True(), 0); 
    } 
} 
1

你可以通過使用RunTestsIfpredicate參數做到這一點:

TestReporterStdout reporter; 
TestRunner runner(reporter); 
return runner.RunTestsIf(Test::GetTestList(), "MySuite", 
    [](Test* t) { 
     return strcmp(t->m_details.testName, "MyTest") == 0; 
    }, 0); 

如果沒有套房,或者你想搜索所有的人,你可以用NULL取代"MySuite"

1

由@stijn給出的答案在測試列表操作中存在一個錯誤,因此它通常會運行您未請求的其他測試。

本示例使用謂詞函子,並且還利用RunTestsIf提供的內置套件名稱匹配。這是正確的,簡單得多。

#include "UnitTest++.h" 
#include "TestReporterStdout.h" 
#include <string.h> 
using namespace UnitTest; 

/// Predicate that is true for tests with matching name, 
/// or all tests if no names were given. 
class Predicate 
{ 
public: 

Predicate(const char **tests, int nTests) 
    : _tests(tests), 
     _nTests(nTests) 
{ 
} 

bool operator()(Test *test) const 
{ 
    bool match = (_nTests == 0); 
    for (int i = 0; !match && i < _nTests; ++i) { 
     if (!strcmp(test->m_details.testName, _tests[i])) { 
      match = true; 
     } 
    } 
    return match; 
} 

private: 
    const char **_tests; 
    int _nTests; 
}; 

int main(int argc, const char** argv) 
{ 
    const char *suiteName = 0; 
    int arg = 1; 

    // Optional "suite" arg must be followed by a suite name. 
    if (argc >=3 && strcmp("suite", argv[arg]) == 0) { 
     suiteName = argv[++arg]; 
     ++arg; 
    } 

    // Construct predicate that matches any tests given on command line. 
    Predicate pred(argv + arg, argc - arg); 

    // Run tests that match any given suite and tests. 
    TestReporterStdout reporter; 
    TestRunner runner(reporter); 
    return runner.RunTestsIf(Test::GetTestList(), suiteName, pred, 0); 
} 
+0

我同意 - 這是一個更好的方法(可能是預期的方式?)來選擇測試。另外,上面的解決方案(stjin&Geoffrey)似乎以一種可能不安全的方式將測試列表關聯起來。 – AngelGabriel 2017-11-05 10:08:58

0

接受答案中的解決方案不適用於我。當套件的第一個測試加載到p時,它不會跳轉到下一個測試(不知道原因)。

我使用Xcode和單元測試++ V1.4

#include "UnitTest++.h" 
#include "TestReporterStdout.h" 

#define SUITE_NAME "ActionFeedback" 

using namespace UnitTest; 

int main(int argc, char** argv) 
{ 
#ifdef SUITE_NAME 
    TestReporterStdout reporter; 
    TestRunner runner(reporter); 
    return runner.RunTestsIf(Test::GetTestList() , SUITE_NAME , True(), 0); 
#else 
    return RunAllTests(); 
#endif 

} 
相關問題