एक राज्य प्रणाली के लिए डिजाइनिंग यूनिट परीक्षण


20

पृष्ठभूमि

टेस्ट ड्रिवेन डेवलपमेंट को मैंने पहले ही स्कूल और इंडस्ट्री में खत्म कर दिया था। मैं इसे सीखने की कोशिश कर रहा हूं, लेकिन कुछ प्रमुख चीजें अभी भी मुझसे बच रही हैं। TDD समर्थकों का कहना है कि बहुत सारी बातें (जैसे बाद में "एकल सिद्धांत" या SAP के रूप में संदर्भित ):

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

स्रोत: http://www.artima.com/weblogs/viewpost.jsp?thread=35578

वे इस तरह की बातें भी कहते हैं (इसके बाद "निजी पद्धति सिद्धांत" या PMP के रूप में संदर्भित ):

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

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

स्रोत: आप निजी विधियों का परीक्षण कैसे करते हैं?

परिस्थिति

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

  • SAP का सुझाव है कि मुझे "राज्य निर्माण प्रक्रिया" का परीक्षण नहीं करना चाहिए, मुझे यह मान लेना चाहिए कि राज्य से मुझे बिल्ड कोड की उम्मीद है और फिर एक राज्य परिवर्तन का परीक्षण करने की कोशिश कर रहा हूं जिसे मैं परीक्षण करना चाहता हूं

  • PMP का सुझाव है कि मैं इस "स्टेट बिल्ड अप" स्टेप को छोड़ नहीं सकता और केवल उन कार्यप्रणाली का परीक्षण कर सकता हूं जो उस कार्यक्षमता को स्वतंत्र रूप से संचालित करती हैं।

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


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


@ डोभाल: कृपया बताएं कि टेलीफोन (SIP UserAgent) को नॉन-स्टेटफुल की तरह कैसे बनाया जाए। इस इकाई का अपेक्षित व्यवहार RFC में राज्य संक्रमण आरेख का उपयोग करके निर्दिष्ट किया गया है।
बार्ट वैन इनगेन शेनॉ

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

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

जवाबों:


15

परिप्रेक्ष्य:

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

मैं उस परिप्रेक्ष्य को सामने लाता हूं क्योंकि मुझे लगता है कि विवरणों में खो जाना आसान है और हम जो हासिल करने की कोशिश कर रहे हैं उसकी दृष्टि खो देते हैं।

सिद्धांत - SAP:

जब मैं टीडीडी में विशेषज्ञ नहीं हूं, तो मुझे लगता है कि आप एकल निबंध सिद्धांत (एसएपी) को पढ़ाने की कोशिश कर रहे हैं का हिस्सा याद कर रहे हैं। एसएपी को "एक समय में एक चीज का परीक्षण" के रूप में बहाल किया जा सकता है। लेकिन एसएपीटी के रूप में टीओटीएटी जीभ को आसानी से रोल नहीं करता है।

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

यदि आप एक समय में एक चीज का परीक्षण करते हैं, तो आपका खोज क्षेत्र बहुत छोटा है और दोष को अधिक तेज़ी से पहचाना जाता है। ध्यान रखें कि "एक समय में एक चीज का परीक्षण करें" जरूरी नहीं कि आपको एक बार में एक से अधिक प्रक्रिया आउटपुट को देखने से बाहर रखे। उदाहरण के लिए, "ज्ञात अच्छे मार्ग" का परीक्षण करते समय, मैं एक विशिष्ट, परिणामी मूल्य के fooसाथ-साथ दूसरे मूल्य में भी देखने की उम्मीद कर barसकता हूं और मैं इसे foo != barअपने परीक्षण के भाग के रूप में सत्यापित कर सकता हूं। कुंजी तार्किक रूप से परीक्षण किए जा रहे मामले के आधार पर आउटपुट चेक का समूह है।

सिद्धांत - PMP:

इसी तरह, मुझे लगता है कि आपको निजी पद्धति सिद्धांत (पीएमपी) के बारे में थोड़ा याद आ रहा है। पीएमपी हमें प्रणाली को ब्लैक बॉक्स की तरह व्यवहार करने के लिए प्रोत्साहित करता है। दिए गए इनपुट के लिए, आपको एक दिया हुआ आउटपुट मिलना चाहिए। आपको परवाह नहीं है कि ब्लैक बॉक्स आउटपुट कैसे उत्पन्न करता है। आप केवल इस बात का ध्यान रखते हैं कि आपके आउटपुट आपके इनपुट के साथ संरेखित हों।

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


लागू टीडीडी ( आपके लिए )

तो आपकी स्थिति एक साधारण अनुप्रयोग से परे एक शिकन प्रस्तुत करती है। आपके ऐप के तरीके स्टेटफुल हैं, इसलिए उनका आउटपुट न केवल इनपुट पर बल्कि पहले से जो कुछ किया गया है, उस पर निर्भर है। मुझे यकीन है कि मुझे <insert some lecture>यहाँ भयानक और ब्ला ब्ला ब्ला के बारे में होना चाहिए , लेकिन यह वास्तव में आपकी समस्या को हल करने में मदद नहीं करता है।

मैं आपको मानने जा रहा हूं कि आपके पास किसी प्रकार की राज्य आरेख तालिका है जो विभिन्न संभावित राज्यों को दिखाती है और संक्रमण को ट्रिगर करने के लिए क्या करने की आवश्यकता है। यदि आप नहीं करते हैं, तो आपको इसकी आवश्यकता होगी क्योंकि यह इस प्रणाली के लिए व्यावसायिक आवश्यकताओं को व्यक्त करने में मदद करेगा।

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

अगला, आपको डेटा प्रोसेसिंग को मान्य करने के लिए परीक्षण बनाने की आवश्यकता है। जब आप डेटा प्रोसेसिंग परीक्षण बनाते हैं, तो उन कुछ राज्य परीक्षणों का पुन: उपयोग किया जाएगा। उदाहरण के लिए, मान लीजिए कि आपके पास एक ऐसी विधि है Foo()जिसके पास Initऔर State1राज्यों के आधार पर अलग-अलग आउटपुट हैं। ChangeFooToState1जब आप " Foo()इन State1" है तो आउटपुट का परीक्षण करने के लिए आप अपने परीक्षण का उपयोग सेटअप चरण के रूप में करना चाहेंगे ।

उस दृष्टिकोण के पीछे कुछ निहितार्थ हैं जिनका मैं उल्लेख करना चाहता हूं। Spoiler, यह वह जगह है जहाँ मैं शुद्धतावादियों को संक्रमित करता हूँ

सबसे पहले, आपको यह स्वीकार करना होगा कि आप एक स्थिति में एक परीक्षण के रूप में कुछ का उपयोग कर रहे हैं और दूसरी स्थिति में एक सेटअप। एक ओर, यह एसएपी का सीधा उल्लंघन प्रतीत होता है। लेकिन अगर आप तार्किक ChangeFooToState1रूप से दो उद्देश्यों के रूप में फ्रेम करते हैं तो आप अभी भी उस भावना को पूरा कर रहे हैं जो एसएपी हमें सिखा रहा है। जब आपको यह सुनिश्चित करने की आवश्यकता होती है कि Foo()परिवर्तन अवस्थाएँ हैं, तो आप ChangeFooToState1परीक्षण के रूप में उपयोग करते हैं । और जब "तब Foo()जब State1आप ChangeFooToState1सेटअप के रूप में उपयोग कर रहे हैं तब आउटपुट को मान्य करने की आवश्यकता होती है ।

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

इसे एक साथ रखना:

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

यदि आप उस दृष्टिकोण का पालन करते हैं, तो bloated, complicated, long, and difficult to writeपरीक्षणों को प्रबंधित करने के लिए थोड़ा आसान होना चाहिए। सामान्य तौर पर, उन्हें छोटा होना चाहिए और उन्हें अधिक संक्षिप्त (यानी कम जटिल) होना चाहिए। आपको ध्यान देना चाहिए कि परीक्षण अधिक डिकूप्ड या मॉड्यूलर भी हैं।

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


11

आप आमतौर पर कार्यों में सेटअप विवरण को दूर कर देंगे ताकि आपको खुद को दोहराना न पड़े। इस तरह से आपको केवल कार्यक्षमता में परिवर्तन होने पर परीक्षण में इसे एक स्थान पर बदलना होगा।

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

यह अक्सर एक वर्ग में बहुत अधिक डालने का संकेत है। यदि आपके पास राज्य की आवश्यकताएं हैं, तो आपको एक वर्ग की आवश्यकता है जो राज्य का प्रबंधन करता है और कुछ नहीं। जो वर्ग इसका समर्थन करते हैं, उन्हें स्टेटलेस होना चाहिए। आपके SIP उदाहरण के लिए, पैकेट को पार्स करना पूरी तरह से स्टेटलेस होना चाहिए। आपके पास एक वर्ग हो सकता है जो एक पैकेट को पार्स करता है, फिर कुछ ऐसा कहता है जैसे sipStateController.receiveInvite()कि राज्य के बदलावों को प्रबंधित करना, जो स्वयं अन्य स्टेटलेस कक्षाओं को कॉल करता है जैसे कि फोन की अंगूठी।

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

दूसरे शब्दों में, आप पूरी तरह से राज्य से बच नहीं सकते हैं, लेकिन आप इसे कम कर सकते हैं और अलग कर सकते हैं।


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

+1 के लिए "आप राज्य से पूरी तरह नहीं बच सकते, लेकिन आप इसे कम कर सकते हैं और अलग कर सकते हैं।" मैं सहमत नहीं हो सकता। सॉफ्टवेयर में राज्य एक आवश्यक बुराई है।
ब्रैंडन

0

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

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

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

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