我使用googletest来实现测试开始,在文档中横跨这句话无意中发现关于value-parameterized tests数据驱动测试不好吗?
- 要测试在各种输入您的密码(又称为数据驱动 测试)。这个功能很容易被滥用,所以请在做这件事时练习一下你的好感 !
我觉得做以下,并想听听你对此事的投入和意见时,我确实是“滥用”的系统。
假设我们有以下代码:
template<typename T>
struct SumMethod {
T op(T x, T y) { return x + y; }
};
// optimized function to handle different input array sizes
// in the most efficient way
template<typename T, class Method>
T f(T input[], int size) {
Method m;
T result = (T) 0;
if(size <= 128) {
// use m.op() to compute result etc.
return result;
}
if(size <= 256) {
// use m.op() to compute result etc.
return result;
}
// ...
}
// naive and correct, but slow alternative implementation of f()
template<typename T, class Method>
T f_alt(T input[], int size);
好了,所以与此代码,它当然具有随机产生的数据,以测试的不同的输入数组大小有意义(通过用f_alt()
比较)来测试f()
分支机构的正确性。最重要的是,我有几个structs
像SumMethod
,MultiplyMethod
等,所以我运行相当大量的试验也为不同的类型:
typedef MultiplyMethod<int> MultInt;
typedef SumMethod<int> SumInt;
typedef MultiplyMethod<float> MultFlt;
// ...
ASSERT(f<int, MultInt>(int_in, 128), f_alt<int, MultInt>(int_in, 128));
ASSERT(f<int, MultInt>(int_in, 256), f_alt<int, MultInt>(int_in, 256));
// ...
ASSERT(f<int, SumInt>(int_in, 128), f_alt<int, SumInt>(int_in, 128));
ASSERT(f<int, SumInt>(int_in, 256), f_alt<int, SumInt>(int_in, 256));
// ...
const float ep = 1e-6;
ASSERT_NEAR(f<float, MultFlt>(flt_in, 128), f_alt<float, MultFlt>(flt_in, 128), ep);
ASSERT_NEAR(f<float, MultFlt>(flt_in, 256), f_alt<float, MultFlt>(flt_in, 256), ep);
// ...
当然现在我的问题是:这样的任何意义,为什么这会很糟糕?
事实上,我曾与float
正在竞选测试时,其中f()
和f_alt()
将给予不同的价值观与SumMethod
由于四舍五入的原因,我可以通过预分类输入数组等提高发现了一个“错误”。从这个经验我认为这实际上是一种很好的做法。
由于两个原因,随机生成的数据不好 - 首先,因为如您所述,测试不可重现。其次,因为角落案件可能不会被随机生成的数据覆盖。第二个缺点是保存随机向量不会起任何作用。 –
谢谢。我修改了我的答案,你当然是对的。 – haimg
@haimg - 如果你在做黑箱测试,你怎么知道使用的算法和它的角落案例? :-) –