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