यूनिट परीक्षण कैसे काम करता है?


23

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

public class TestAdder {
    public void testSum() {
        Adder adder = new AdderImpl();
        assert(adder.add(1, 1) == 2);
        assert(adder.add(1, 2) == 3);
        assert(adder.add(2, 2) == 4);
        assert(adder.add(0, 0) == 0);
        assert(adder.add(-1, -2) == -3);
        assert(adder.add(-1, 1) == 0);
        assert(adder.add(1234, 988) == 2222);
    }
}

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

assert(adder.add(a, b) == (a+b));

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


14
How does unit testing work?कोई भी वास्तव में जानता है :)
yannis

30
"आपको वांछित परिणाम को मैन्युअल रूप से गणना करने की आवश्यकता है"। वह "पूरी तरह से बेकार" कैसे है? आप कैसे कह सकते हैं कि उत्तर सही है?
एस.लॉट

9
@ एस.लॉट: इसे प्रगति कहा जाता है, प्राचीन काल में लोग संख्याओं को कम करने के लिए कंप्यूटर का इस्तेमाल करते थे और समय की बचत करते थे, आधुनिक दिनों में लोग यह सुनिश्चित करने के लिए समय बिताते हैं कि कंप्यूटर संख्याओं में कमी कर सकते हैं: D
कोडर

2
@ कोडर: यूनिट परीक्षण का उद्देश्य "संख्याओं को कम करना और समय की बचत करना नहीं है";)
एंड्रेस एफ। 19

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

जवाबों:


26

यूनिट परीक्षण, यदि आप छोटी पर्याप्त इकाइयों का परीक्षण कर रहे हैं, तो हमेशा स्पष्ट रूप से स्पष्ट रूप से जोर दे रहे हैं।

कारण यह है कि add(x, y)यहां तक कि एक इकाई परीक्षण का भी उल्लेख किया गया है, क्योंकि कुछ समय बाद कोई व्यक्ति जाएगा addऔर विशेष टैक्स लॉजिक हैंडलिंग कोड को यह एहसास नहीं कराएगा कि ऐड हर जगह उपयोग किया जाता है।

इकाई परीक्षण साहचर्य सिद्धांत के बारे में बहुत अधिक हैं: यदि ए बी करता है, और बी सी करता है, तो ए सी करता है। "ए डू सी" उच्च स्तर का परीक्षण है। उदाहरण के लिए, निम्नलिखित पर विचार करें, पूरी तरह से वैध व्यापार कोड:

public void LoginUser (string username, string password) {
    var user = db.FetchUser (username);

    if (user.Password != password)
        throw new Exception ("invalid password");

    var roles = db.FetchRoles (user);

    if (! roles.Contains ("member"))
        throw new Exception ("not a member");

    Session["user"] = user;
}

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

public void LoginUser (string username, string password) {

    var user = _userRepo.FetchValidUser (username, password);

    _rolesRepo.CheckUserForRole (user, "member");

    _localStorage.StoreValue ("user", user);
}

अब हम इकाइयों के लिए नीचे हैं। एक इकाई परीक्षण इस बात की परवाह नहीं करता है कि इसके _userRepoलिए मान्य व्यवहार को क्या माना जाता है FetchValidUser, केवल इसे ही कहा जाता है। आप यह सुनिश्चित करने के लिए किसी अन्य परीक्षण का उपयोग कर सकते हैं कि एक वैध उपयोगकर्ता क्या बनाता है। इसी तरह CheckUserForRole... भूमिका संरचना कैसी दिखती है, यह जानने से आपने अपने परीक्षण को अस्वीकृत कर दिया है। आपने अपने पूरे कार्यक्रम को सख्ती से बांधने से भी रोक दिया है Session। मुझे लगता है कि सभी लापता टुकड़े यहाँ दिखेंगे:

class UserRepository : IUserRepository
{
    public User FetchValidUser (string username, string password)
    {
        var user = db.FetchUser (username);

        if (user.Password != password)
            throw new Exception ("invalid password");

        return user;
    }
}

class RoleRepository : IRoleRepository
{
    public void CheckUserForRole (User user, string role)
    {
        var roles = db.FetchRoles (user);

        if (! roles.Contains (role))
            throw new Exception ("not a member");
    }
}

class SessionStorage : ILocalStorage
{
    public void StoreValue (string key, object value)
    {
        Session[key] = value;
    }
}

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

उम्मीद है की यह मदद करेगा :)


13

मैं वर्तमान में ज्यादातर "प्रक्रियात्मक" कार्यों को कोडित कर रहा हूं जो ~ 10 बूलियन और कुछ ints लेते हैं और मुझे इस पर आधारित एक अंतर परिणाम देते हैं, मुझे लगता है कि मैं केवल एक इकाई परीक्षण कर सकता हूं जो परीक्षण में एल्गोरिथ्म को फिर से कोड करना होगा

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


मौजूदा कोड चलाने और परिणाम रिकॉर्ड करने के लिए +1। इस स्थिति में, यह संभवतः व्यावहारिक दृष्टिकोण है।
MarkJ

12

चूंकि किसी और ने वास्तविक उदाहरण नहीं दिया है:

    public void testRoman() {
        RomanNumeral numeral = new RomanNumeral();
        assert( numeral.toRoman(1) == "I" )
        assert( numeral.toRoman(4) == "IV" )
        assert( numeral.toRoman(5) == "V" )
        assert( numeral.toRoman(9) == "IX" )
        assert( numeral.toRoman(10) == "X" )
    }
    public void testSqrt() {
        assert( sqrt(4) == 2 )
        assert( sqrt(9) == 3 )
    }

तुम कहो:

मुझे लगता है कि यह परीक्षण पूरी तरह से बेकार है, क्योंकि आपको वांछित परिणाम की मैन्युअल रूप से गणना करने और उसका परीक्षण करने की आवश्यकता है

लेकिन मुद्दा यह है कि जब आप मैन्युअल गणना करते हैं तो कोडिंग करते समय आपसे गलती होने की संभावना बहुत कम होती है (या अपनी गलतियों को नोटिस करने की संभावना कम से कम)।

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

स्क्वायर रूट फ़ंक्शन को लागू करते समय आपसे गलती होने की कितनी संभावना है? बहुत संभावना है। हाथ से एक वर्गमूल की गणना करते समय आप कितनी गलती करते हैं? शायद अधिक संभावना है। लेकिन sqrt के साथ, आप उत्तर प्राप्त करने के लिए एक कैलकुलेटर का उपयोग कर सकते हैं।

FYI करें मैं वर्तमान में ज्यादातर "प्रक्रियात्मक" कार्यों को कोडित कर रहा हूं जो ~ 10 बूलियन और कुछ इन्टल्स लेते हैं और मुझे इस पर आधारित एक अंतर परिणाम देते हैं, मुझे लगता है कि मैं केवल एक इकाई परीक्षण कर सकता हूं जो कि एल्गोरिथ्म में बस फिर से कोड करने के लिए होगा परीक्षा

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

कुंजी यह है कि आप सही आउटपुट ढूंढना चाहते हैं। लेकिन आपको सही होने के लिए उन आउटपुट का परीक्षण करना होगा जो कुछ ज्ञात हैं। इसकी गणना करने के लिए अपना स्वयं का एल्गोरिथ्म लिखने के लिए अच्छा नहीं है क्योंकि यह बहुत अच्छी तरह से गलत हो सकता है। इस मामले में मूल्यों को मैन्युअल रूप से गणना करना बहुत कठिन है।

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

यदि आपने वास्तविक कोड दिखाया है तो आप समस्या के बारे में अधिक विस्तृत प्रतिक्रिया दे सकते हैं।


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

11

मुझे लगता है कि मैं केवल एक इकाई परीक्षण कर सकता हूं जो कि परीक्षण में एल्गोरिदम को फिर से कोड करना होगा

आप इस तरह के एक साधारण वर्ग के लिए लगभग सही हैं।

इसे और अधिक जटिल कैलकुलेटर के लिए आज़माएं .. एक गेंदबाजी स्कोर कैलकुलेटर की तरह।

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

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


4
नोटिंग के लिए +1 यह जटिल कार्यों के लिए अधिक उपयोगी है। क्या होगा यदि आपने फ़्लोटिंग पॉइंट मानों में adder.add () को विस्तारित करने का निर्णय लिया है? मैट्रिसेस? बड़ा खाता मान?
joshin4colours

6

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

मैं वर्तमान में ज्यादातर "प्रक्रियात्मक" कार्यों को कोडित कर रहा हूं जो ~ 10 बूलियन और कुछ ints लेते हैं और इसके आधार पर मुझे एक परिणाम देते हैं

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

मुझे अपने OO में जाने की आवश्यकता नहीं है प्रक्रियात्मक प्रोग्रामिंग से बेहतर है ...


इस मामले में विधि का "हस्ताक्षर" बड़े पैमाने पर नहीं है, मैं सिर्फ एक std :: वेक्टर <bool> से पढ़ता हूं जो एक वर्ग सदस्य है। मुझे यह भी बताना चाहिए कि मैं पोर्ट कर रहा हूँ (संभवतः बुरी तरह से डिज़ाइन किया गया) रूबी कोड (जो मैंने नहीं बनाया)
lezebulon

2
@lezebulon भले ही अगर उस एकल विधि को स्वीकार करने के लिए कई संभावित इनपुट हैं तो वह विधि बहुत अधिक कर रही है
maple_shaft

3

मेरे विचार में इकाई परीक्षण आपके छोटे योजक वर्ग पर भी उपयोगी हैं: एल्गोरिथ्म को "रीकोड" करने के बारे में न सोचें और इसके बारे में एक ब्लैक बॉक्स के रूप में सोचें, जिसमें आपके पास एकमात्र ज्ञान है कार्यात्मक व्यवहार (यदि आप परिचित हैं) तेज़ गुणा के साथ आप कुछ तेज़ी से जानते हैं, लेकिन "a * b") और आपके सार्वजनिक इंटरफ़ेस का उपयोग करने की तुलना में जटिल प्रयास करते हैं। आपको अपने आप से पूछना चाहिए "क्या गलत हो सकता है?" ...

अधिकांश मामलों में यह सीमा पर होता है (मैं देखता हूं कि आप पहले से ही इन पैटर्नों को जोड़कर परीक्षण ++, -, + -, 00 - समय - इनको पूरा करने के लिए - +, 0+, 0-, +0, -0) करते हैं। वहाँ जोड़ने या घटाने (नकारात्मक जोड़ने;) पर MAX_INT और MIN_INT पर क्या होता है, इसके बारे में सोचें। या यह सुनिश्चित करने की कोशिश करें कि आपके परीक्षण बिल्कुल वही दिखते हैं जो शून्य पर और उसके आसपास होता है।

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

अपने परीक्षण वर्गों के लिए संकेत: एक विधि में केवल एक मुखर लिखने की कोशिश करें। तरीके अच्छे नाम (उदाहरण के लिए "testAddingToMaxInt", "testAddingTwoNegatives") दें, जब कोड परिवर्तन के बाद आपका परीक्षण विफल हो जाए, तो सर्वोत्तम प्रतिक्रिया दें।


2

मैन्युअल रूप से गणना किए गए रिटर्न मान के लिए परीक्षण करने के बजाय, या अपेक्षित रिटर्न मान की गणना करने के लिए परीक्षण में तर्क की नकल करके, अपेक्षित संपत्ति के लिए वापसी मूल्य का परीक्षण करें।

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

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


2

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

I feel that this test is totally useless, because you are required to manually compute the wanted result and test it, I feel like a better unit test here would be

एक मूट प्वाइंट। उदाहरण में परीक्षण से पता चलता है कि कैसे एक कक्षा को तुरंत किया जाए और इसे कई परीक्षणों के माध्यम से चलाया जाए। एकल कार्यान्वयन के minutia पर ध्यान देना पेड़ों के लिए जंगल को याद कर रहा है।

Can someone provide me with an example where unit testing is actually useful?

आपके पास एक कर्मचारी इकाई है। इकाई में एक नाम और पता होता है। क्लाइंट एक ReportTo फ़ील्ड जोड़ने का निर्णय लेता है।

void TestBusinessLayer()
{
   int employeeID = 1234
   Employee employee = Employee.GetEmployee(employeeID)
   BusinessLayer bl = new BusinessLayer()
   Assert.isTrue(bl.Add(employee))//assume Add returns true on pass
}

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

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

I feel like the only unit testing I could do would be to simply re-code the algorithm in the test.

यहां तक ​​कि प्रक्रियात्मक तर्क भी आसानी से एक समारोह के अंदर समझाया जाता है। परीक्षण / (मॉक ऑब्जेक्ट) के लिए इंटिमेट / प्रिमिटिव में एनकैप्सुलेट, तत्काल और पास। एक यूनिट टेस्ट में कोड को कॉपी पेस्ट न करें। जो DRY को हरा देता है। यह परीक्षण को पूरी तरह से हरा देता है क्योंकि आप कोड का परीक्षण नहीं कर रहे हैं, लेकिन कोड की एक प्रति। यदि कोड जिसे परिवर्तनों का परीक्षण किया जाना चाहिए था, परीक्षण अभी भी गुजरता है!


<पेडैंट्री> "गेमट", "
गैम्बिट

@ चाओ लोल हर दिन कुछ नया सीखते हैं।
पी। ब्रायन। मैके

2

अपना उदाहरण लेते हुए (थोड़ा सा प्रतिशोध के साथ),

assert(a + b, math.add(a, b));

इससे मदद नहीं मिलती:

  • समझें कि math.addआंतरिक रूप से कैसे व्यवहार किया जाता है,
  • जानते हैं कि किन मामलों के साथ क्या होगा।

यह कहना बहुत सुंदर है:

  • आप को पता है कि विधि करता चाहते हैं, जाने के लिए और स्रोत कोड की लाइनों के सैकड़ों देख अपने आप को (क्योंकि हाँ, math.add कर सकते हैं एलओसी के सैकड़ों शामिल, नीचे देखें)।
  • मैं यह जानने की जहमत नहीं उठाता कि विधि सही ढंग से काम करती है या नहीं। यह ठीक है अगर मैं उम्मीद और वास्तविक मूल्य दोनों से अलग हूं जो मैंने वास्तव में उम्मीद की थी

इसका मतलब यह भी है कि आपको परीक्षण नहीं जोड़ना है:

assert(3, math.add(1, 2));
assert(4, math.add(2, 2));

वे न तो मदद करते हैं, न ही कम से कम, एक बार जब आपने पहला दावा किया, तो दूसरा उपयोगी नहीं है।

इसके बजाय, इसके बारे में:

const numeric Pi = 3.1415926535897932384626433832795;
const numeric Expected = 4.1415926535897932384626433832795;
assert(Expected, math.add(Pi, 1),
    "Adding an integer to a long numeric doesn't give a long numeric result.");
assert(Expected, math.add(1, Pi),
    "Adding a long numeric to an integer doesn't give a long numeric result.");

यह आत्म-व्याख्यात्मक है और आपके लिए और बाद में स्रोत कोड बनाए रखने वाले व्यक्ति के लिए दोनों के लिए उपयोगी है। कल्पना करें कि यह व्यक्ति math.addकोड को सरल बनाने और प्रदर्शन को अनुकूलित करने के लिए एक मामूली संशोधन करता है , और परीक्षा परिणाम को देखता है जैसे:

Test TestNumeric() failed on assertion 2, line 5: Adding a long numeric to an
integer doesn't give a long numeric result.

Expected value: 4.1415926535897932384626433832795
Actual value: 4

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

उसी तरह, 4.141592पहले दावे पर वास्तविक मूल्य प्राप्त करना स्वयं-व्याख्यात्मक है: आप जानते हैं कि विधि एक बड़ी सटीकता से निपटने की उम्मीद है , लेकिन वास्तव में, यह विफल रहता है।

एक ही कारण के लिए, निम्नलिखित दो दावे कुछ भाषाओं में समझ सकते हैं:

// We don't expect a concatenation. `math` library is not intended for this.
assert(0, math.add("Hello", "World"));

// We expect the method to convert every string as if it was a decimal.
assert(5, math.add("0x2F", 5));

इसके अलावा, किस बारे में:

assert(numeric.Infinity, math.add(numeric.Infinity, 1));

आत्म-व्याख्यात्मक भी: आप चाहते हैं कि आपकी विधि अनन्तता से सही तरीके से निपटने में सक्षम हो। जा रहे हैं अनंत से परे या एक अपवाद फेंक एक अपेक्षित व्यवहार नहीं है।

या हो सकता है, आपकी भाषा के आधार पर, यह अधिक समझ में आएगा?

/**
 * Ensures that when adding numbers which exceed the maximum value, the method
 * fails with OverflowException, instead of restarting at numeric.Minimum + 1.
 */
TestOverflow()
{
    UnitTest.ExpectException(ofType(OverflowException));

    numeric result = math.add(numeric.Maximum, 1));

    UnitTest.Fail("The tested code succeeded, while an OverflowException was
        expected.");
}

1

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

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

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


1

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


0

शायद आप जोड़ते हैं () ADD निर्देश के साथ लागू किया गया था। यदि कुछ जूनियर प्रोग्रामर या हार्डवेयर इंजीनियर ने ANDS / ORS / XORS, बिट इनवर्ट्स और शिफ्ट्स का उपयोग करके ऐड () फ़ंक्शन को फिर से लागू किया है, तो आप ADD इंस्ट्रक्शन के खिलाफ इसे टेस्ट कर सकते हैं।

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


0

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

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

यहीं से आपके यूनिट टेस्ट वास्तव में अपने में आते हैं।

आप अपने कोड के आंतरिक कार्यान्वयन को बदल सकते हैं लेकिन उस कोड के किसी भी उपभोक्ता को, परिणाम समान रहता है।

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