2011-10-06 9 views
11

मैं googletest का उपयोग कर परीक्षण लागू करने के लिए शुरू कर दिया और के बारे में value-parameterized testsडेटा-संचालित परीक्षण खराब है?

  • आप विभिन्न आदानों पर अपने कोड (यानी डेटा के आधार पर परीक्षण) परीक्षण करना चाहते दस्तावेज में इस उद्धरण भर में ठोकर खाई है। यह सुविधा दुरुपयोग के लिए आसान है, इसलिए इसे करने के दौरान कृपया अपने अच्छे भावना का प्रयोग करें!

मुझे लगता है कि मैं वास्तव में "दुरुपयोग" कर रहा हूँ प्रणाली जब निम्न कार्य और इस मामले पर अपने इनपुट और राय सुनना पसंद करेंगे।

मान लें हम निम्नलिखित कोड है: तो इस कोड के साथ, यह निश्चित रूप से परीक्षण करने के लिए बेतरतीब ढंग से उत्पन्न डेटा की विभिन्न इनपुट सरणी आकारों के साथ समझ में आता है (f_alt() के साथ तुलना करके) f() परीक्षण करने के लिए,

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

ठीक है शाखाओं की शुद्धता।

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

अब निश्चित रूप से मेरे सवाल है: उस के शीर्ष पर, मैं कई structsSumMethod, MultiplyMethod, आदि जैसे, इसलिए मैं परीक्षण की काफी बड़ी संख्या में भी चल रहा हूँ विभिन्न प्रकार के लिए है इस पड़ता है कोई समझ और यह बुरा क्यों होगा?

वास्तव में, मैं एक "बग" जब float के साथ परीक्षण चलाने जहां f() और f_alt(), गोलाई जो मैं इनपुट सरणी आदि presorting से सुधार सकता है की वजह से SumMethod के साथ अलग अलग मान प्रदान करेगा .. इस अनुभव से पाया है मैं वास्तव में कुछ हद तक अच्छा अभ्यास मानता हूं।

उत्तर

10

मुझे लगता है कि मुख्य समस्या "यादृच्छिक रूप से जेनरेट किए गए डेटा" के साथ परीक्षण कर रही है। यह आपके प्रश्न से स्पष्ट नहीं है कि प्रत्येक बार जब आपका परीक्षण दोहन चलता है तो यह डेटा फिर से उत्पन्न होता है। यदि ऐसा है, तो आपके परीक्षण परिणाम पुन: उत्पन्न नहीं होते हैं। अगर कुछ परीक्षण विफल हो जाते हैं, तो इसे हर बार जब आप इसे चलाते हैं, तो नीले चंद्रमा में, कुछ अजीब यादृच्छिक परीक्षण डेटा संयोजन पर असफल होना चाहिए।

तो मेरी राय में आपको अपना परीक्षण डेटा पूर्व-उत्पन्न करना चाहिए और इसे अपने परीक्षण सूट के हिस्से के रूप में रखना चाहिए। आपको यह सुनिश्चित करने की भी आवश्यकता है कि डेटासेट पर्याप्त पर्याप्त और पर्याप्त कोड कवरेज प्रदान करने के लिए पर्याप्त विविध है।

इसके अलावा, जैसा कि बेन वोगेट ने टिप्पणी की थी, यादृच्छिक डेटा के साथ परीक्षण केवल पर्याप्त नहीं है। आपको अपने एल्गोरिदम में कोने के मामलों की पहचान करने और इन मामलों के लिए विशेष रूप से बनाए गए डेटा के साथ अलग-अलग परीक्षण करने की आवश्यकता है। हालांकि, मेरी राय में, यादृच्छिक डेटा के साथ अतिरिक्त परीक्षण भी फायदेमंद होता है जब/यदि आप सुनिश्चित नहीं हैं कि आप अपने सभी कोने के मामलों को जानते हैं। आप उन्हें यादृच्छिक डेटा का उपयोग करके मौके से मार सकते हैं।

+2

यादृच्छिक रूप से जेनरेट किया गया डेटा दो कारणों से खराब है - पहला, क्योंकि जैसा आपने बताया है, परीक्षण पुन: उत्पन्न नहीं होते हैं। और दूसरी बात, क्योंकि कोने के मामलों को यादृच्छिक रूप से जेनरेट किए गए डेटा द्वारा कवर नहीं किया जा सकता है। यादृच्छिक वैक्टर को सहेजना दूसरी कमी के लिए कुछ भी नहीं करता है। –

+0

धन्यवाद। मैंने अपना जवाब संशोधित किया, आप बिल्कुल सही हैं। – haimg

+0

@haimg - यदि आप ब्लैक बॉक्स परीक्षण कर रहे हैं, तो आप एल्गोरिदम का उपयोग कैसे करते हैं और इसके कोने के मामलों को कैसे जानते हैं? :-) –

6

समस्या यह है कि आप उसी तरह फ्लोट पर शुद्धता पर जोर नहीं दे सकते हैं।

एक निश्चित ईपीएसलॉन के भीतर शुद्धता की जांच करें, जो गणना और अपेक्षित मूल्यों के बीच एक छोटा सा अंतर है। यह सबसे अच्छा है जो आप कर सकते हैं। यह सभी फ़्लोटिंग पॉइंट नंबरों के लिए सच है।

मुझे लगता है कि मैं वास्तव में हूँ "कोस" प्रणाली जब कर निम्नलिखित

आपको लगता है यह बुरा था इससे पहले कि आप कि लेख पढ़ने किया? क्या आप इसके बारे में बुरा क्या बता सकते हैं?

आपको कभी-कभी इस कार्यक्षमता का परीक्षण करना होगा। आपको इसे करने के लिए डेटा चाहिए। दुर्व्यवहार कहां है?

+0

निश्चित रूप से। मैं बस उपर्युक्त उदाहरण में इसे सही ढंग से रखना भूल गया था। संपादित। इसके अलावा, मुझे इस तरह के परीक्षण लिखने के खिलाफ तर्कों में अधिक दिलचस्पी है। – bbtrb

0

खराब कारणों में से एक कारण यह है कि डेटा संचालित परीक्षणों को बनाए रखना कठिन होता है और लंबे समय तक परीक्षणों में बग को पेश करना आसान होता है। विवरण के लिए यहां देखें: http://googletesting.blogspot.com/2008/09/tott-data-driven-traps.html

मेरे दृष्टिकोण के मुताबिक जब आप गंभीर रिफैक्टरिंग कर रहे हैं तो आप सबसे अधिक उपयोगी हैं और आपको यकीन नहीं है कि आपने तर्क को गलत तरीके से नहीं बदला है। यदि आपका यादृच्छिक डेटा परीक्षण उस तरह के परिवर्तनों के बाद असफल हो जाएगा, तो आप अनुमान लगा सकते हैं: क्या यह डेटा की वजह से या आपके परिवर्तनों के कारण है?

हालांकि, मुझे लगता है कि यह उपयोगी हो सकता है (तनाव परीक्षण के समान जो 100% पुनरुत्पादित नहीं होते हैं)। लेकिन यदि आप कुछ निरंतर एकीकरण प्रणाली का उपयोग कर रहे हैं, तो मुझे यकीन नहीं है कि डेटा-संचालित परीक्षणों में बड़ी मात्रा में यादृच्छिक जेनरेट किए गए डेटा को इसमें शामिल किया जाना चाहिए। मैं अलग-अलग तैनाती करता हूं जो समय-समय पर को यादृच्छिक परीक्षणों के बहुत सारे बनाता है (इसलिए जब आप इसे चलाते हैं तो कुछ खराब होने की संभावना बहुत अधिक होनी चाहिए)। लेकिन यह सामान्य परीक्षण सूट के हिस्से के रूप में बहुत संसाधन भारी है।

संबंधित मुद्दे