可以使用多种不同类型的参数对Googletest进行参数设置的值匹配mbUnit灵活性吗? [英] Can Googletest value-parameterized with multiple, different types of parameters match mbUnit flexibility?

查看:64
本文介绍了可以使用多种不同类型的参数对Googletest进行参数设置的值匹配mbUnit灵活性吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 following mbUnit tests written in C++/CLI.

有关mbUnit的说明,请参见 Hanselman 2006年文章。截至2019年本次编辑,他包括的其他链接已失效。

For an explanation of mbUnit, see the Hanselman 2006 article. As of this 2019 edit, the other links he includes are dead.

请注意,使用 [Test] 属性指示这是一种测试方法,而 [Row(...)] 属性定义实例化的值。

Note how compact this is, with the [Test] attribute indicating this is a test method and the [Row(...)] attributes defining the values for an instantiation.

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

甚至更好的是,这种来自C#的更奇特的测试(超越.NET属性中可以定义的范围,超出C ++ / CLI中可能的范围):

Or even better, this more exotic testing from C# (pushing the boundaries of what can be defined in .Net attributes beyond what's possible in 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)
{
...
}

help 表示,值参数化测试只能让您一次编写测试d然后轻松实例化并使用任意数量的参数值运行它。但我相当确定这是指测试用例的数量。

The help says Value-parameterized tests will let you write your test only once and then easily instantiate and run it with an arbitrary number of parameter values. but I'm fairly certain that is referring to the number of test cases.

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

Even without varying the data types, it seems to me that a parameterized test can only take one parameter?

2019更新

已添加,因为我对此问题执行了ping操作。显示的 Row 属性是mbUnit的一部分。

Added because I got pinged about this question. The Row attribute shown is part of mbUnit.

有关mbUnit的说明,请参见 Hanselman 2006年文章。截至2019年本次编辑,他包含的其他链接已失效。

For an explanation of mbUnit, see the Hanselman 2006 article. As of this 2019 edit, the other links he includes are dead.

在C#世界中,NUnit添加了参数化测试,以更强大,更灵活的方式进行,包括以参数化灯具

In the C# world, NUnit added parameterised testing in a more powerful and flexible way including a way to handle generics as Parameterised Fixtures.

以下测试将执行十五次,则每个x值重复三次,每次都从-1.0到+1.0组合5次随机加倍。

The following test will be executed fifteen times, three times for each value of x, each combined with 5 random doubles from -1.0 to +1.0.

[Test]
public void MyTest(
    [Values(1, 2, 3)] int x,
    [Random(-1.0, 1.0, 5)] double d)
{
    ...
}

以下测试治具将由NUnit实例化三次,将每组参数传递给适当的构造函数。请注意,存在三种不同的构造函数,它们匹配作为参数提供的数据类型。

The following test fixture would be instantiated by NUnit three times, passing in each set of arguments to the appropriate constructor. Note that there are three different constructors, matching the data types provided as arguments.

[TestFixture("hello", "hello", "goodbye")]
[TestFixture("zip", "zip")]
[TestFixture(42, 42, 99)]
public class ParameterizedTestFixture
{
    private string eq1;
    private string eq2;
    private string neq;

    public ParameterizedTestFixture(string eq1, string eq2, string neq)
    {
        this.eq1 = eq1;
        this.eq2 = eq2;
        this.neq = neq;
    }

    public ParameterizedTestFixture(string eq1, string eq2)
        : this(eq1, eq2, null) { }

    public ParameterizedTestFixture(int eq1, int eq2, int neq)
    {
        this.eq1 = eq1.ToString();
        this.eq2 = eq2.ToString();
        this.neq = neq.ToString();
    }

    [Test]
    public void TestEquality()
    {
        Assert.AreEqual(eq1, eq2);
        if (eq1 != null && eq2 != null)
            Assert.AreEqual(eq1.GetHashCode(), eq2.GetHashCode());
    }

    [Test]
    public void TestInequality()
    {
        Assert.AreNotEqual(eq1, neq);
        if (eq1 != null && neq != null)
            Assert.AreNotEqual(eq1.GetHashCode(), neq.GetHashCode());
    }
}


推荐答案

是,只有一个参数。但是,您可以使该参数任意复杂。您可以修改文档中的代码以使用 Row 类型,例如:

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

然后定义参数化测试:

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

最后,将其实例化:

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

这篇关于可以使用多种不同类型的参数对Googletest进行参数设置的值匹配mbUnit灵活性吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆