Googletest可以使用多种不同类型的参数进行参数化,以匹配mbUnit的灵活性吗?

And*_*ent 16 c++ unit-testing googletest

我想编写C++ Google测试,它可以使用具有不同数据类型的多个参数的值参数化测试,理想地匹配用C++/CLI编写的以下mbUnit测试的复杂性.

请注意这是多么紧凑,[Test]属性指示这是一个测试方法和[Row(...)]定义实例化值的属性.

[Test]
[Row("Empty.mdb", "select count(*) from collar", 0)]
[Row("SomeCollars.mdb", "select count(*) from collar", 17)]
[Row("SomeCollars.mdb", "select count(*) from collar where max_depth=100", 4)]
void CountViaDirectSQLCommand(String^ dbname, String^ command, int numRecs)
{
   String^ dbFilePath = testDBFullPath(dbname);
   {
       StAnsi fpath(dbFilePath);
       StGdbConnection db( fpath );
       db->Connect(fpath);
       int result = db->ExecuteSQLReturningScalar(StAnsi(command));
       Assert::AreEqual(numRecs, result);
   }
}
Run Code Online (Sandbox Code Playgroud)

或者甚至更好,这是来自C#的更奇特的测试(推动.Net属性中定义的界限超出了C++/CLI中可能的范围):

[Test]
[Row("SomeCollars.mdb", "update collar set x=0.003 where hole_id='WD004'", "WD004",
    new string[] { "x", "y" },
    new double[] { 0.003, 7362.082 })]  // y value unchanged 
[Row("SomeCollars.mdb", "update collar set x=1724.8, y=6000 where hole_id='WD004'", "WD004",
    new string[] { "x", "y" },
    new double[] { 1724.8, 6000.0 })]
public void UpdateSingleRowByKey(string dbname, string command, string idValue, string[] fields, double[] values)
{
...
}
Run Code Online (Sandbox Code Playgroud)

帮助下价值参数测试将让你写你的测试一次,然后轻松地实例化和与参数值任意数量的运行.但我很确定这是指测试用例的数量.

即使不改变数据类型,在我看来,参数化测试只能采用一个参数?

Rob*_*edy 27

是的,只有一个参数.但是,您可以使该参数任意复杂.您可以调整文档中的代码以使用您Row键入的内容,例如:

class AndyTest : public ::testing::TestWithParam<Row> {
  // You can implement all the usual fixture class members here.
  // To access the test parameter, call GetParam() from class
  // TestWithParam<T>.
};
Run Code Online (Sandbox Code Playgroud)

然后定义参数化测试:

TEST_P(AndyTest, CountViaDirectSQLCommand)
{
  // Call GetParam() here to get the Row values
  Row const& p = GetParam();
  std::string dbFilePath = testDBFullPath(p.dbname);
  {
    StAnsi fpath(dbFilePath);
    StGdbConnection db(p.fpath);
    db.Connect(p.fpath);
    int result = db.ExecuteSQLReturningScalar(StAnsi(p.command));
    EXPECT_EQ(p.numRecs, result);
  }
}
Run Code Online (Sandbox Code Playgroud)

最后,实例化它:

INSTANTIATE_TEST_CASE_P(InstantiationName, AndyTest, ::testing::Values(
  Row("Empty.mdb", "select count(*) from collar", 0),
  Row("SomeCollars.mdb", "select count(*) from collar", 17),
  Row("SomeCollars.mdb", "select count(*) from collar where max_depth=100", 4)
));
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,罗布。我担心对单个参数使用某种结构是解决方案。正如您从我显示完整测试的编辑中看到的那样,它确实使 gtest 方法比 mbUnit/NUnit 样式笨重得多。我刚刚意识到,与 .Net 的每个测试的选择相比,还必须对给定夹具的所有测试进行参数化。然而,对于那些不愿意使用 C++/CLI 来测试其本机代码的人来说,gtest 参数化仍然比其他本机套件提供的任何东西都好! (2认同)

kka*_*123 7

使用自定义结构作为参数的替代方法是使用参数生成器::testing::Combine(g1, g2, ..., gn)。此生成器允许您将其他参数生成器组合成一组参数,其类型std::tuple具有与提供的值的类型匹配的模板类型。

请注意,此生成器生成所提供值的笛卡尔积。这意味着将创建每个可能的有序元组。我相信最初的问题是要求提供具有所提供值的严格参数数组,但这是不支持的。如果您需要一个严格参数数组,您可以将元组与参数生成器一起使用::testing::Values(v1, v2, ..., vN),其中每个值都是一个单独的元组。

例子:

#include <string>
#include <tuple>

class MyTestSuite : 
  public testing::TestWithParam<std::tuple<std::string, std::string, int>>
{

};

TEST_P(MyTestSuite, TestThatThing)
{
  functionUnderTest(std::get<0>(GetParam()), 
                    std::get<1>(GetParam()), 
                    std::get<2>(GetParam()));
  . . .
}

INSTANTIATE_TEST_SUITE_P(
  MyTestGroup,
  MyTestSuite,
  ::testing::Combine(
    ::testing::Values("FirstString1", "FirstString2"),
    ::testing::Values("SecondString1", "SecondString2"),
    ::testing::Range(10, 13)));

INSTANTIATE_TEST_SUITE_P(
  MyOtherTestGroupThatUsesStrictParameters,
  MyTestSuite,
  ::testing::Values(
    {"FirstString1", "SecondString1", 10},
    {"FirstString2", "SecondString2", 32},
    {"FirstString3", "SecondString3", 75}));
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,创建的参数MyTestGroup如下所示:

[
  {"FirstString1", "SecondString1", 10},
  {"FirstString1", "SecondString1", 11},
  {"FirstString1", "SecondString1", 12},
  {"FirstString1", "SecondString2", 10},
  {"FirstString1", "SecondString2", 11},
  {"FirstString1", "SecondString2", 12},
  {"FirstString2", "SecondString1", 10},
  {"FirstString2", "SecondString1", 11},
  {"FirstString2", "SecondString1", 12},
  {"FirstString2", "SecondString2", 10},
  {"FirstString2", "SecondString2", 11},
  {"FirstString2", "SecondString2", 12}
]
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅 GoogleTest 文档。(访问于 12/17/2019)