我使用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 - 如果你在做黑箱測試,你怎麼知道使用的算法和它的角落案例? :-) –