मैं एक अच्छे ऑनलाइन संसाधन की ओर इशारा नहीं कर सकता (इन विषयों पर अंग्रेज़ी विकिपीडिया के लेख कामचलाऊ होते हैं), लेकिन मैं एक व्याख्यान को संक्षेप में सुन सकता हूं जो मैंने सुना है जिसमें बुनियादी परीक्षण सिद्धांत भी शामिल है।
परीक्षण मोड
परीक्षण के विभिन्न वर्ग हैं, जैसे इकाई परीक्षण या एकीकरण परीक्षण । एक इकाई परीक्षण यह दावा करता है कि कोड का एक सुसंगत टुकड़ा (फ़ंक्शन, वर्ग, मॉड्यूल) अपने स्वयं के कार्यों पर अपेक्षित रूप से लिया जाता है, जबकि एक एकीकरण परीक्षण यह दावा करता है कि ऐसे कई टुकड़े एक साथ सही तरीके से काम करते हैं।
एक परीक्षण मामला एक ज्ञात वातावरण है जिसमें कोड का एक टुकड़ा निष्पादित किया जाता है, उदाहरण के लिए विशिष्ट परीक्षण इनपुट का उपयोग करके, या अन्य कक्षाओं का मजाक उड़ाते हुए। कोड का व्यवहार तब अपेक्षित व्यवहार की तुलना में होता है, उदाहरण के लिए एक विशिष्ट वापसी मूल्य।
एक परीक्षण केवल बग की उपस्थिति को साबित कर सकता है, सभी बगों की अनुपस्थिति कभी नहीं। टेस्ट ने प्रोग्राम की शुद्धता पर ऊपरी सीमा लगा दी।
कोड कवरेज़
कोड कवरेज मेट्रिक्स को परिभाषित करने के लिए, स्रोत कोड को एक नियंत्रण प्रवाह ग्राफ में अनुवाद किया जा सकता है जहां प्रत्येक नोड में कोड का एक रैखिक खंड होता है। नियंत्रण केवल प्रत्येक ब्लॉक के अंत में इन नोड्स के बीच बहता है, और हमेशा सशर्त होता है (यदि स्थिति, फिर गोटो नोड ए, और गोटो नोड बी)। ग्राफ में एक स्टार्ट नोड और एक एंड नोड है।
- इस ग्राफ के साथ, स्टेटमेंट कवरेज सभी नोड्स पर सभी विज़िट किए गए नोड्स का अनुपात है। पूर्ण विवरण कवरेज पूरी तरह से परीक्षण के लिए पर्याप्त नहीं है।
- शाखा कवरेज सभी किनारों में CFG में नोड्स के बीच सभी विज़िट किए गए किनारों का अनुपात है। यह अपर्याप्त रूप से परीक्षण करता है।
- पथ कवरेज सभी पथों के लिए सभी विज़िट किए गए पथों का अनुपात है, जहां एक पथ शुरू से अंत तक किनारों के किसी भी अनुक्रम है। समस्या यह है कि छोरों के साथ, अनंत मार्ग हो सकते हैं, इसलिए पूर्ण पथ कवरेज का व्यावहारिक रूप से परीक्षण नहीं किया जा सकता है।
इसलिए हालत की स्थिति की जांच करना अक्सर उपयोगी होता है ।
- में सरल हालत कवरेज , प्रत्येक परमाणु हालत एक बार सच है और एक बार गलत है - लेकिन इस पूर्ण बयान कवरेज गारंटी नहीं है।
- में कई हालत कवरेज , परमाणु शर्तों के सभी संयोजनों पर ले लिया है
true
और false
। इसका मतलब है कि पूर्ण शाखा कवरेज, लेकिन महंगा है। कार्यक्रम में अतिरिक्त बाधाएं हो सकती हैं जो कुछ संयोजनों को बाहर करती हैं। यह तकनीक शाखा कवरेज प्राप्त करने के लिए अच्छा है, मृत कोड पा सकते हैं, लेकिन गलत स्थिति से उपजी बग नहीं पा सकते हैं।
- में कम से कम एक से अधिक शर्त कवरेज , प्रत्येक परमाणु और समग्र हालत एक बार सही और गलत है। यह अभी भी पूर्ण शाखा कवरेज का तात्पर्य है। यह कई हालत कवरेज का एक सबसेट है, लेकिन कम परीक्षण मामलों की आवश्यकता है।
जब हालत कवरेज का उपयोग करके परीक्षण इनपुट का निर्माण करते हैं, तो शॉर्ट-सर्किटिंग को ध्यान में रखा जाना चाहिए। उदाहरण के लिए,
function foo(A, B) {
if (A && B) x()
else y()
}
जरूरतों के साथ परीक्षण किया जाना foo(false, whatever)
, foo(true, false)
और foo(true, true)
के लिए पूर्ण कम से कम एक से अधिक शर्त कवरेज।
यदि आपके पास ऐसी वस्तुएं हैं जो कई राज्यों में हो सकती हैं, तो प्रवाह को नियंत्रित करने के लिए सभी राज्य संक्रमणों के अनुरूप परीक्षण समझदार लगता है।
कुछ और जटिल कवरेज मीट्रिक हैं, लेकिन वे आम तौर पर यहां प्रस्तुत मैट्रिक्स के समान हैं।
ये सफेद बॉक्स परीक्षण विधियां हैं, और आंशिक रूप से स्वचालित हो सकती हैं। ध्यान दें कि एक यूनिट टेस्ट सूट का उद्देश्य किसी भी चुने हुए मीट्रिक द्वारा उच्च कोड कवरेज होना चाहिए , लेकिन 100% हमेशा संभव नहीं होता है। अपवाद हैंडलिंग का परीक्षण करना विशेष रूप से कठिन है, जहां दोषों को विशिष्ट स्थानों में इंजेक्ट किया जाना है।
क्रियात्मक परीक्षण
फिर कार्यात्मक परीक्षण होते हैं जो यह दावा करते हैं कि कोड एक ब्लैक बॉक्स के रूप में कार्यान्वयन को देखकर कल्पना का पालन करता है। इस तरह के परीक्षण इकाई परीक्षणों और एकीकरण परीक्षणों के लिए उपयोगी होते हैं। क्योंकि सभी संभावित इनपुट डेटा (उदाहरण के लिए स्ट्रिंग स्ट्रिंग की सभी संभावित स्ट्रिंग्स के साथ परीक्षण करना) के साथ परीक्षण करना असंभव है, इनपुट (और आउटपुट) को समतुल्य वर्गों में समूहित करना उपयोगी है - यदि length("foo")
सही है, foo("bar")
साथ ही साथ काम करने की संभावना है। इनपुट और आउटपुट तुल्यता वर्गों के बीच प्रत्येक संभावित संयोजन के लिए, कम से कम एक प्रतिनिधि इनपुट चुना और परीक्षण किया जाता है।
इसके अलावा एक परीक्षण करना चाहिए
- बढ़त मामलों
length("")
, foo("x")
, length(longer_than_INT_MAX)
,
- मान जो भाषा द्वारा अनुमत हैं, लेकिन फ़ंक्शन के अनुबंध द्वारा नहीं
length(null)
, और
- संभव जंक डेटा
length("null byte in \x00 the middle")
…
संख्या विज्ञान के साथ, इसका मतलब है परीक्षण 0, ±1, ±x, MAX, MIN, ±∞, NaN
, और फ्लोटिंग पॉइंट तुलना के साथ दो पड़ोसी फ्लोट का परीक्षण करना। एक और जोड़ के रूप में, यादृच्छिक परीक्षण मूल्यों को समतुल्यता वर्गों से लिया जा सकता है। डिबगिंग को कम करने के लिए, यह उपयोग किए गए बीज को रिकॉर्ड करने के लायक है ...
गैर-कार्यात्मक परीक्षण: लोड परीक्षण, तनाव परीक्षण
सॉफ्टवेयर के एक टुकड़े में गैर-कार्यात्मक आवश्यकताएं होती हैं, जिनका परीक्षण भी किया जाना होता है। इनमें निर्धारित सीमाओं (लोड परीक्षण), और उनसे परे (तनाव परीक्षण) परीक्षण शामिल हैं। एक कंप्यूटर गेम के लिए, यह लोड टेस्ट में प्रति सेकंड न्यूनतम संख्या के फ्रेम का दावा कर सकता है। किसी वेबसाइट पर तनाव-परीक्षण किया जा सकता है ताकि प्रतिक्रिया समय का निरीक्षण किया जा सके जब दो बार प्रत्याशित रूप से कई सर्वरों को पीट रहे हों। इस तरह के परीक्षण न केवल पूरे सिस्टम के लिए बल्कि एकल संस्थाओं के लिए भी प्रासंगिक हैं - एक लाख प्रविष्टियों के साथ एक हैश टेबल कैसे ख़राब हो जाती है?
अन्य प्रकार के परीक्षण पूरे सिस्टम परीक्षण हैं जहां परिदृश्यों की नकल की जाती है, या यह साबित करने के लिए स्वीकृति परीक्षण किए जाते हैं कि विकास अनुबंध पूरा हुआ था।
गैर-परीक्षण विधियां
समीक्षा
गैर-परीक्षण तकनीकें हैं जिनका उपयोग गुणवत्ता आश्वासन के लिए किया जा सकता है। उदाहरण वॉकथ्रू, औपचारिक कोड समीक्षा या जोड़ी प्रोग्रामिंग हैं। जबकि कुछ हिस्सों को स्वचालित किया जा सकता है (जैसे लिंटर का उपयोग करके), ये आम तौर पर समय गहन होते हैं। हालांकि, अनुभवी प्रोग्रामर द्वारा कोड समीक्षाओं में बग खोज की उच्च दर है, और विशेष रूप से डिजाइन के दौरान मूल्यवान हैं, जहां कोई स्वचालित परीक्षण संभव नहीं है।
जब कोड समीक्षाएं इतनी शानदार हैं, तो हम अभी भी परीक्षण क्यों लिखते हैं? परीक्षण सूट का बड़ा लाभ यह है कि वे स्वचालित रूप से (ज्यादातर) चला सकते हैं, और प्रतिगमन परीक्षणों के लिए बहुत उपयोगी हैं ।
औपचारिक सत्यापन
औपचारिक सत्यापन कोड के कुछ गुणों को जाता है और साबित करता है । मैनुअल सत्यापन ज्यादातर महत्वपूर्ण भागों के लिए व्यवहार्य है, कम पूरे कार्यक्रमों के लिए। सबूतों ने कार्यक्रम की शुद्धता पर एक कम बाध्यता डाल दी । सबूतों को एक निश्चित डिग्री तक स्वचालित किया जा सकता है, जैसे एक स्थिर प्रकार के चेकर के माध्यम से।
assert
बयानों का उपयोग करके कुछ निश्चित रूप से स्पष्ट रूप से जाँच की जा सकती है ।
इन सभी तकनीकों में अपना स्थान है, और पूरक हैं। TDD कार्यात्मक परीक्षणों को आगे लिखता है, लेकिन कोड लागू होने के बाद परीक्षणों को उनके कवरेज मेट्रिक्स द्वारा आंका जा सकता है।
टेस्टेबल कोड लिखने का मतलब है छोटी कोड इकाइयाँ जिन्हें अलग से परखा जा सकता है (उपयुक्त ग्रैन्युलैरिटी, एकल जिम्मेदारी सिद्धांत के साथ सहायक कार्य)। प्रत्येक फ़ंक्शन के लिए कम तर्क, बेहतर। इस तरह के कोड भी निर्भरता इंजेक्शन के माध्यम से नकली वस्तुओं के सम्मिलन के लिए खुद को उधार देते हैं।
double pihole(double value) { return (value - Math.PI) / (value - Math.PI); }
जो मैंने अपने गणित शिक्षक से सीखा है । इस कोड में ठीक एक छेद है , जिसे ब्लैक-बॉक्स परीक्षण से अकेले नहीं खोजा जा सकता है। मठ में ऐसा कोई छिद्र नहीं है। यदि आप एकतरफा सीमा के बराबर हैं, तो पथरी में आपको छेद को बंद करने की अनुमति है।