अंतर्निहित यादृच्छिक / गैर-नियतात्मक एल्गोरिदम का यूनिट-परीक्षण


41

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

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

क्या किसी के पास परीक्षण के डिजाइन के लिए कोई सुझाव है जो गैर-नियतात्मक व्यवहार की अपेक्षा करनी चाहिए?


सुझाव के लिए सभी को धन्यवाद। मुख्य राय यह प्रतीत होती है कि मुझे नियतात्मक, दोहराव, मुखर परिणाम प्राप्त करने के लिए एक निर्धारक परीक्षा की आवश्यकता है । समझ में आता है।

मैंने "सैंडबॉक्स" परीक्षणों का एक सेट बनाया जिसमें बाधा प्रक्रिया के लिए उम्मीदवार एल्गोरिदम शामिल हैं (एक बाइट सरणी जो किसी भी लंबे समय तक एक मिनट और अधिकतम के बीच हो सकती है)। फिर मैं उस कोड को एक फ़ोर लूप के माध्यम से चलाता हूं जो एल्गोरिथ्म को कई ज्ञात बाइट सरणियाँ देता है (मानों को शुरू करने के लिए 1 से 10,000,000 तक) और एल्गोरिथ्म प्रत्येक को 1009 और 7919 के बीच एक मूल्य के लिए विवश करता है (मैं एक सुनिश्चित करने के लिए अभाज्य संख्याओं का उपयोग कर रहा हूँ एल्गोरिथ्म इनपुट और आउटपुट रेंज के बीच कुछ गंभीर GCF से नहीं गुजरेगा)। परिणामी विवश मूल्यों को गिना जाता है और एक हिस्टोग्राम का उत्पादन किया जाता है। "पास" करने के लिए, सभी इनपुट हिस्टोग्राम के भीतर परिलक्षित होना चाहिए (यह सुनिश्चित करने के लिए कि हमें कोई भी "खोना" नहीं है), और हिस्टोग्राम में किसी भी दो बाल्टी के बीच का अंतर 2 से अधिक नहीं हो सकता है (यह वास्तव में होना चाहिए <= 1 , लेकिन बने रहें)। विजेता एल्गोरिथ्म, यदि कोई हो, को सीधे उत्पादन कोड में काट दिया जा सकता है और प्रतिगमन के लिए एक स्थायी परीक्षण रखा जा सकता है।

यहाँ कोड है:

    private void TestConstraintAlgorithm(int min, int max, Func<byte[], long, long, long> constraintAlgorithm)
    {
        var histogram = new int[max-min+1];
        for (int i = 1; i <= 10000000; i++)
        {
            //This is the stand-in for the PRNG; produces a known byte array
            var buffer = BitConverter.GetBytes((long)i);

            long result = constraintAlgorithm(buffer, min, max);

            histogram[result - min]++;
        }

        var minCount = -1;
        var maxCount = -1;
        var total = 0;
        for (int i = 0; i < histogram.Length; i++)
        {
            Console.WriteLine("{0}: {1}".FormatWith(i + min, histogram[i]));
            if (minCount == -1 || minCount > histogram[i])
                minCount = histogram[i];
            if (maxCount == -1 || maxCount < histogram[i])
                maxCount = histogram[i];
            total += histogram[i];
        }

        Assert.AreEqual(10000000, total);
        Assert.LessOrEqual(maxCount - minCount, 2);
    }

    [Test, Explicit("sandbox, does not test production code")]
    public void TestRandomizerDistributionMSBRejection()
    {
        TestConstraintAlgorithm(1009, 7919, ConstrainByMSBRejection);
    }

    private long ConstrainByMSBRejection(byte[] buffer, long min, long max)
    {
        //Strip the sign bit (if any) off the most significant byte, before converting to long
        buffer[buffer.Length-1] &= 0x7f;
        var orig = BitConverter.ToInt64(buffer, 0);
        var result = orig;
        //Apply a bitmask to the value, removing the MSB on each loop until it falls in the range.
        var mask = long.MaxValue;
        while (result > max - min)
        {
            mask >>= 1;
            result &= mask;
        }
        result += min;

        return result;
    }

    [Test, Explicit("sandbox, does not test production code")]
    public void TestRandomizerDistributionLSBRejection()
    {
        TestConstraintAlgorithm(1009, 7919, ConstrainByLSBRejection);
    }

    private long ConstrainByLSBRejection(byte[] buffer, long min, long max)
    {
        //Strip the sign bit (if any) off the most significant byte, before converting to long
        buffer[buffer.Length - 1] &= 0x7f;
        var orig = BitConverter.ToInt64(buffer, 0);
        var result = orig;

        //Bit-shift the number 1 place to the right until it falls within the range
        while (result > max - min)
            result >>= 1;

        result += min;
        return result;
    }

    [Test, Explicit("sandbox, does not test production code")]
    public void TestRandomizerDistributionModulus()
    {
        TestConstraintAlgorithm(1009, 7919, ConstrainByModulo);
    }

    private long ConstrainByModulo(byte[] buffer, long min, long max)
    {
        buffer[buffer.Length - 1] &= 0x7f;
        var result = BitConverter.ToInt64(buffer, 0);

        //Modulo divide the value by the range to produce a value that falls within it.
        result %= max - min + 1;

        result += min;
        return result;
    }

... और यहाँ परिणाम है:

यहाँ छवि विवरण दर्ज करें

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

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

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


2
तो, आखिरकार, आप एक प्रोग्राम चाहते हैं जो एक यादृच्छिक संख्या जनरेटर के आउटपुट को देखता है और यह तय करता है कि क्या यह यादृच्छिक है? जैसा कि "5,4,10,31,120,390,2,3,4" यादृच्छिक था, लेकिन "49,39,1,10,103,12,4,189" नहीं था?
psr

नहीं, लेकिन वास्तविक PRNG और अंतिम परिणाम के बीच पूर्वाग्रह को पेश करने से बचना अच्छा होगा।
कीथ्स

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

आपको संयोजनों के लिए भी परीक्षण करना चाहिए। लगभग प्रति घंटे के बराबर अपेक्षित निरीक्षण होने पर, उस मामले से बचाव नहीं होगा, जहां कहें, मंगलवार को सुबह 11 बजे निरीक्षण हमेशा गुरुवार को दोपहर 2 बजे और शुक्रवार को सुबह 10 बजे किया जाता है।
डेविड थॉर्नले

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

जवाबों:


17

आप वास्तव में यहां क्या परीक्षण करना चाहते हैं, मेरा मानना ​​है कि यादृच्छिक संख्या से परिणामों का एक विशिष्ट सेट दिया गया है, आपकी बाकी विधि सही ढंग से निष्पादित करती है।

यदि आप जो खोज रहे हैं, तो वह रैंडमाइज़र का मज़ाक उड़ाता है, इसे परीक्षण के दायरे में नियतात्मक बनाता है।

मेरे पास आम तौर पर GUID जनरेटर और DateTime.Now सहित गैर-निर्धारक या अप्रत्याशित (परीक्षण लिखने के समय) डेटा के लिए सभी प्रकार की वस्तुएं हैं।

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

मैं बाद को पसंद करता हूं क्योंकि यह नहीं टूटेगा अगर PRNG का ढांचा लागू हो जाए। हालांकि, इसे बीज देने का एक फायदा यह है कि अगर आपको उत्पादन में कोई ऐसा मामला मिलता है जो पहले जैसा काम नहीं करता था, तो आपको इसे पूरा करने में सक्षम होने के लिए केवल एक संख्या को लॉग इन करने में सक्षम होना चाहिए।

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


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

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

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

यादृच्छिक अनुक्रमों (सहसंबंध, ब्लॉक-सहसंबंध, औसत, मानक विचलन, आदि) के ठीक से सांख्यिकीय मैट्रिक्स केवल अपेक्षाओं की आपकी सीमा को पूरा करने में विफल होंगे, यदि आप वास्तव में छोटे नमूने करते हैं। अपने सैम्पलिंग सेटों को बढ़ाएँ और / या अपनी अनुमत त्रुटि पट्टियाँ
बढ़ाएँ

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

23

यह एक मूर्खतापूर्ण जवाब की तरह लग रहा है, लेकिन मैं इसे वहां फेंकने जा रहा हूं, क्योंकि मैंने इसे पहले भी देखा है:

PRNG से अपना कोड घटाएं - यादृच्छिककरण बीज का उपयोग कोड के सभी में करें जो यादृच्छिककरण का उपयोग करता है। तब आप एक एकल बीज (या उस के कई बीज आपको बेहतर महसूस करवाएंगे) से 'काम कर' मान निर्धारित कर सकते हैं। यह आपको बड़ी संख्या के कानून पर भरोसा किए बिना अपने कोड का पर्याप्त रूप से परीक्षण करने की क्षमता देगा।

यह अयोग्य लगता है, लेकिन यह है कि सेना यह कैसे करती है (या तो वह या वे एक 'यादृच्छिक तालिका' का उपयोग करते हैं जो वास्तव में यादृच्छिक नहीं है)


बिल्कुल सही: यदि आप एक एल्गोरिथ्म के एक तत्व का परीक्षण नहीं कर सकते हैं, तो इसे अमूर्त करें और इसे मॉक करें
स्टीव ग्रेट्रेक्स

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

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

यह बेवकूफी नहीं है - यह वही तरीका है जो Google अपने पेपर के अनुसार स्पैनर परीक्षणों में विफलता इंजेक्शन को पुन: उत्पन्न करने के लिए उपयोग करता है :)
अक्षत महाजन

6

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

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

विकिपीडिया लेख http://en.wikipedia.org/wiki/Randomness_tests और इसके अनुवर्ती लिंक में अधिक जानकारी है।


यहां तक ​​कि औसत दर्जे के PRNG किसी भी सांख्यिकीय परीक्षणों में कोई पेटेंट नहीं दिखाएंगे। अच्छे PRNGs के लिए उन्हें वास्तविक यादृच्छिक संख्याओं से अलग करना व्यावहारिक रूप से असंभव है।
कोडइन्चोस

4

मेरे पास आपके लिए दो उत्तर हैं।

=== सबसे पहले ===

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

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

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

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


=== दूसरा उत्तर ===

वाह ... क्या मस्त समस्या है!

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

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

  2. अपने एल्गोरिथ्म को एक फ़ंक्शन के रूप में विचार करें जो इनपुट के रूप में सभी आरएनजी आउटपुट का संयोजन लेता है, फिर आउटपुट के रूप में निरीक्षण समय का उत्पादन करता है। यदि आप जानते हैं कि यह फ़ंक्शन लगातार टुकड़ा है, तो आपकी संपत्ति का परीक्षण करने का एक तरीका है। RNG को एक नकली RNG से बदलें और एल्गोरिदम को कई बार चलाएं, समान रूप से वितरित RNG आउटपुट का निर्माण करें। इसलिए यदि आपके कोड में 2 RNG कॉल की आवश्यकता होती है, तो प्रत्येक रेंज में [0..1], आपके पास 100 बार एल्गोरिथ्म चलाने के लिए हो सकता है, मानों को लौटाता है [(0.0,0.0), (0.0,0.1), (0.0) 0.2), ... (0.0,0.9), (0.1,0.0), (0.1,0.1), ... (0.9,0.9)]। तब आप जांच सकते हैं कि 100 रनों का आउटपुट अनुमत सीमा के भीतर समान रूप से वितरित किया गया था या नहीं।

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


3

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

आप नहीं चाहते हैं कि आपकी इकाई परीक्षण उदाहरण के लिए रैंडम.नेक्स्टइंट (१०००) रिटर्न ० या १ ९९९ में हो रही है।


3

आप Sevcikova et al: "स्टोचस्टिक सिस्टम का स्वचालित परीक्षण: एक सांख्यिकीय ग्राउंड दृष्टिकोण" ( PDF ) पर एक नज़र रखना चाहते हैं ।

अर्बनसिम सिमुलेशन प्लेटफॉर्म के लिए विभिन्न परीक्षण मामलों में कार्यप्रणाली को लागू किया गया है।


यह अच्छा सामान है।
कीथ्स

2

एक सरल हिस्टोग्राम दृष्टिकोण एक अच्छा पहला कदम है, लेकिन यादृच्छिकता साबित करने के लिए पर्याप्त नहीं है। एक समान PRNG के लिए आप (बहुत कम से कम) भी 2-आयामी स्कैटर प्लॉट उत्पन्न करेंगे (जहाँ x पिछला मान है और y नया मान है)। यह प्लॉट भी एक समान होना चाहिए। यह आपकी स्थिति में जटिल है क्योंकि सिस्टम में जानबूझकर गैर-रैखिकताएं हैं।

मेरा दृष्टिकोण होगा:

  1. सत्यापित करें (या दिए गए रूप में लें) कि स्रोत PRNG पर्याप्त रूप से यादृच्छिक है (मानक सांख्यिकीय उपायों का उपयोग करके)
  2. सत्यापित करें कि आउटपुट स्थान पर एक अप्रशिक्षित PRNG-से-डेटाइम रूपांतरण पर्याप्त रूप से यादृच्छिक है (यह रूपांतरण में पूर्वाग्रह की कमी की पुष्टि करता है)। आपका सरल प्रथम-क्रम एकरूपता परीक्षण यहाँ पर्याप्त होना चाहिए।
  3. सत्यापित करें कि विवश मामले पर्याप्त रूप से एक समान हैं (वैध डिब्बे पर एक साधारण प्रथम-क्रम एकरूपता परीक्षण)।

इन परीक्षणों में से प्रत्येक सांख्यिकीय है और आत्मविश्वास की उच्च डिग्री के साथ झूठी सकारात्मक और गलत नकारात्मक से बचने के लिए बड़ी संख्या में नमूना बिंदुओं की आवश्यकता होती है।

रूपांतरण / बाधा एल्गोरिथम की प्रकृति के अनुसार:

दिया गया: छद्म-यादृच्छिक मान p उत्पन्न करने की विधि जहाँ 0 <= p <= M

आवश्यकता: उत्पादन में y (संभवतः बंद) श्रेणी 0 <= y <= N <= M

कलन विधि:

  1. गणना करें r = floor(M / N), अर्थात संपूर्ण आउटपुट रेंज की संख्या जो इनपुट रेंज के भीतर फिट होती है।
  2. p के लिए अधिकतम स्वीकार्य मान की गणना करें :p_max = r * N
  3. p के लिए मान तब तक उत्पन्न करें जब तक कि उससे कम या उसके बराबर मान न p_maxमिल जाए
  4. calculate y = p / r
  5. यदि y स्वीकार्य है, तो उसे वापस कर दें, अन्यथा चरण 3 के साथ दोहराएं

कुंजी गैर-समान रूप से तह करने के बजाय अस्वीकार्य मूल्यों को त्यागने के लिए है।

छद्म कोड में:

# assume prng generates non-negative values
def randomInRange(min, max, prng):
    range = max - min
    factor = prng.max / range

    do:
        value = prng()
    while value > range * factor
    return (value / factor) + min

def constrainedRandom(constraint, prng):
    do:
        value = randomInRange(constraint.min, constraint.max, prng)
    while not constraint.is_acceptable(value)

1

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


1

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


लेकिन अगर यह वास्तव में यादृच्छिक है, तो कभी-कभी, कुछ शेड्यूल का उपयोग नहीं किया जाएगा; और कभी-कभी, कुछ शेड्यूल का 20 से अधिक बार उपयोग किया जाएगा। मैं नहीं जानता कि आप कैसे परीक्षण करना चाहते हैं कि प्रत्येक शेड्यूल का उपयोग "10 बार के करीब" किया जाता है, लेकिन जो भी स्थिति आप यहाँ परीक्षण करते हैं, आपके पास एक परीक्षण होगा जो कभी-कभी विफल रहता है जब प्रोग्राम कल्पना करने के लिए काम कर रहा होता है।
दाऊद का कहना है कि मोनिका

एक पर्याप्त नमूना आकार (और एकरूपता पर उचित सीमा) के साथ @DawoodibnKareem आप अरबों में परीक्षण विफल होने की संभावना को कम कर सकते हैं। और आम तौर पर इस तरह के आंकड़े n के साथ घातांक होते हैं इसलिए आपको उन नंबरों की अपेक्षा कम समय लगता है।
मलबिग

1

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

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


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

0

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


0

यह मामला संपत्ति आधारित परीक्षण के लिए आदर्श लगता है ।

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

यहाँ sumफ़ंक्शन का परीक्षण कर रहा है (गूंगा, विफल) उदाहरण :

@given(lists(floats()))
def test_sum(alist):
    result = sum(alist)
    assert isinstance(result, float)
    assert result > 0
  • परीक्षण रूपरेखा एक समय में एक सूची उत्पन्न करेगी
  • सूची की सामग्री फ़्लोटिंग पॉइंट संख्या होगी
  • sum कहा जाता है और परिणाम के गुणों को मान्य किया जाता है
  • परिणाम हमेशा फ्लोट होता है
  • परिणाम सकारात्मक है

इस परीक्षण में "बग" का एक गुच्छा मिलेगा sum(टिप्पणी करें यदि आप इन सभी का अनुमान लगाने में सक्षम थे ):

  • sum([]) is 0 (int, फ्लोट नहीं)
  • sum([-0.9]) नकारात्मक है
  • sum([0.0]) सख्ती से सकारात्मक नहीं है
  • sum([..., nan]) is nan जो सकारात्मक नहीं है

डिफ़ॉल्ट सेटिंग्स के साथ, hpythesis1 "खराब" इनपुट पाए जाने के बाद परीक्षण को रद्द कर देता है, जो टीडीडी के लिए अच्छा है। मुझे लगा कि कई / सभी "खराब" इनपुटों की रिपोर्ट करने के लिए इसे कॉन्फ़िगर करना संभव है, लेकिन मुझे अब वह विकल्प नहीं मिल रहा है।

ओपी मामले में, मान्य की गई संपत्तियां अधिक जटिल होंगी: निरीक्षण प्रकार ए वर्तमान, निरीक्षण प्रकार एक सप्ताह में तीन बार, निरीक्षण समय बी हमेशा दोपहर 12 बजे, निरीक्षण प्रकार सी 9 से 9 तक, [दिया गया शेड्यूल एक सप्ताह के लिए होता है] प्रकारों का निरीक्षण ए, बी, सी सभी उपस्थित हैं, आदि।

सबसे प्रसिद्ध पुस्तकालय है QuickCheck हास्केल के लिए, अन्य भाषाओं में इस तरह के पुस्तकालयों के एक सूची के लिए नीचे विकिपीडिया पृष्ठ देखें:

https://en.wikipedia.org/wiki/QuickCheck

इस तरह के परीक्षण के बारे में परिकल्पना (अजगर के लिए) का अच्छा लेखन है:

https://hypothesis.works/articles/what-is-property-based-testing/


-1

क्या आप इकाई परीक्षण कर सकते हैं, यह निर्धारित करने के लिए तर्क है कि क्या यादृच्छिक तिथियां वैध हैं या यदि किसी अन्य यादृच्छिक तिथि का चयन करने की आवश्यकता है।

रैंडम डेट जेनरेटर का परीक्षण करने का कोई तरीका नहीं है, जो तारीखों का एक समूह हो और यह तय कर सके कि क्या वे उपयुक्त रूप से यादृच्छिक हैं।


-1

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

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

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


नहीं, बस नहीं। इकाई परीक्षण साबित करते हैं कि कार्यक्रम अपनी आवश्यकताओं को पूरा करता है, इसलिए दोनों एक और एक ही हैं। और मैं रिवर्स-इंजीनियर यादृच्छिक एल्गोरिदम के लिए भविष्य कहनेवाला सॉफ्टवेयर लिखने के व्यवसाय में नहीं हूं। अगर मुझे लगता है कि मैं आपको इसके बारे में नहीं बताऊंगा, तो मैं उनकी चाबियों की भविष्यवाणी करके और सबसे अधिक बोली लगाने वाले के लिए रहस्यों को बेचकर एक सुरक्षित क्रैकिंग वेबसाइट बनाऊंगा। मेरा व्यवसाय एक अनुसूचक लिख रहा है जो कई बार ऐसा बनाता है जो विवश हैं, लेकिन बाधाओं के भीतर अप्रत्याशित हैं, और मुझे यह साबित करने के लिए नियतात्मक परीक्षणों की आवश्यकता है कि मैंने ऐसा किया है, न कि संभाव्य लोगों का कहना है कि मुझे पूरा यकीन है।
कीथ्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.