我想编写 C++ Google 测试,它可以使用具有不同数据类型的多个参数的值参数化测试,理想地匹配以下用 C++/CLI 编写的 mbUnit 测试的复杂性。
有关 mbUnit 的解释,请参阅Hanselman 2006 文章。截至 2019 年的编辑,他包含的其他链接已失效。
请注意这是多么紧凑,[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);
}
}
甚至更好的是,来自 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)
{
...
}
帮助说值参数化测试将让您只编写一次测试,然后轻松实例化并使用任意数量的参数值运行它。但我相当确定这是指测试用例的数量。
即使不改变数据类型,在我看来参数化测试只能采用一个参数?
2019 年更新
添加是因为我对这个问题感到困惑。显示的Row
属性是 mbUnit 的一部分。
有关 mbUnit 的解释,请参阅Hanselman 2006 文章。截至 2019 年的编辑,他包含的其他链接已失效。
在 C# 世界中,NUnit 以更强大和更灵活的方式添加了参数化测试,包括将泛型作为Parameterised Fixtures处理的方式。
以下测试将执行 15 次,每个 x 值执行 3 次,每次结合 5 个从 -1.0 到 +1.0 的随机双精度数。
[Test]
public void MyTest(
[Values(1, 2, 3)] int x,
[Random(-1.0, 1.0, 5)] double d)
{
...
}
以下测试夹具将由 NUnit 实例化 3 次,将每组参数传递给适当的构造函数。请注意,有三种不同的构造函数,它们与作为参数提供的数据类型相匹配。
[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());
}
}