परिणामों की भविष्यवाणी करने के लिए कोड के लिए यूनिट परीक्षण कैसे लिखते हैं?


124

मैं अक्सर बहुत संख्यात्मक / गणितीय कार्यक्रमों के साथ काम करता हूं, जहां किसी फ़ंक्शन का सटीक परिणाम अग्रिम में भविष्यवाणी करना मुश्किल है।

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

क्या यूनिट परीक्षण लिखने और टीडीडी को लागू करने के लिए तकनीक ज्ञात है जब परीक्षण के तहत कोड का परिणाम भविष्यवाणी करना मुश्किल है?

परिणामों की भविष्यवाणी करने में मुश्किल के साथ कोड का ए (वास्तविक) उदाहरण:

एक फ़ंक्शन weightedTasksOnTime, जो प्रति दिन किए गए काम की मात्रा को workPerDayसीमा में (0, 24], वर्तमान समय initialTime> 0, और कार्यों की एक सूची को देखते हुए दिया गया है taskArray; प्रत्येक संपत्ति को पूरा करने के लिए एक समय के साथ time> 0, नियत तारीख dueऔर महत्व मूल्य importance; रेंज में एक सामान्यीकृत मूल्य [0, 1] उन कार्यों के महत्व का प्रतिनिधित्व करता है जो उनकी dueतिथि से पहले पूरा हो सकते हैं यदि प्रत्येक कार्य यदि दिए गए क्रम में पूरा हो जाता है taskArray, तो शुरू होता है initialTime

इस फ़ंक्शन को लागू करने के लिए एल्गोरिथ्म अपेक्षाकृत सीधा है: इसमें कार्यों पर पुनरावृति taskArray। प्रत्येक कार्य के लिए, जोड़ने timeके लिए initialTime। यदि नया समय < due, importanceएक संचायक में जोड़ें । उलटा वर्कपेयर द्वारा समय को समायोजित किया जाता है। संचायक को वापस करने से पहले, कार्य आयात के योग को सामान्य करने के लिए विभाजित करें।

function weightedTasksOnTime(workPerDay, initialTime, taskArray) {
    let simulatedTime = initialTime
    let accumulator = 0;
    for (task in taskArray) {
        simulatedTime += task.time * (24 / workPerDay)
        if (simulatedTime < task.due) {
            accumulator += task.importance
        }
    }
    return accumulator / totalImportance(taskArray)
}

मेरा मानना ​​है कि उपरोक्त समस्या को सरल बनाया जा सकता है, जबकि इसके मूल को बनाए रखने, हटाने workPerDayऔर सामान्य करने की आवश्यकता, देने के लिए:

function weightedTasksOnTime(initialTime, taskArray) {
    let simulatedTime = initialTime
    let accumulator = 0;
    for (task in taskArray) {
        simulatedTime += task.time
        if (simulatedTime < task.due) {
            accumulator += task.importance
        }
    }
    return accumulator
}

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


4
क्या आप किसी फ़ंक्शन का एक सरल उदाहरण प्रदान कर सकते हैं जिसका परिणाम भविष्यवाणी करना मुश्किल है?
रॉबर्ट हार्वे

62
FWIW आप एल्गोरिथ्म का परीक्षण नहीं कर रहे हैं। संभवत: यह सही है। आप कार्यान्वयन का परीक्षण कर रहे हैं। हाथ से काम करना अक्सर समानांतर निर्माण के रूप में ठीक होता है।
क्रिस्टियन एच


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

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

जवाबों:


251

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

दूसरा है पवित्रता की जाँच। ये वे चेक हैं जो आप करते हैं जहां आपको पता नहीं है कि क्या उत्तर सही है , लेकिन आप निश्चित रूप से जानते होंगे कि क्या यह गलत है । ये ऐसी चीजें हैं जैसे समय को आगे बढ़ना चाहिए, मूल्य एक उचित सीमा में होना चाहिए, प्रतिशत 100 तक जोड़ना चाहिए, आदि।

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


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

21
एक और चीज जो कुछ मामलों में मददगार हो सकती है (हालांकि यह शायद नहीं) एक उलटा कार्य लिखना और परीक्षण करना है कि जब जंजीर होती है, तो आपका इनपुट और आउटपुट समान होता है।
साइबरस्पेस

7
sanity check अक्सर संपत्ति आधारित परीक्षणों के लिए QuickCheck
jk

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

5
@ आईफ्लो यकीन नहीं होता कि आप मजाक कर रहे थे, लेकिन उलटा उलटा पहले से मौजूद है। वर्थ यह महसूस करते हुए कि परीक्षण विफल हो सकता है उलटा कार्य में एक समस्या हो सकती है
ल्यूसिडब्रोट

80

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

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


32
मेटामॉर्फिक संबंध संपत्ति-आधारित परीक्षण का एक विशिष्ट उदाहरण है , जो सामान्य रूप से इन जैसी स्थितियों के लिए एक उपयोगी उपकरण है
Dannnno

38

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

यह पता लगाएगा कि एल्गोरिथ्म (या डेटा जिस पर निर्भर करता है) बदल गया है

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


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

21

उसी तरह आप किसी अन्य प्रकार के कोड के लिए यूनिट टेस्ट लिखते हैं:

  1. कुछ प्रतिनिधि परीक्षण मामलों का पता लगाएं, और उन का परीक्षण करें।
  2. किनारे के मामलों का पता लगाएं, और उन का परीक्षण करें।
  3. त्रुटि की स्थिति का पता लगाएं, और उन का परीक्षण करें।

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

साइड-इफेक्ट्स, या फ़ंक्शंस से बचें जो बाहरी ताकतों से प्रभावित होते हैं। शुद्ध कार्यों का परीक्षण करना आसान है।


2
गैर-नियतात्मक एल्गोरिदम के लिए आप RNG के बीज को बचा सकते हैं या निश्चित अनुक्रम या कम विसंगति नियतात्मक श्रृंखला का उपयोग करके इसे मॉक कर सकते हैं जैसे
हैलटन

14
@PaintingInAir यदि एल्गोरिदम के आउटपुट को सत्यापित करना असंभव है, तो क्या एल्गोरिथ्म भी गलत हो सकता है?
वोल्फगैंगग्रॉइस

5
Unless your code involves some random elementयहां ट्रिक यह है कि आप अपने रैंडम नंबर जनरेटर को इंजेक्टेड डिपेंडेंसी बना लें, ताकि आप इसे एक नंबर जेनरेटर के लिए बदल सकें, जो आप चाहते हैं वह सटीक परिणाम देता है। यह आपको फिर से सही परीक्षण करने में सक्षम बनाता है - इनपुट मापदंडों के रूप में उत्पन्न संख्याओं की गिनती करना। not deterministic (i.e. it won't produce the same output given the same input)चूंकि एक इकाई परीक्षण एक नियंत्रित स्थिति से शुरू होना चाहिए , यह केवल गैर-नियतात्मक हो सकता है यदि इसके पास एक यादृच्छिक तत्व है - जिसे आप तब इंजेक्ट कर सकते हैं। मैं यहां अन्य संभावनाओं के बारे में नहीं सोच सकता।
फ्लटर

3
@PaintingInAir: या तो। मेरी टिप्पणी तेजी से निष्पादन या तेज परीक्षण लेखन दोनों पर लागू होती है। यदि आपको हाथ से एकल उदाहरण की गणना करने में तीन दिन लगते हैं (मान लें कि आप उपलब्ध सबसे तेज़ विधि का उपयोग करें जो कोड का उपयोग नहीं कर रहा है) - तो तीन दिन वह है जो उसे लगेगा। यदि आप इसके बजाय वास्तविक कोड पर अपने अपेक्षित परीक्षा परिणाम के आधार पर हैं, तो परीक्षण स्वयं समझौता कर रहा है। यह करने जैसा है if(x == x), यह एक व्यर्थ की तुलना है। आपको अपने दो परिणामों की आवश्यकता है ( वास्तविक : कोड से आता है; अपेक्षित : आपके बाहरी ज्ञान से आता है) एक दूसरे से स्वतंत्र होने के लिए।
फ्लोटर

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

17

पोस्ट की गई टिप्पणियों के कारण अपडेट करें

मूल उत्तर को संक्षिप्तता के लिए हटा दिया गया था - आप इसे संपादित इतिहास में पा सकते हैं।

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

पहले, एक टीएल; डीआर अन्यथा लम्बे उत्तर से बचने के लिए:

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

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

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

यहां तक ​​कि अगर आप ग्राहक और रसोइए दोनों हैं, तब भी इसके बीच एक सार्थक अंतर है:

  • मैंने इस भोजन को ठीक से तैयार नहीं किया, यह स्वादिष्ट नहीं था (= कुक त्रुटि)। जले हुए स्टेक का कभी भी स्वाद अच्छा नहीं लगता है, भले ही आपको स्टेक पसंद हो।
  • मैंने भोजन ठीक से तैयार किया, लेकिन मुझे यह पसंद नहीं है (= ग्राहक त्रुटि)। यदि आपको स्टेक पसंद नहीं है, तो आप स्टेक खाने को पसंद नहीं करेंगे, भले ही आपने इसे पूर्णता के लिए पकाया हो।

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

आपको कोड के परीक्षण, और व्यावसायिक आवश्यकताओं के परीक्षण के बीच अंतर करने की आवश्यकता है।

उदाहरण के लिए, ग्राहक चाहता है कि वह [इस] की तरह काम करे । हालाँकि, डेवलपर गलत समझता है, और वह कोड लिखता है जो [कि] करता है ।

इसलिए डेवलपर इकाई परीक्षण लिखेगा जो कि परीक्षण करेगा [ यदि ] अपेक्षित रूप से काम करता है। यदि उसने एप्लिकेशन को सही ढंग से विकसित किया है, तो उसका यूनिट परीक्षण पास हो जाएगा, भले ही एप्लिकेशन ऐसा नहीं करता हो [ जिसे ग्राहक उम्मीद कर रहा था।

यदि आप ग्राहक की अपेक्षाओं (व्यावसायिक आवश्यकताओं) का परीक्षण करना चाहते हैं, तो इसे एक अलग (और बाद में) चरण में करने की आवश्यकता है।

इन परीक्षणों को चलाया जाना चाहिए, जब आपको दिखाने के लिए एक सरल विकास वर्कफ़्लो:

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

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

  • यूनिट परीक्षण एक विशेष उपकरण है जो यह सत्यापित करने में आपकी सहायता करता है कि आपका विकास चरण समाप्त हो गया है या नहीं।
  • क्यूए परीक्षण आवेदन का उपयोग करके किया जाता है ।

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

एक उद्यमी और अकादमिक के रूप में, आपको यहाँ एक महत्वपूर्ण अंतर याद आ रहा है, जो विभिन्न जिम्मेदारियों को उजागर करता है।

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

मुझे "यदि आप एल्गोरिथ्म के साथ आया था" स्थिति पर अधिक विस्तार देखकर खुशी होगी, जैसा कि मुझे लगता है कि यह समस्या पेश करने की सबसे अधिक संभावना है। विशेष रूप से ऐसी स्थितियों में जहां कोई "यदि ए तो बी, बाकी सी" उदाहरण प्रदान किए जाते हैं। (ps मैं downvoter नहीं कर रहा हूँ)
PaintingInAir

@PaintingInAir: लेकिन मैं वास्तव में इस पर विस्तृत नहीं कर सकता क्योंकि यह आपकी स्थिति पर निर्भर करता है। यदि आपने यह एल्गोरिथ्म बनाने का निर्णय लिया है, तो आपने स्पष्ट रूप से एक विशेष सुविधा प्रदान करने के लिए ऐसा किया है। आपको ऐसा करने के लिए किसने कहा? उन्होंने उनके अनुरोध का वर्णन कैसे किया? क्या उन्होंने आपको बताया कि उन्हें कुछ विशेष स्थितियों में क्या करने की आवश्यकता थी? (यह जानकारी वह है जो मैं अपने उत्तर में "विश्लेषण" के रूप में संदर्भित करता हूं) आपको जो भी स्पष्टीकरण प्राप्त हुआ है (जो आपको एल्गोरिथ्म बनाने के लिए नेतृत्व किया गया था) का उपयोग यह परीक्षण करने के लिए किया जा सकता है कि क्या एल्गोरिथ्म अनुरोध के अनुसार काम करता है। संक्षेप में, कुछ भी लेकिन कोड / स्व-निर्मित एल्गोरिथ्म का उपयोग किया जा सकता है।
फ्लोटर

2
@PaintingInAir: ग्राहक, विश्लेषक और डेवलपर को कसकर जोड़े रखना खतरनाक है; जैसा कि आप समस्या को परिभाषित करने जैसे महत्वपूर्ण कदमों को छोड़ देने की संभावना रखते हैं । मुझे विश्वास है कि आप यहाँ क्या कर रहे हैं। आप एल्गोरिथ्म की शुद्धता का परीक्षण करना चाहते हैं , बजाय इसके कि यह सही ढंग से लागू किया गया था। लेकिन ऐसा नहीं है कि आप इसे कैसे करते हैं। कार्यान्वयन का परीक्षण इकाई परीक्षणों का उपयोग करके किया जा सकता है। एल्गोरिथ्म का परीक्षण स्वयं आपके (परीक्षण किए गए) एप्लिकेशन का उपयोग करने और इसके परिणामों की जांच करने का विषय है - यह वास्तविक परीक्षण आपके कोडबेस के दायरे से बाहर है (जैसा कि यह होना चाहिए )।
फ्लोटर

4
यह उत्तर पहले से ही बहुत बड़ा है। यदि आप इसे फेंकना नहीं चाहते हैं, तो मूल सामग्री को सुधारने का एक तरीका खोजने की कोशिश करें, ताकि आप इसे नए उत्तर में एकीकृत कर सकें।
jpmc26

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

9

संपत्ति परीक्षण

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

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

संपत्ति परीक्षण के लिए सबसे अच्छा परिचय है कि मैंने देखा है यह एफ # में एक है। उम्मीद है कि वाक्यविन्यास तकनीक की व्याख्या को समझने में कोई बाधा नहीं है।


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

4

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

जब एल्गोरिथ्म कठिन होता है तो आप परिणाम की मैन्युअल गणना को आसान बनाने के लिए कई चीजें कर सकते हैं।

  1. एक्सेल का उपयोग करें। एक स्प्रेडशीट सेट करें जो आपके लिए कुछ या सभी गणना करता है। इसे सरल रखें ताकि आप चरणों को देख सकें।

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

  3. स्वच्छता-जांच के लिए कुल संपत्तियों का उपयोग करें। उदाहरण के लिए, मान लें कि आपके पास प्रायिकता कैलकुलेटर है; आप यह नहीं जान सकते कि व्यक्तिगत परिणाम क्या होने चाहिए, लेकिन आप जानते हैं कि इन सभी को 100% तक जोड़ना होगा।

  4. पाशविक बल। एक प्रोग्राम लिखें जो सभी संभावित परिणाम उत्पन्न करता है, और जांचें कि आपके एल्गोरिथ्म में जो भी उत्पन्न होता है, उससे बेहतर कोई नहीं है।


3., कुछ राउंडिंग त्रुटियों के लिए अनुमति दें। यह संभव है कि आपकी कुल राशि 100,000001% या इसी तरह के करीब-लेकिन-सटीक आंकड़े न हो।
फ्लैटर

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

6
@ फ्लेटर आमतौर पर आपके पास अन्य आवश्यकताएं होने के साथ-साथ शुद्धता भी होती है, जो ब्रूट फोर्स से नहीं मिलती है। जैसे प्रदर्शन।
इवान

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

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

2

टी एल; डॉ

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


शुरुआत

एल्गोरिथ्म ( workPerDayउदाहरण के लिए शून्य या नकारात्मक ) द्वारा अस्वीकार किए जाने वाले मामलों का परीक्षण शुरू करें और ऐसे मामले जो तुच्छ हैं (जैसे खाली स्थान tasks)।

उसके बाद, आप पहले सबसे सरल मामलों का परीक्षण करना चाहते हैं। के लिए tasksइनपुट, हम अलग-अलग लंबाई परीक्षण करने के लिए की जरूरत है; यह 0, 1 और 2 तत्वों का परीक्षण करने के लिए पर्याप्त होना चाहिए (2 इस परीक्षण के लिए "कई" श्रेणी से संबंधित है)।

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

तुलनात्मक परीक्षण

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

फ़ॉलबैक

कभी-कभी मुझे युक्ति के अनुरूप चरणों में एक हाथ से गणना परिणाम दिखाने वाली लंबी टिप्पणी का सहारा लेना पड़ता है (ऐसी टिप्पणी आमतौर पर परीक्षण मामले से अधिक लंबी होती है)। सबसे खराब स्थिति तब होती है जब आपको किसी अन्य भाषा में या किसी भिन्न परिवेश के लिए पहले के कार्यान्वयन के साथ संगतता बनाए रखनी होती है। कभी-कभी आपको परीक्षण डेटा को कुछ के साथ लेबल करना होगा /* derived from v2.6 implementation on ARM system */। यह बहुत संतोषजनक नहीं है, लेकिन पोर्टिंग करते समय, या अल्पकालिक बैसाखी के रूप में एक निष्ठा परीक्षण के रूप में स्वीकार्य हो सकता है।

अनुस्मारक

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

अनुभवहीन परिणामों (जैसे फ्लोटिंग-पॉइंट) के लिए एक उपयुक्त "लगभग-बराबर" का उपयोग करना न भूलें।

ओवर-टेस्टिंग से बचें - केवल एक परीक्षण जोड़ें यदि यह किसी चीज़ को कवर करता है (जैसे कि एक सीमा मूल्य) जो अन्य परीक्षणों तक नहीं पहुंचा है।


2

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

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

फिर, स्पष्ट रूप से, किनारे के मामलों में जैसे (आपके उदाहरण में) कार्यों की एक खाली सूची लाएं; इस तरह बातें।

आपका परीक्षण सूट शायद एक विधि के लिए उतना महान नहीं होगा जहां आप आसानी से परिणामों की भविष्यवाणी कर सकते हैं; लेकिन अभी भी 100% बिना किसी परीक्षण सूट (या सिर्फ एक धूम्रपान परीक्षण) से बेहतर है।

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

यदि यह आपके लिए एक नियमित मामला है, तो आपको अपनी आवश्यकताओं के इंजीनियरों के साथ एक अच्छी बात करनी होगी। यदि वे आपकी आवश्यकताओं को इस तरह से तैयार नहीं कर सकते हैं जो आपके लिए जांचना आसान (या हर संभव) है, तो आप कब जानते हैं कि आप समाप्त हो गए हैं?


2

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

मैंने Synthetic Aperture Radar (SAR) का उपयोग करके इमेज प्रोसेसिंग करने के लिए सॉफ्टवेयर (और अच्छी तरह से जांचा) सॉफ्टवेयर लिखा है। यह प्रकृति में वैज्ञानिक / संख्यात्मक है (इसमें बहुत अधिक ज्यामिति, भौतिकी और गणित शामिल है)।

सुझावों की एक जोड़ी (सामान्य वैज्ञानिक / संख्यात्मक परीक्षण के लिए):

1) उलटा उपयोग करें। का क्या fftहै [1,2,3,4,5]? कोई जानकारी नहीं। क्या है ifft(fft([1,2,3,4,5]))? होना चाहिए [1,2,3,4,5](या इसके करीब, फ्लोटिंग पॉइंट त्रुटियां आ सकती हैं)। वही 2 डी केस के लिए जाता है।

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

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

EXPECT_TRUE(register(img1, img2).size() < min(img1.size(), img2.size()))

चूंकि आप केवल ओवरलैपिंग भागों पर पंजीकरण कर सकते हैं, पंजीकृत छवि आपकी छोटी छवि के बराबर या उसके बराबर होनी चाहिए, और यह भी:

scale = 255
EXPECT_PIXEL_EQ_WITH_TOLERANCE(reg(img, img), img, .05*scale)

चूँकि स्वयं के लिए पंजीकृत की गई छवि स्वयं क्लोज़ होनी चाहिए, लेकिन आप एल्गोरिथ्म के कारण हाथ में फ़्लोटिंग पॉइंट एरर्स से थोड़ा अधिक अनुभव कर सकते हैं, इसलिए बस प्रत्येक पिक्सेल की जाँच करें +/- 5% की सीमा पर पिक्सेल ले सकते हैं। (0-255 greyscale है, इमेज प्रोसेसिंग में आम है)। परिणाम कम से कम इनपुट के समान आकार का होना चाहिए।

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

4) अपने RNG के लिए एक यादृच्छिक संख्या के बीज का उपयोग करें।

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

आपका विशेष मामला

1) परीक्षण करें कि एक खाली taskArray रिटर्न 0 (ज्ञात मुखर)।

2) यादृच्छिक इनपुट ऐसी है कि उत्पन्न task.time > 0 , task.due > 0, और task.importance > 0 सभी के लिए task है, और जोर परिणाम से अधिक है 0 (किसी न किसी तरह ज़ोर, यादृच्छिक इनपुट) । आपको पागल होने और यादृच्छिक बीज उत्पन्न करने की आवश्यकता नहीं है, आपका एल्गोरिथ्म बस इतना जटिल नहीं है कि इसे वारंट किया जा सके। वहाँ के बारे में 0 मौका है कि यह भुगतान करेगा: बस परीक्षण सरल रखें।

3) टेस्ट task.importance == 0 सभी task एस के लिए है, तो परिणाम है 0 (ज्ञात जोर)

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

HTH।


1

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

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

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


1

यहाँ कुछ अन्य उत्तर बहुत अच्छे हैं:

  • आधार, किनारे और कोने के मामलों का परीक्षण करें
  • पवित्रता की जाँच करें
  • तुलनात्मक परीक्षण करें

... मैं कुछ अन्य रणनीति जोड़ूंगा:

  • समस्या का विरोध करें।
  • कोड के बाहर एल्गोरिथ्म को साबित करें।
  • परीक्षण करें कि [बाह्य रूप से सिद्ध] एल्गोरिथम को डिजाइन के रूप में लागू किया गया है।

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

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


0

यह कुछ आदर्शवादी उत्तर की तरह लग सकता है लेकिन यह विभिन्न प्रकार के परीक्षण की पहचान करने में मदद करता है।

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

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

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


0

मुझे लगता है कि यह प्रक्रिया का पालन करने के अवसरों पर पूरी तरह से स्वीकार्य है:

  • एक परीक्षण के मामले को डिजाइन करें
  • उत्तर पाने के लिए अपने सॉफ़्टवेयर का उपयोग करें
  • हाथ से उत्तर की जाँच करें
  • एक प्रतिगमन परीक्षण लिखें ताकि भविष्य के सॉफ्टवेयर संस्करण इस उत्तर को देना जारी रखेंगे।

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

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

सिर्फ इसलिए कि आप एक पुस्तक में पढ़ते हैं कि एक विशेष पद्धति पहले परीक्षण मामलों को लिखने के लिए प्रोत्साहित करती है, इसका मतलब यह नहीं है कि आपको हमेशा ऐसा करना होगा। नियम तोड़े जाने हैं।


0

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

मैं अतिरिक्त रूप से क्या करता हूं जो मैंने अन्य उत्तरों में नहीं देखा है, किसी भी तरह से ऑटो-जनरेट टेस्ट करना है:

  1. 'रैंडम' इनपुट
  2. डेटा की श्रेणियों में परिवर्तन
  3. सीमाओं के सेट से परीक्षण मामलों का निर्माण
  4. उपर्युक्त सभी।

उदाहरण के लिए, यदि फ़ंक्शन अनुमत इनपुट रेंज [-1,1] के साथ तीन पैरामीटर लेता है, तो प्रत्येक पैरामीटर के सभी संयोजनों का परीक्षण करें, {-2, -1.01, -1, -0.99, -0.5, -0.01, 0,0.01 , 0.5,0.99,1,1.01,2, (-1,1) में कुछ और यादृच्छिक}

संक्षेप में: कभी-कभी खराब गुणवत्ता को मात्रा द्वारा सब्सिडी दी जा सकती है।

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