वैज्ञानिक सॉफ्टवेयर के लिए निरंतर एकीकरण


22

मैं कोई सॉफ्टवेयर इंजीनियर नहीं हूँ। मैं जियोसाइंस के क्षेत्र में एक पीएचडी छात्र हूं।

लगभग दो साल पहले मैंने एक वैज्ञानिक सॉफ्टवेयर की प्रोग्रामिंग शुरू की। मैंने कभी भी निरंतर एकीकरण (CI) का उपयोग नहीं किया, मुख्यतः क्योंकि पहले मुझे नहीं पता था कि यह मौजूद है और मैं इस सॉफ्टवेयर पर काम करने वाला एकमात्र व्यक्ति था।

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

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

मेरे पास कुछ सवाल हैं जहां मैं कुछ सलाह लेना चाहूंगा:

सबसे पहले सॉफ्टवेयर कैसे काम करता है की एक छोटी व्याख्या:

  • सॉफ्टवेयर सभी आवश्यक सेटिंग्स युक्त एक .xml फ़ाइल द्वारा नियंत्रित किया जाता है। आप केवल एक इनपुट तर्क के रूप में .xml फ़ाइल के लिए पथ पास करके सॉफ़्टवेयर प्रारंभ करते हैं और यह परिणामों के साथ कुछ फ़ाइलों को चलाता है और बनाता है। एक सिंगल रन में ~ 30 सेकंड लग सकते हैं।

  • यह एक वैज्ञानिक सॉफ्टवेयर है। लगभग सभी कार्यों में कई इनपुट पैरामीटर होते हैं, जिनके प्रकार ज्यादातर वर्ग होते हैं जो काफी जटिल होते हैं। मेरे पास बड़ी कैटलॉग के साथ कई .txt फाइलें हैं जो इन वर्गों के उदाहरण बनाने के लिए उपयोग की जाती हैं।

अब चलिए मेरे सवालों पर आते हैं:

  1. इकाई परीक्षण, एकीकरण परीक्षण, एंड-टू-एंड परीक्षण? : मेरा सॉफ्टवेयर अब सैकड़ों कार्यों और ~ 80 कक्षाओं के साथ कोड की लगभग 30.000 पंक्तियाँ है। यह सैकड़ों तरह के कार्यों के लिए यूनिट परीक्षण लिखना शुरू करने के लिए मुझे अजीब लगता है जो पहले से ही लागू हैं। इसलिए मैंने केवल कुछ परीक्षण मामलों को बनाने के बारे में सोचा। 10-20 अलग .xml फाइलें तैयार करें और सॉफ्टवेयर को चलने दें। मुझे लगता है कि इसे एंड-टू-एंड टेस्ट कहा जाता है? मैं अक्सर पढ़ता हूं कि आपको ऐसा नहीं करना चाहिए, लेकिन शायद यह एक शुरुआत के रूप में ठीक है अगर आपके पास पहले से ही एक काम करने वाला सॉफ्टवेयर है? या यह केवल एक गूंगा विचार है कि सीआई को पहले से काम कर रहे सॉफ़्टवेयर में जोड़ने का प्रयास किया जाए।

  2. यदि आप फ़ंक्शन पैरामीटर बनाना मुश्किल है, तो आप यूनिट टेस्ट कैसे लिखेंगे? मान लें कि मेरे पास एक फ़ंक्शन है double fun(vector<Class_A> a, vector<Class_B>)और आमतौर पर, मुझे पहले प्रकार की वस्तुओं को बनाने के लिए कई पाठ फ़ाइलों में पढ़ने की आवश्यकता होती है Class_Aऔर Class_B। मैंने कुछ डमी फ़ंक्शंस बनाने के बारे में सोचा जैसे Class_A create_dummy_object()बिना टेक्स्ट फ़ाइलों में पढ़े। मैंने कुछ प्रकार के क्रमांकन को लागू करने के बारे में भी सोचा । (मैं वर्ग वस्तुओं के निर्माण का परीक्षण करने की योजना नहीं बनाता क्योंकि वे केवल कई पाठ फ़ाइलों पर निर्भर करते हैं)

  3. यदि परिणाम अत्यधिक परिवर्तनशील हैं तो परीक्षण कैसे लिखें? मेरा सॉफ्टवेयर बड़े मोंटे-कार्लो सिमुलेशन का उपयोग करता है और पुनरावृति से काम करता है। आमतौर पर, आपके पास ~ 1000 पुनरावृत्तियों और प्रत्येक पुनरावृत्ति पर, आप मोंटे-कार्लो सिमुलेशन के आधार पर वस्तुओं के ~ 500-20.000 उदाहरण बना रहे हैं। यदि केवल एक पुनरावृत्ति का एक परिणाम थोड़ा भिन्न होता है तो आगामी आगामी पुनरावृत्तियां पूरी तरह से भिन्न होती हैं। आप इस स्थिति से कैसे निपटेंगे? मुझे लगता है कि एंड-टू-एंड परीक्षणों के खिलाफ यह एक बड़ा बिंदु है, क्योंकि अंतिम परिणाम अत्यधिक परिवर्तनशील है?

CI के साथ किसी भी अन्य सलाह की बहुत सराहना की जाती है।



1
आपको कैसे पता चलेगा कि आपका सॉफ्टवेयर सही तरीके से काम कर रहा है? क्या आप उस चेक को स्वचालित करने का एक तरीका खोज सकते हैं ताकि आप इसे हर बदलाव पर चला सकें? किसी मौजूदा प्रोजेक्ट में CI को पेश करते समय यह आपका पहला कदम होना चाहिए।
बार्ट वैन इनगेन शानौ

आपने यह कैसे सुनिश्चित किया कि आपका सॉफ़्टवेयर पहली बार में स्वीकार्य परिणाम तैयार करे? क्या आपको यकीन है कि यह वास्तव में "काम करता है"? दोनों प्रश्नों के उत्तर आपको अपने सॉफ़्टवेयर को अभी और भविष्य में परीक्षण करने के लिए पर्याप्त सामग्री देंगे।
पॉलीग्नोम

जवाबों:


23

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

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

  • सी के rand()फ़ंक्शन का उपयोग करते समय यह भूलना आसान है जो वैश्विक स्थिति पर निर्भर करता है।
  • आदर्श रूप से, एक यादृच्छिक संख्या जनरेटर को आपके कार्यों के माध्यम से एक स्पष्ट वस्तु के रूप में पारित किया जाता है। C ++ 11 का randomमानक लाइब्रेरी हेडर इसे बहुत आसान बनाता है।
  • सॉफ्टवेयर के मॉड्यूल में यादृच्छिक स्थिति को साझा करने के बजाय, मैंने दूसरा RNG बनाने के लिए उपयोगी पाया है जो कि पहले RNG से एक यादृच्छिक संख्या के आधार पर लिया गया है। फिर, यदि अन्य मॉड्यूल द्वारा RNG के लिए अनुरोधों की संख्या में परिवर्तन होता है, तो पहले RNG द्वारा उत्पन्न अनुक्रम समान रहता है।

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

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

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

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

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

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


7

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

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

यदि आप फ़ंक्शन पैरामीटर बनाना मुश्किल है, तो आप यूनिट टेस्ट कैसे लिखेंगे?

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

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

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

यदि परिणाम अत्यधिक परिवर्तनशील हैं तो परीक्षण कैसे लिखें?

सुझावों की एक जोड़ी:

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

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

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

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

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

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

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

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

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

HTH।


2
  1. परीक्षण के प्रकार

    • यह सैकड़ों तरह के कार्यों के लिए इकाई परीक्षण लिखना शुरू करने के लिए मुझे अजीब लगता है जो पहले से ही लागू हैं

      इसे दूसरे तरीके से सोचें: यदि कई कार्य स्पर्श करने वाला एक पैच आपके एंड-टू-एंड परीक्षणों में से एक को तोड़ता है, तो आप यह कैसे पता लगाने जा रहे हैं कि समस्या किसकी है?

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

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

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

    • हाँ, CI को मौजूदा सॉफ़्टवेयर में जोड़ना समझदारी और सामान्य है।

  2. यूनिट टेस्ट कैसे लिखें

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

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

  3. परिवर्तनशील परिणाम

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

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


1
  1. यह सीआई को जोड़ने के लिए एक गूंगा विचार नहीं है। अनुभव से मुझे पता है कि यह एक ऐसा तरीका है जब आपके पास एक ओपन सोर्स प्रोजेक्ट है जहां लोग योगदान देने के लिए स्वतंत्र हैं। सीआई आपको कोड जोड़ने या बदलने से लोगों को रोकने की अनुमति देता है यदि कोड आपके प्रोग्राम को तोड़ता है, तो यह एक कामकाजी कोडबेस होने में लगभग अमूल्य है।

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

  2. परीक्षण वस्तु निर्माण वास्तव में काफी कठिन और कठिन है। आप डमी ऑब्जेक्ट बनाना चाहते हैं। इन वस्तुओं में कुछ डिफ़ॉल्ट होना चाहिए, लेकिन किनारे का मामला, मूल्य जिनके लिए आप निश्चित रूप से जानते हैं कि आउटपुट क्या होना चाहिए।

  3. इस विषय के बारे में पुस्तकों के साथ समस्या यह है कि CI का परिदृश्य (और अन्य भागों में) इतनी तेज़ी से विकसित होता है कि पुस्तक में कुछ भी संभवत: कुछ महीनों बाद पुराना हो जाएगा। मुझे ऐसी किसी किताब की जानकारी नहीं है जो आपकी मदद कर सके, लेकिन Google को हमेशा की तरह आपका उद्धारकर्ता होना चाहिए।

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

कुछ सुझाव:

  • अपने GIT प्लेटफ़ॉर्म में CI टूल के एकीकरण का उपयोग करके टूटे हुए कोड को अपने कोडबेस में जाने से रोकें।
  • अन्य डेवलपर्स द्वारा सहकर्मी-समीक्षा करने से पहले कोड को रोकना। यह त्रुटियों को अधिक आसानी से ज्ञात करता है और फिर से टूटे हुए कोड को आपके कोडबेस में प्रवेश करने से रोकता है।

1

इससे पहले की उत्तर में आमोन पहले से ही कुछ बहुत ही महत्वपूर्ण बिंदुओं का उल्लेख किया। मुझे कुछ और जोड़ने दें:

1. वैज्ञानिक सॉफ्टवेयर और वाणिज्यिक सॉफ्टवेयर के विकास के बीच अंतर

वैज्ञानिक सॉफ्टवेयर के लिए, सामान्य रूप से वैज्ञानिक समस्या पर ध्यान केंद्रित किया जाता है। समस्याएं सैद्धांतिक पृष्ठभूमि को अधिक संभाल रही हैं, सर्वोत्तम संख्यात्मक विधि ढूंढना आदि, सॉफ्टवेयर केवल एक, कम या ज्यादा, काम का छोटा हिस्सा है।

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

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

यदि आप अपनी परियोजना को व्यावसायिक सॉफ़्टवेयर के समान सॉफ़्टवेयर में बदलना चाहते हैं, तो आपको निम्नलिखित की जाँच करनी चाहिए:

  • आपके पास समय और संसाधन हैं?
  • सॉफ्टवेयर का दीर्घकालिक परिप्रेक्ष्य क्या है? जब आप अपना काम पूरा कर लेंगे और विश्वविद्यालय छोड़ रहे हैं तो सॉफ्टवेयर के साथ क्या होगा?

2. परीक्षण समाप्त करने के लिए अंत

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

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

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

उदाहरणों में आपके सॉफ़्टवेयर के विशिष्ट परिणाम शामिल होने चाहिए। इसमें आपके पैरामीटर स्थान और संख्यात्मक एल्गोरिदम के किनारे के मामले भी शामिल होने चाहिए।

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

3. निरंतर एकीकरण

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

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

मुझे नहीं लगता है कि यह एक अच्छा विचार है कि निरंतर एकीकरण के लिए किसी प्रकार का स्वचालितवाद है।

वैसे, क्या आप एक संस्करण नियंत्रण प्रणाली का उपयोग कर रहे हैं?

4. अपने संख्यात्मक एल्गोरिदम का परीक्षण करना

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

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

आप उन परीक्षणों को अपने परीक्षण कोड में कर सकते हैं और अपने उत्पादन कोड के लिए सबसे तेज़ एल्गोरिथम का उपयोग कर सकते हैं।


0

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

उस ने कहा, जो मूल्यवान है वह है:

  • एल्गोरिथ्म के संदर्भ में, क्या यह उस समय की सबसे अच्छी विधि है?
  • विभिन्न कम्प्यूट प्लेटफॉर्म (विभिन्न एचपीसी वातावरण, ओएस फ्लेवर आदि) को पोर्ट करना कितना आसान है
  • मजबूती - क्या यह मेरे डेटासेट पर चलती है?

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

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