2017-06-02 114 views
3

我想用一組不同的輸入和期望的輸出對一個函數進行單元測試。以不同的測試運行重複的測試報告

我的功能是不相關的。因此我將改用一個例子功能,其對英語單詞與下列候選人實現:

int countEnglishWords(const std::string& text) 
{ 
    return 5; 
}; 

下面是一組測試數據。數據的結尾標有一個單詞「END」。

struct TestData { 
    std::string text; 
    int englishWords; 
}; 

struct TestData data[] = // Mark end with "END" 
{ 
    { "The car is very fast", 5 }, 
    { "El coche es muy rapido", 0 }, 
    { "The rain in Spain stays mainly in the plain", 9}, 
    { "XXXXX OOOOO TTTT", 0}, 
    { "Yes Si No No", 3}, 
    { "I have a cheerful live", 5}, 
    { "END", 0} 
}; 

我可以很容易地編寫6個測試用例,我會得到我想要的結果。但這是不可維護的,因爲任何進一步的測試添加到測試用例都不會被測試,所以需要編寫另一個測試用例,這將只是鍋爐板。因此,我寫它通過這樣的所有測試數據環路一個單獨的測試案例:

#include <cppunit/ui/text/TestRunner.h> 
#include <cppunit/extensions/HelperMacros.h> 

class cppUnit_test: public CppUnit::TestFixture 
{ 
private: 
    CPPUNIT_TEST_SUITE (cppUnit_test); 
    CPPUNIT_TEST(myTest); 
    CPPUNIT_TEST_SUITE_END(); 

public: 
    void myTest(); 
}; 

void cppUnit_test::myTest() 
{ 
    TestData* p = data; 
    while (p->text != "END") 
    { 
    std::stringstream ss; 
    ss << "Text=\"" << p->text << "\" Counted=" << 
     countEnglishWords(p->text) << " Expected=" << p->englishWords; 
    CPPUNIT_ASSERT_MESSAGE(ss.str().c_str(), 
       countEnglishWords(p->text) == p->englishWords); 
    ++p; 
    } 
} 

int main() 
{ 
    CPPUNIT_TEST_SUITE_REGISTRATION (cppUnit_test); 
    CppUnit::Test *suite = 
     CppUnit::TestFactoryRegistry::getRegistry().makeTest(); 
    CppUnit::TextUi::TestRunner runner; 
    runner.addTest(suite); 
    runner.run(); 
    return 0; 
} 

的問題是,前面的代碼通過第一個測試精細運行,還檢測在第二測試,但後錯誤它停止測試。報告是:

!!!失敗!!!
測試結果:
運行:1次失敗:1個錯誤:0

雖然我希望得到的結果是:

!!! FAILURES!
測試結果:
運行:6次失敗:4個錯誤:0

+0

Cppunit 1.14爲此功能提供支持。有CPPUNIT_TEST_PARAMETERIZED和TestCaller現在接受任何可以轉換爲std :: function 的可調用函數。兩者都可以用來實現所需的行爲。 – moggi

回答

1

正如我在評論的CppUnit 1.14.0已經提到可以支持你的使用情況。

我想引用外部數組最快的方法是使用CPPUNIT_TEST_PARAMETERIZED。這個宏需要兩個參數:第一個類似於CPPUNIT_TEST測試方法,然後第二個參數是可迭代的。

基於您的代碼會看起來像:

CPPUNIT_TEST_PARAMETERIZED(myTest, aData); 

現在我們需要去適應你的MYTEST功能一點點。

void cppUnit_test::myTest(const TestData& data) 
{ 
    std::stringstream ss; 
    ss << "Text=\"" << data.text << "\" Counted=" << 
     countEnglishWords(data.text) << " Expected=" << data.englishWords; 

    bool b = countEnglishWords(data.text) == data.englishWords; 
    std::string a = ss.str(); 
    CPPUNIT_ASSERT_MESSAGE(a, 
      b); 
} 

最後,由於框架需要一種報告哪個測試失敗的方法,它期望它可以打印傳遞給測試函數的參數。在這種情況下,最簡單的方法是添加一個簡單的運算符< <過載。

std::ostream& operator<<(std::ostream& strm, const TestData& data) 
{ 
    strm << data.text; 
    return strm; 
} 

如果合併這些作品,你應該迅速得到一個通用的解決方案,你想不調整測試代碼,讓你儘可能多的數據添加到您的數據陣列。