c++ - 运行重复的测试报告作为不同的测试

标签 c++ cppunit

我想使用一组不同的输入和预期输出来对函数进行单元测试。

我的函数是无关紧要的,因此我将使用一个示例函数来计算英语单词和以下候选实现:

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

问题是前面的代码在第一次测试中运行良好,在第二次测试中也检测到错误,但之后它停止了测试。报告是:

!!!FAILURES!!!
Test Results:
Run: 1 Failures: 1 Errors: 0

虽然我想得到的结果是:

!!!FAILURES!!!
Test Results:
Run: 6 Failures: 4 Errors: 0

最佳答案

正如我在评论中提到的,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); 
}

最后,由于框架需要一种方法来报告哪个测试失败,它希望它可以打印传递给测试函数的参数。在这种情况下,最简单的方法是添加一个简单的 operator<< 重载。

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

如果您将这些部分结合起来,您应该可以快速获得一个通用解决方案,该解决方案允许您根据需要向数据数组添加尽可能多的数据,而无需调整测试代码。

关于c++ - 运行重复的测试报告作为不同的测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44324285/

相关文章:

C++:任意模板类型的容器

c++ - 不可能的事件序列

c++ - cppunit 中的 QTtestrunner 问题

c++ - 从规范的 CPPunit 测试用例中生成引用测试文件

c++ - 可变参数模板 lambda 参数的模板推导

c++ - Qt5 Beta - 找不到 serviceframework.pro

c++ - 如何处理 Visual Studio 中的第 3 方 C++ 库 LNK4099 警告

c++ - 如何让 CppUnit 轻量级运行?

c - 如何使用curl发出HTTPS请求并传递json

c++ - 组件测试的测试框架