जब डेटा की व्यवस्था करना बहुत बोझिल हो तो परीक्षण कैसे करें?


19

मैं एक पार्सर लिख रहा हूं और उसी के एक हिस्से के रूप में, मेरे पास एक Expanderवर्ग है जो एकल जटिल बयान को कई सरल बयानों में "विस्तार" करता है। उदाहरण के लिए, यह इसका विस्तार करेगा:

x = 2 + 3 * a

में:

tmp1 = 3 * a
x = 2 + tmp1

अब मैं सोच रहा हूं कि इस कक्षा का परीक्षण कैसे किया जाए, विशेष रूप से परीक्षणों की व्यवस्था कैसे करें। मैं मैन्युअल रूप से इनपुट सिंटैक्स ट्री बना सकता हूं:

var input = new AssignStatement(
    new Variable("x"),
    new BinaryExpression(
        new Constant(2),
        BinaryOperator.Plus,
        new BinaryExpression(new Constant(3), BinaryOperator.Multiply, new Variable("a"))));

या मैं इसे एक स्ट्रिंग के रूप में लिख सकता हूं और इसे पार्स कर सकता हूं:

var input = new Parser().ParseStatement("x = 2 + 3 * a");

दूसरा विकल्प बहुत सरल, छोटा और पठनीय है। लेकिन यह एक संप्रदाय का भी परिचय देता है Parser, जिसका अर्थ है कि एक बग Parserइस परीक्षण को विफल कर सकता है। तो, परीक्षण की एक इकाई परीक्षण किया जा रहा बंद कर देंगे Expander, और मैं तकनीकी रूप से के एकीकरण के परीक्षण हो जाता है लगता है Parserऔर Expander

मेरा सवाल है: क्या इस Expanderवर्ग का परीक्षण करने के लिए इस तरह के एकीकरण परीक्षणों पर ज्यादातर (या पूरी तरह से) भरोसा करना ठीक है ?


3
कि एक बग Parserकुछ अन्य परीक्षण में विफल हो सकता है एक समस्या नहीं है यदि आप आदतन केवल शून्य विफलताओं पर प्रतिबद्ध हैं, इसके विपरीत इसका मतलब है कि आपके पास अधिक कवरेज है Parser। मैं इसके बारे में चिंता करना चाहूंगा कि एक बग Parserइस परीक्षण को सफल बना सकता है जब इसे विफल होना चाहिए था । यूनिट परीक्षण बग को खोजने के लिए होते हैं, आखिरकार एक परीक्षण टूट जाता है जब यह नहीं होता है लेकिन होना चाहिए।
जोनास कोल्कर

जवाबों:


27

यदि आप ऐसा कर सकते हैं, तो आप अपने आप को बहुत अधिक जटिल, दिलचस्प और उपयोगी व्यवहार के कई और अधिक परीक्षण लिख रहे हैं। तो विकल्प है कि शामिल है

var input = new Parser().ParseStatement("x = 2 + 3 * a");

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

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

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

var input = new AssignStatement(
    new Variable("x"),
    new BinaryExpression(
        new Constant(2),
        BinaryOperator.Plus,
        new BinaryExpression(new Constant(3), BinaryOperator.Multiply, new Variable("a"))));

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


2
यह समझदार है - विशेष रूप से इस तथ्य के बारे में कि सब कुछ कई अन्य लोगों पर निर्भर करता है। एक अच्छी इकाई का परीक्षण न्यूनतम संभव परीक्षण करना चाहिए। जो कुछ भी उस न्यूनतम संभव राशि के भीतर है, उसे पूर्ववर्ती इकाई परीक्षण द्वारा परीक्षण किया जाना चाहिए। यदि आपने पूरी तरह से पार्सर का परीक्षण किया है, तो आप मान सकते हैं कि आप पार्सर का उपयोग ParseStatement
जॉन स्टोरी

6
मुख्य शुद्धता चिंता (मुझे लगता है) अपनी इकाई परीक्षणों में परिपत्र निर्भरता लिखने से बचने के लिए है। यदि या तो पार्सर या पार्सर परीक्षण विस्तारक का उपयोग करते हैं, और यह विस्तारक परीक्षण पार्सर के काम पर निर्भर करता है, तो आपको एक मुश्किल-से-प्रबंधन जोखिम है जो आप परीक्षण कर रहे हैं वह यह है कि पार्सर और विस्तारक संगत हैं , जबकि क्या आप यह परीक्षण करना चाहते थे कि विस्तारक वास्तव में वही करता है जो वह करना चाहता है । लेकिन जब तक कोई अन्य निर्भरता वापस नहीं आती है, तब तक इस इकाई परीक्षण में पार्सर का उपयोग करना वास्तव में किसी इकाई परीक्षण में मानक पुस्तकालय का उपयोग करने से अलग नहीं है।
स्टीव जेसोप

@SteveJessop अच्छी बात है। स्वतंत्र घटकों का उपयोग करना महत्वपूर्ण है ।
जोनाथन यूनिस

3
कुछ मैंने उन मामलों में किया है जहां पार्सर खुद एक महंगा ऑपरेशन है (उदाहरण के लिए कॉम इंटरॉप के माध्यम से एक्सेल फाइलों से डेटा पढ़ना) टेस्ट जनरेशन विधियों को लिखना है जो पार्सर और आउटपुट कोड को कंसोल पर चलाते हैं डेटा पार्सर रिटर्न को फिर से बनाते हैं। । मैं फिर जनरेटर से अधिक पारंपरिक इकाई परीक्षणों में आउटपुट की प्रतिलिपि बनाता हूं। इससे क्रॉस पर निर्भरता को कम करने की अनुमति मिलती है, जब परीक्षण किए गए हर बार नहीं चलने पर पार्सर को केवल सही तरीके से काम करने की आवश्यकता होती है। (एक्सेल प्रक्रियाओं को बनाने / नष्ट करने के लिए कुछ सेकंड / टेस्ट को बर्बाद नहीं करना एक अच्छा बोनस था।)
Dan Neely

@ दानेली के दृष्टिकोण के लिए +1। हम अपने डेटा मॉडल के कई क्रमबद्ध संस्करणों को परीक्षण डेटा के रूप में संग्रहीत करने के लिए समान उपयोग करते हैं, ताकि हम सुनिश्चित कर सकें कि नया कोड अभी भी पुराने डेटा के साथ काम कर सकता है।
क्रिस हेस

6

बेशक यह ठीक है!

आपको हमेशा कार्यात्मक / एकीकरण परीक्षण की आवश्यकता होती है जो पूर्ण कोड पथ का उपयोग करते हैं। और इस मामले में पूर्ण कोड पथ का अर्थ है उत्पन्न कोड का मूल्यांकन। यही कारण है कि आप परीक्षण है कि पार्स है x = 2 + 3 * aकोड है कि यदि साथ रन का उत्पादन a = 5सेट हो जाएगा xकरने के लिए 17के साथ और यदि रन a = -2सेट हो जाएगा xकरने के लिए -4

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


4

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

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

आदर्श रूप से आपके पास दोनों होंगे, लेकिन किसी भी दर पर, आमतौर पर एक स्वचालित परीक्षण बिना परीक्षण के बेहतर होता है।


0

पार्सर पर बहुत सारे परीक्षण करें और जैसे ही पार्सर परीक्षण पास करता है, उन आउटपुट को पार्सर को मॉक करने के लिए एक फाइल को सहेजें और अन्य घटक का परीक्षण करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.