मैं यूनिट टेस्ट में समानता के लिए दोहरे मूल्यों की ठीक से तुलना कैसे कर सकता हूं?


20

मैंने हाल ही में एक समय श्रृंखला मॉड्यूल तैयार किया है, जहां मेरा समय श्रृंखला अनिवार्य रूप से एक है SortedDictionnary<DateTime, double>

अब मैं यह सुनिश्चित करने के लिए इकाई परीक्षण बनाना चाहूंगा कि यह मॉड्यूल हमेशा काम कर रहा है और अपेक्षित परिणाम उत्पन्न कर रहा है।

एक सामान्य ऑपरेशन समय श्रृंखला में बिंदुओं के बीच प्रदर्शन की गणना करना है।

इसलिए मैं क्या करता हूं, {1.0, 2.0, 4.0} (कुछ तिथियों पर) के साथ एक समय श्रृंखला बनाएं, और मुझे परिणाम की उम्मीद है कि {100%, 100%}।

बात यह है, अगर मैं मैन्युअल रूप से मान {1.0, 1.0} के साथ एक समय श्रृंखला बनाता हूं और मैं समानता (प्रत्येक बिंदु की तुलना करके) की जांच करता हूं, तो परीक्षण पास नहीं होगा, क्योंकि वास्तविक बाइनरी अभ्यावेदन के साथ काम करने पर हमेशा अशुद्धि रहेगी संख्या।

इसलिए, मैंने निम्नलिखित फ़ंक्शन बनाने का निर्णय लिया:

private static bool isCloseEnough(double expected, double actual, double tolerance=0.002)
{
    return squaredDifference(expected, actual) < Math.Pow(tolerance,2);
}

क्या इस तरह के मामले से निपटने का एक और सामान्य तरीका है?

जवाबों:


10

मैं इस समस्या से निपटने के दो अन्य तरीकों के बारे में सोच सकता हूं:

आप उपयोग कर सकते हैं Is.InRange:

Assert.That(result, Is.InRange(expected-tolerance, expected+tolerance));

आप उपयोग कर सकते हैं Math.Round:

Assert.That(Math.Round(result, sigDigits), Is.EqualTo(expected));

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


2
बस ध्यान दें कि यह उत्तर NUnit विशिष्ट है और "कांस्ट्रिंग-आधारित" जोर मॉडल दिखाता है। क्लासिक अभिकथन मॉडल जैसा दिखेगा: Assert.AreEqual (अपेक्षित, वास्तविक, सहिष्णुता);
रिचर्ड फेम

1
@RichardM: उत्तर के रूप में पोस्ट करें और मैं इसे स्वीकार करने का चयन करूंगा।
एसआरकेएक्स

@Dasblinkenlight का उत्तर सही है, बस कुछ विवरण जोड़ना (क्योंकि यह स्पष्ट नहीं हो सकता है - क्लासिक जोर मॉडल भी NUnit है)। फ्लोटिंग पॉइंट वैल्यू से निपटने के लिए अन्य टेस्ट फ्रेमवर्क (MSTest नहीं) के अपने-अपने मुखर मॉडल हैं।
रिचर्डएम

1
Assert.That(result, Is.InRange(expected-tolerance, expected+tolerance));विफल हो जाएगा अगर tolerance/abs(expected) < 1E-16
मात्रा_देव

@quant_dev आप बिल्कुल सही हैं। चूंकि ओपी प्रतिशत के रूप में रिटर्न की गणना करने के बारे में बात करता है, इसलिए मैंने माना कि abs(expected)यह दोहरे अंकों में एकल होगा। मैंने 1E-9 के आसपास के क्षेत्र में सहिष्णुता को भी ग्रहण किया। इन मान्यताओं के तहत यह सादगीपूर्ण दृष्टिकोण आपको यथोचित सेवा दे सकता है (मैं Is.InRangeअपने परीक्षणों में उपयोग करता हूं)।
dasblinkenlight

6

जैसा कि रिचर्डएम ने सुझाव दिया था, यदि आप NUnit का उपयोग नहीं करते हैं, तो सबसे अच्छा तरीका Assert.AreEqual (डबल, डबल, डबल) का उपयोग करना प्रतीत होता है , जहां अंतिम एक सटीक है।


3

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

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