2017-06-02 77 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; 
} 

如果合并这些作品,你应该迅速得到一个通用的解决方案,你想不调整测试代码,让你尽可能多的数据添加到您的数据阵列。