क्या बहुत सी इकाई परीक्षण होने जैसी कोई बात है?


139

मुझे मौजूदा एप्लिकेशन के लिए यूनिट टेस्ट लिखने का काम सौंपा गया है। अपनी पहली फ़ाइल खत्म करने के बाद, मेरे पास मूल कोड की 419 लाइनों के लिए परीक्षण कोड की 717 लाइनें हैं।

क्या यह अनुपात हमारे कोड कवरेज को बढ़ाने के साथ असहनीय हो रहा है?

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

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

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


145
निर्भर करता है। क्या आप टिक-टैक-टो का खेल लिख रहे हैं, या आप परमाणु रिएक्टर का प्रबंधन करने के लिए कोड लिख रहे हैं?
ब्रायन ओकले

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

5
उच्च स्तर पर परीक्षण आपको वास्तविक कवरेज के बेहतर परिप्रेक्ष्य प्रदान करेगा। वास्तविक कवरेज से मेरा मतलब है कि सिस्टम के नियमित उपयोग के दौरान एक होने की अधिक संभावना है। इस तरह का कवरेज आप पहले हासिल करना चाहते हैं। 50% तक पहुंचने के लिए YAGNI या मृत कोड हो सकता है जो एक बार हटाए जाने के बाद समग्र कवरेज को भी बढ़ाने में योगदान देगा।
Laiv

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

12
साइक्लाइट परीक्षण दस्तावेज एक मजेदार रीड है: sqlite.org/testing.html । उद्धरण: "SQLite लाइब्रेरी में C कोड के लगभग 122.9 KSLOC सम्‍मिलित हैं। तुलना के अनुसार, परियोजना में परीक्षण कोड और परीक्षण लिपियों के रूप में 745 गुना - 91596.1 KSLOC है।"
user60561

जवाबों:


180

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

बहुत सारे परीक्षण बनाए रखना आमतौर पर समस्याग्रस्त नहीं है। कई टीमों के पास 100% यूनिट टेस्ट कवरेज के शीर्ष पर स्वचालित एकीकरण और सिस्टम परीक्षण हैं।

हालाँकि, आप परीक्षण रखरखाव चरण में नहीं हैं, आप कैच अप खेल रहे हैं। 50% परीक्षण कवरेज में अपनी कक्षाओं के 100% भाग को 50% से कम करना बेहतर है, 100% परीक्षण कवरेज में आपकी सीसा, और आपका नेतृत्व आपको तदनुसार अपना समय आवंटित करने के लिए प्रयास करने की कोशिश करता है। आपके पास उस आधार रेखा के बाद, फिर अगला चरण आमतौर पर उन फ़ाइलों में 100% के लिए जोर दे रहा है जो आगे जा रहे हैं।


11
आपके उत्तर के लिए धन्यवाद। इसने मेरे प्रश्न को परिप्रेक्ष्य में रखने में मदद की और वास्तविक समस्या को संबोधित किया - मेरा दृष्टिकोण! +1
user2954463

43
@astra आपका रवैया उतना बुरा नहीं है। यह सवाल करना अच्छा है कि क्यों। आपके अन्य प्रश्न के उत्कृष्ट प्रश्न का उत्तर देने के लिए: "मैं अपने साथियों को कैसे जानता हूं और मैं" सबसे सामान्य उपयोग के मामलों "के लिए एक ही विचार साझा करता हूं? आप उन्हें अपने परीक्षणों को देखने के लिए प्राप्त करें। उनके बारे में देखें। उनके बारे में बात करें। बहुत कुछ और शायद वे भी करेंगे। कोड की समीक्षा करने वाले परीक्षण शायद ही कभी बर्बाद होते हैं। हालांकि मैं सम्मेलन कक्ष के बजाय एक टर्मिनल पर मेरा काम करता हूं
कैंडिड_ऑरेंज

18
10 साल में कभी भी
फेल

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

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

66

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

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


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

यह एक शानदार उत्तर है और मेरे अनुभव के साथ पूरी तरह से संरेखित है।
टोनी

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

3
यह स्वीकार किए जाते हैं की तुलना में एक बेहतर जवाब है! "कुछ मामलों में, विकास के अधिकांश प्रयासों में निम्न-गुणवत्ता वाले परीक्षण अपडेट होते हैं" - मैंने यह अनुभव किया है और यह बेकार है। कुछ भी परीक्षण नहीं होने से अधिक, कुछ मामलों में।
बेंजामिन हॉजसन

36

आपके सवालों के जवाब

क्या बहुत सी इकाई परीक्षण होने जैसी कोई बात है?

बेशक ... आप उदाहरण के लिए, कई परीक्षण कर सकते हैं जो पहली नज़र में अलग-अलग प्रतीत होते हैं, लेकिन वास्तव में एक ही चीज़ का परीक्षण करते हैं (तार्किक रूप से परीक्षण के तहत "दिलचस्प" एप्लिकेशन कोड की समान लाइनों पर निर्भर करते हैं)।

या आप अपने कोड के इनरल्स का परीक्षण कर सकते हैं जो कभी भी सतह से बाहर की तरफ नहीं होते (यानी, किसी भी तरह के इंटरफ़ेस कॉन्ट्रैक्ट का हिस्सा नहीं हैं), जहां कोई इस बारे में बहस कर सकता है कि क्या समझ में आता है। उदाहरण के लिए आंतरिक लॉग संदेशों का सटीक शब्द या जो भी हो।

मुझे मौजूदा एप्लिकेशन के लिए यूनिट टेस्ट लिखने का काम सौंपा गया है। अपनी पहली फ़ाइल खत्म करने के बाद, मेरे पास मूल कोड की 419 लाइनों के लिए परीक्षण कोड की 717 लाइनें हैं।

यह मुझे काफी सामान्य मानता है। आपके परीक्षण वास्तविक परीक्षण के शीर्ष पर सेटअप और आंसू पर बहुत सारी लाइनें-ऑफ-कोड खर्च करते हैं। अनुपात में सुधार हो सकता है, या नहीं भी हो सकता है। मैं स्वयं काफी भारी परीक्षण कर रहा हूं, और अक्सर वास्तविक कोड की तुलना में परीक्षणों पर अधिक स्थान और समय का निवेश करता हूं।

क्या यह अनुपात हमारे कोड कवरेज को बढ़ाने के साथ असहनीय हो रहा है?

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

इकाई परीक्षण की मेरी समझ यह सुनिश्चित करने के लिए कक्षा में प्रत्येक विधि का परीक्षण करना था कि हर विधि अपेक्षित रूप से काम करती है।

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

हालाँकि, पुल अनुरोध में मेरी टेक लीड ने कहा कि मुझे उच्च स्तर के परीक्षण पर ध्यान देना चाहिए।

तब आप लोगों को यह मानने के चक्कर में पड़ गए कि यूनिट टेस्ट कहने पर लोगों को वास्तव में यूनिट टेस्ट का मतलब है । मैं कई प्रोग्रामर्स से मिला हूं जो कहते हैं कि "यूनिट टेस्ट" लेकिन इसका मतलब कुछ अलग है।

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

ज़रूर, बस 80% महत्वपूर्ण कोड पर ध्यान केंद्रित करने से लोड कम हो जाता है ... मैं सराहना करता हूं कि आप अपने बॉस के बारे में बहुत सोचते हैं, लेकिन यह मुझे सबसे ज्यादा पसंद नहीं है।

मेरे लिए, 100% यूनिट टेस्ट कवरेज एक बुलंद लक्ष्य है, लेकिन अगर हम केवल 50% तक पहुंच गए, तो हमें पता चलेगा कि उस 50% में से 100% कवर किया गया था।

मुझे नहीं पता कि "यूनिट टेस्ट कवरेज" क्या है। मेरा मानना ​​है कि "कोड कवरेज" का मतलब है कि परीक्षण सूट चलाने के बाद, कोड की प्रत्येक पंक्ति (= 100%) को कम से कम एक बार निष्पादित किया गया है।

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

एकीकरण जांच

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

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

जो व्यवहार कुशल विकास या सुविधा प्रेरित विकास के साथ काम करते हैं; वे परिभाषा के अनुसार (सख्त) इकाई परीक्षणों के साथ काम नहीं करते हैं।

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

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

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

फ़ीचर / एकीकरण परीक्षणों में स्पष्ट रूप से कीड़े की अपनी इच्छा हो सकती है (उदाहरण के लिए, प्रदर्शन, 3 पार्टी फ्रेमवर्क का निरर्थक परीक्षण; चूंकि आप आमतौर पर डबल्स का उपयोग नहीं करते हैं, वे भी मेरे अनुभव में, ...) लिखने के लिए कठिन हो जाते हैं। d किसी भी दिन 100% कोड-कवरेज-यूनिट-परीक्षण किए गए एप्लिकेशन (लाइब्रेरी नहीं!) पर 100% सकारात्मक-फ़ीचर-परीक्षणित एप्लिकेशन लें।


1
एकीकरण परीक्षण महान हैं लेकिन यूनिट परीक्षणों के लिए कोई प्रतिस्थापन नहीं हैं, व्यावसायिक अनुप्रयोगों के लिए भी नहीं। उनके साथ कई समस्याएं हैं: ए) वे परिभाषा के अनुसार चलने में लंबा समय लेते हैं (इसका मतलब यह भी है कि वृद्धिशील परीक्षण बहुत बेकार हैं), बी) वे वास्तविक समस्या को इंगित करने के लिए अविश्वसनीय रूप से कठिन बनाते हैं (ओह 50 एकीकरण परीक्षण अभी असफल रहे, उस परिवर्तन के कारण क्या हुआ?) और c) वे एक ही कोड पथ को बार-बार कवर करते हैं।
Voo

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

1
@Voo, जो आपने लिखा है वह सब सच है, और जहां तक ​​मैं बता सकता हूं कि मैंने पहले ही उन सभी समस्याओं का उल्लेख किया है, जिनका उत्तर आपने दिया है ...
AnoE

यदि आप उस सारांश से सहमत हैं, तो मैं वास्तव में नहीं देखता कि आप इस निष्कर्ष पर कैसे पहुँच सकते हैं कि आप इकाई परीक्षणों के लिए एकीकरण परीक्षण पसंद करेंगे। बड़े कार्यक्रमों के व्यापक एकीकरण परीक्षण सूट को चलाने के लिए घंटों या दिन भी लगते हैं, वे महान हैं, लेकिन वास्तविक विकास के दौरान बहुत ही बेकार हैं। और आपकी स्वीकृति परीक्षण (जो हर कोई कर रहा है, ठीक है?) एक ही मुद्दे को पकड़ लेगा जो एकीकरण परीक्षण पाएंगे जो इकाई परीक्षणों से चूक जाएंगे - हालांकि यह सच नहीं है।
Voo

24

हां, बहुत अधिक इकाई परीक्षण करना संभव है। यदि आपके पास इकाई परीक्षणों के साथ 100% कवरेज और उदाहरण के लिए कोई एकीकरण परीक्षण नहीं है, तो आपके पास एक स्पष्ट मुद्दा है।

कुछ परिदृश्य:

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

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

  2. आपके पास 20% परीक्षणों के साथ हर कमिटमेंट के लिए उचित कवरेज हो सकता है, शेष 80% एकीकरण या कम से कम अलग-अलग टेस्ट पास करता है; इस परिदृश्य में आपके द्वारा देखे जाने वाले प्रमुख नकारात्मक प्रभाव धीमे बदलाव हैं क्योंकि आपको परीक्षण करने के लिए एक बड़े समय का इंतजार करना होगा।

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

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


2
जो इकाई परीक्षणों के साथ कोई समस्या नहीं है, लेकिन अन्य स्तरों पर उचित परीक्षण बनाने और निष्पादित करने के लिए संसाधनों को खर्च किए बिना इकाई परीक्षण कवरेज के लिए एक विशिष्ट संख्या की मांग करके अपनी प्राथमिकताओं को गलत करने के लिए संगठन के साथ।
jwenting

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

मुझे आपका वर्णन @johncip से प्यार है, निश्चित रूप से यह एक लगातार उदाहरण है कि कैसे एक अच्छा वर्ग निर्माणकर्ता को अनावश्यक आवश्यक मापदंडों का एक गुच्छा जोड़कर भयानक हो जाता है ...
ब्रूनो गार्डिया

19

ध्यान रखें कि प्रत्येक परीक्षण में एक लागत के साथ-साथ एक लाभ भी है। कमियां शामिल हैं:

  • एक परीक्षा लिखनी होगी;
  • एक परीक्षण चलाने के लिए (आमतौर पर बहुत कम मात्रा में) समय लगता है;
  • परीक्षण को कोड के साथ बनाए रखा जाना चाहिए - परीक्षण को तब बदलना चाहिए जब एपीआई वे परिवर्तन का परीक्षण कर रहे हों;
  • टेस्ट लिखने के लिए आपको अपना डिज़ाइन बदलना पड़ सकता है (हालाँकि ये बदलाव आमतौर पर बेहतर होते हैं)।

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

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


12

हां, बहुत सी इकाई परीक्षण के रूप में ऐसी बात है।

जबकि परीक्षण अच्छा है हर इकाई परीक्षण है:

  • एक संभावित रखरखाव का बोझ जो एपीआई को कसकर जोड़ा जाता है

  • वह समय जो किसी और चीज पर खर्च किया जा सकता है

  • यूनिट टेस्ट सूट में समय का एक टुकड़ा
  • इसमें कोई वास्तविक मूल्य नहीं जोड़ा जा सकता है क्योंकि यह शून्य से कुछ अन्य परीक्षण की नकल के प्रभाव में है जिससे कि कुछ अन्य परीक्षण पास हो जाएंगे और यह परीक्षा विफल हो जाएगी।

यह 100% कोड कवरेज के लिए लक्ष्य के लिए बुद्धिमान है, लेकिन इसका मतलब है कि प्रत्येक परीक्षण का एक सूट स्वतंत्र रूप से कुछ निर्दिष्ट प्रविष्टि बिंदु (फ़ंक्शन / विधि / कॉल आदि) पर 100% कोड कवरेज प्रदान करता है।

हालांकि यह दिया गया है कि अच्छा कवरेज हासिल करना कितना मुश्किल हो सकता है और यह सच है कि 'गलत इकाई परीक्षण' में 'बहुत अधिक इकाई परीक्षण' जैसी कोई चीज है।

अधिकांश कोड के लिए व्यावहारिक संकेत इंगित करता है:

  1. सुनिश्चित करें कि आपके पास प्रवेश-बिंदुओं की 100% कवरेज है (सब कुछ किसी भी तरह से परीक्षण किया जाता है) और इसका लक्ष्य 'गैर-त्रुटियों' रास्तों के 100% कोड कवरेज के करीब होना है।

  2. किसी भी प्रासंगिक न्यूनतम / अधिकतम मान या आकार का परीक्षण करें

  3. आपको जो कुछ भी लगता है उसका परीक्षण करें, विशेष रूप से 'अजीब' मूल्यों का एक अजीब विशेष मामला है।

  4. जब आप बग ढूंढते हैं तो एक यूनिट टेस्ट होता है जो उस बग को प्रकट करता है और इस बारे में सोचता है कि क्या इसी तरह के मामलों को जोड़ा जाना चाहिए।

अधिक जटिल एल्गोरिदम के लिए भी विचार करें:

  1. अधिक मामलों के कुछ थोक परीक्षण करना।
  2. 'ब्रूट-फोर्स' के कार्यान्वयन की तुलना करने और आक्रमणकारियों की जाँच करने के लिए।
  3. यादृच्छिक परीक्षण मामलों के उत्पादन की कुछ विधि का उपयोग करना और ब्रुअर्स-फोर्स और आक्रमणकारियों सहित बाद की स्थितियों की जांच करना।

उदाहरण के लिए कुछ यादृच्छिक इनपुट के साथ एक छँटाई एल्गोरिथ्म की जाँच करें और डेटा को मान्य करके इसे स्कैन करके अंत में सॉर्ट किया जाता है।

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

हो सकता है कि आपका वरिष्ठ जानता हो कि आपके द्वारा बनाये जा रहे घटक को एकीकृत करते समय कुछ बड़े टुकड़े और इकाई का अधिक अच्छी तरह से परीक्षण किया जाएगा।

कुंजी पाठ परीक्षण को जोड़ने के लिए जब कीड़े पाए जाते हैं। जो मुझे इकाई परीक्षणों के विकास के बारे में मेरा सबसे अच्छा सबक देता है:

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

इसलिए यदि आप एक कंपाइलर लिख रहे हैं और आपको एक प्रतीक तालिका (कहना) लिखना है। एक मूल परीक्षण के साथ प्रतीक तालिका को ऊपर और चलाएं और फिर तालिका को भरने वाले घोषणा पार्सर पर काम करें। यदि आप इसमें बग ढूंढते हैं तो केवल प्रतीक तालिका 'स्टैंड-अलोन' इकाई में और परीक्षण जोड़ें। अन्यथा घोषणा पार्सर और बाद में पूरे संकलक पर इकाई परीक्षणों द्वारा कवरेज बढ़ाएं।

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

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


4
मैं यह नहीं कहूंगा कि 100% कवरेज व्यावहारिक है। 100% कवरेज एक अत्यंत उच्च मानक है।
ब्रायन ओकले

दुर्भाग्य से भी यादृच्छिक विधि त्रुटियों को याद कर सकती है। प्रमाण के लिए कोई विकल्प नहीं है, भले ही अनौपचारिक हो।
फ्रैंक हिलमैन

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

@FrankHileman सवाल यह था कि "क्या इकाई सॉफ्टवेयर को ध्यान से डिजाइन करने, स्थैतिक जाँच तर्क और एल्गोरिदम को साबित करने के लिए एक अच्छा विकल्प का परीक्षण कर रही है" तो इसका उत्तर 'नहीं' है। न तो विधि अपने दम पर उच्च-गुणवत्ता वाले सॉफ़्टवेयर का उत्पादन करेगी।
Persixty

3

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

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

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

अगले सबसे मूल्यवान परीक्षण वे हैं जो चरम सीमा या सीमा बिंदुओं का उपयोग करते हैं। उदाहरण के लिए, एक फ़ंक्शन जो वर्ष के महीनों (1-आधारित) को स्वीकार करता है, उसे 0, 1, 12 और 13 के साथ परीक्षण किया जाना चाहिए, ताकि आप जान सकें कि वैध-अवैध संक्रमण सही जगह पर हैं। यह इन परीक्षणों के लिए 2..11 का उपयोग करने के लिए अति-परीक्षण है।

आप एक कठिन स्थिति में हैं, इसमें आपको मौजूदा कोड के लिए परीक्षण लिखना होगा। आप कोड लिख रहे हैं (या लिखने के बारे में) कोड के रूप में धार मामलों की पहचान करना आसान है।


3

इकाई परीक्षण की मेरी समझ यह सुनिश्चित करने के लिए कक्षा में प्रत्येक विधि का परीक्षण करना था कि हर विधि अपेक्षित रूप से काम करती है।

यह समझ गलत है।

इकाई परीक्षण परीक्षण के तहत इकाई के व्यवहार को सत्यापित करते हैं

उस अर्थ में एक इकाई "एक वर्ग में एक विधि" जरूरी नहीं है। मुझे द आर्ट ऑफ़ यूनिट टेस्टिंग में रॉय ओशेरोव द्वारा एक इकाई की परिभाषा पसंद है :

एक इकाई उत्पादन कोड की सभी है जिसे बदलने का समान कारण है।

इसके आधार पर, एक इकाई परीक्षण को आपके कोड के हर वांछित व्यवहार को सत्यापित करना चाहिए । जहां "इच्छा" आवश्यकताओं से अधिक या कम होती है।


हालाँकि, पुल अनुरोध में मेरी टेक लीड ने कहा कि मुझे उच्च स्तर के परीक्षण पर ध्यान देना चाहिए।

वह सही है, लेकिन जैसा सोचता है उससे अलग तरीके से।

आपके प्रश्न से मैं समझता हूं कि आप उस परियोजना में "समर्पित परीक्षक" हैं।

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

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

डंप ऑटोमोबाइल सादृश्य को एक बार फिर से तनाव में लाने के लिए: असेंबली लाइन के अंत में कार के साथ कितने परीक्षण किए जाते हैं? बिल्कुल एक: यह अपने आप ही पार्किंग के लिए ड्राइव करना चाहिए ...

यहाँ मुद्दा यह है:

हमें "इकाई परीक्षण" और "इकाई परीक्षण ढांचे का उपयोग करके स्वचालित परीक्षण" के बीच के अंतर के बारे में पता होना चाहिए।


मेरे लिए, 100% यूनिट टेस्ट कवरेज एक बुलंद लक्ष्य है, लेकिन अगर हम केवल 50% तक पहुंच गए, तो हमें पता चलेगा कि उस 50% में से 100% कवर किया गया था।

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

आपको 100% कोड कवरेज की आवश्यकता नहीं है।

लेकिन आपको 100% व्यवहार कवरेज की आवश्यकता है। (हां, कोड कवरेज और व्यवहार कवरेज किसी भी तरह सहसंबंधित है, लेकिन वे इसके लिए समान नहीं हैं।)

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


निष्कर्ष

कुछ परीक्षण नहीं की तुलना में बेहतर परीक्षण हैं। इसमें कोई शक नहीं!

लेकिन बहुत ज्यादा यूनिट टेस्ट होने जैसी कोई बात नहीं है।

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


2

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

इससे पहले कि आप इसे केवल एक प्रबंधन समस्या के रूप में खारिज कर दें, विचार करें कि वास्तविक दुनिया में कई परियोजनाएं कम स्टाफिंग से ग्रस्त हैं क्योंकि वे विरासत की स्थिति से संपर्क करते हैं। कभी-कभी यह पहली रिलीज के ठीक बाद भी होने लगता है।


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

2
यह परीक्षण के साथ समस्या नहीं है, लेकिन संगठन के साथ है।
jwenting

2
@CodeMonkey निर्भरताएं नहीं टूटीं। उन्हें उन तरीकों से अपडेट किया जा रहा था जिनके लिए हमारे उत्पाद में बदलाव की आवश्यकता थी। हां, परीक्षण मूल्यवान थे, लेकिन अन्य लोगों की तरह मूल्यवान नहीं थे। स्वचालित परीक्षण सबसे मूल्यवान होते हैं जब समकक्ष मैनुअल परीक्षण कठिन होता है।
mrog

2
@jwenting हाँ, यह एक संगठनात्मक समस्या है, कोड समस्या नहीं। लेकिन यह इस तथ्य को नहीं बदलता है कि बहुत सारे परीक्षण थे। एक असफल परीक्षण जिसकी जांच नहीं की जा सकती, वह बेकार है, कारण चाहे जो भी हो।
mrog

एक "एसडीईटी" क्या है?
पीटर मोर्टेंसन

1

उत्पाद कोड की तुलना में परीक्षण कोड की अधिक पंक्तियाँ होना आवश्यक नहीं है, यह मानते हुए कि आप कॉपी-पेस्ट को समाप्त करने के लिए अपने परीक्षण कोड को फिर से बना रहे हैं।

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

"क्यों अधिकांश यूनिट परीक्षण बेकार है" पेपर में एक महान उद्धरण यह है कि यूनिट परीक्षणों में "शुद्धता का व्यापक, औपचारिक, स्वतंत्र ओरेकल होना चाहिए, और ... अवर्णनीय व्यापार मूल्य"


0

एक बात जिसका मैंने उल्लेख नहीं किया है वह यह है कि किसी भी समय किसी भी डेवलपर को चलाने के लिए आपके परीक्षणों को त्वरित और आसान होना चाहिए ।

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

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

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

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