Can Googletest value-parameterized with multiple, different types of parameters match mbUnit flexibility?

前端 未结 2 2081
孤城傲影
孤城傲影 2020-12-28 15:47

I\'d like to write C++ Google tests which can use value-parameterized tests with multiple parameters of different data types, ideally matching the complexity of the followin

相关标签:
2条回答
  • 2020-12-28 16:38

    An alternative to using a custom structure as the parameter is to use the parameter generator ::testing::Combine(g1, g2, ..., gn). This generator allows you to combine the other parameter generators into a set of parameters with a type std::tuple that has a template type that matches the types of the values provided.

    Note that this generator produces the Cartesian product of the values provided. That means that every possible ordered tuple will be created. I believe the original question is asking for a strict array of parameters with the provided values, which this does not support. If you need to have an array of strict parameters, you could use a tuple with the parameter generator ::testing::Values(v1, v2, ..., vN) where each value is a separate tuple.

    Example:

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

    In the above example, the parameters created for MyTestGroup would look like the following:

    [
      {"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}
    ]
    

    Refer to the GoogleTest documentation for further details. (Accessed on 12/17/2019)

    0 讨论(0)
  • 2020-12-28 16:41

    Yes, there's a single parameter. You can make that parameter be arbitrarily complex, though. You could adapting the code from the documentation to use you Row type, for example:

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

    Then define your parameterized test:

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

    Finally, instantiate it:

    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)
    ));
    
    0 讨论(0)
提交回复
热议问题