通过Google测试进行数据驱动的单元测试[英] Data-driven unit tests with google test

本文是小编为大家收集整理的关于通过Google测试进行数据驱动的单元测试的处理方法,想解了通过Google测试进行数据驱动的单元测试的问题怎么解决?通过Google测试进行数据驱动的单元测试问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我目前正在使用 google google google google google单元测试框架.现在,我的老板对我测试的数据(即我称之为测试的类方法的值)感到不安,这是在测试中很难连接的.他要求从文件中读取此数据.他的论点是,因此为以前被遗忘的角案添加另一个测试会更容易.我对单位测试并不是那么经验,但到目前为止,这不是我的做法.因此,我试图弄清楚什么是最好的方法 - 即使是一个好主意.我很快遇到了DDT(数据驱动的测试)方法.

Google单元测试框架具有他们称为" 价值参数测试.有了我的测试固定装置即可成为模板类,我可以传递参数.但是,我看到了一些问题:

  • 我目前每个课程都有一个固定装置.但是我需要每个方法测试的固定装置,因为每种方法都需要一组不同的参数.这将是很多额外的工作.
  • 正如我所看到的,我只能传递一个参数.由于我的测试需要几个(我的方法的所有参数加上预期的结果),因此需要我传递诸如向量或地图之类的东西.再次,这种结构和检索听起来像是很多工作.

我会想象,像Google测试框架一样成熟,以使其更容易.但是,他们写

价值参数测试(当您想通过各种输入(又称数据驱动测试)测试代码时).此功能易于滥用,因此请在执行此功能时锻炼身体!

此外,还有此博客pobl tott:tott:数据驱动陷阱,也警告我(滥用)数据驱动的单元测试.

所以我的问题归结为:

  • 进行数据驱动的单元测试是一个好主意吗?
  • 如何使用Google测试框架进行数据驱动的单元测试

我并不是真正属于Googletest,基本上可以自由选择我想要的任何框架.

编辑

我在googletest常见问题的常见问题解答中找到了以下语句

Google测试尚未对[...]数据驱动的测试提供良好的支持.我们希望能够尽快在这一领域进行改进.

推荐答案

gtest对此有所支持 - 但也许他们不知道...

使用testing::ValuesIn - 在这个简化的示例中喜欢:

class SomeTests : public TestWithParam<int>
{
public:

};

TEST_P(SomeTests, shouldBePositive)
{
    ASSERT_GT(GetParam(), 0);
}

和 - 从输入流获取值的方式:

std::ifstream inputValuesFromFile("input.txt");
INSTANTIATE_TEST_CASE_P(FromFileStream,
                        SomeTests,
                        ValuesIn(std::istream_iterator<int>(inputValuesFromFile), 
                                 std::istream_iterator<int>()));

要使用比" int"更复杂的类型,您需要为其编写操作员>> - 喜欢:

struct A
{
    int a;
    std::vector<int> b;
}
std::istream& operator >> (std::istream& is, A& out)
{
     std::size_t bSize;
     if ((is >> A.a) && (is >> bSize))
     {
         out.b.reserve(bSize);
         while (bSize-- > 0)
         {
             int b;
             if (!(is >> b))
                break;
             out.b.push_back(b);   
         }
     }
     return is;
}

当然 - 在更复杂的情况下 - 考虑使用类似XML的(JSON?)格式和一些专业的迭代器,而不是std::istream_iterator<T>.

.

对于XML-喜欢格式 - 您可能会考虑此类方案(这是非常假设的代码 - 我在我的脑海中没有任何此类库):

SomeLib::File xmlData("input.xml");

class S1BasedTests : public TestWithParam<S1>
{};

TEST_P(S1BasedTests , shouldXxxx)
{
    const S1& s1 = GetParam();
    ...
}
auto s1Entities = file.filterBy<S1>("S1");
INSTANTIATE_TEST_CASE_P(S1,
                        S1BasedTests,
                        ValuesIn(s1Entities.begin(), s1Entities .end()));

//等任何类型的S1


如果市场上没有这样的C ++ - 类型友好的库(我搜索了2分钟,找不到) - 那么也许是这样的东西:

SomeLib::File xmlFile("input.xml");

struct S1BasedTests : public TestWithParam<SomeLib::Node*>
{
   struct S1 // xml=<S1 a="1" b="2"/>
   {
       int a;
       int b;
   };
   S1 readNode()
   {
        S1 s1{};
        s1.a = GetParam()->getNode("a").getValue<int>();
        s1.b = GetParam()->getNode("b").getValue<float>();
        return s1;
   }
};

TEST_P(S1BasedTests , shouldXxxx)
{
    const S1& s1 = readNode();
    ...
}
INSTANTIATE_TEST_CASE_P(S1,
                        S1BasedTests ,
                        ValuesIn(xmlFile.getNode("S1").getChildren()));
                        // xml=<S1s> <S1.../> <S1.../> </S1>

//等任何节点类型,例如S1

本文地址:https://www.itbaoku.cn/post/1794063.html