Database
 sql >> डेटाबेस >  >> RDS >> Database

पुरानी परियोजना में टीडीडी लागू करने के नियम

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

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

प्रस्तावना

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

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

नियम 1:बॉटम-अप (इनसाइड-आउट) का उपयोग करना

यह नियम एक कार्यशील प्रोजेक्ट में कोड के नए टुकड़े एम्बेड करते समय विश्लेषण और सॉफ़्टवेयर डिज़ाइन की विधि को संदर्भित करता है।

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

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

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

नियम 2:केवल संशोधित कोड का परीक्षण करें

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

उदाहरण

एक ऑनलाइन-स्टोर मॉड्यूल है, जो चयनित वस्तुओं का कार्ट बनाता है और इसे डेटाबेस में संग्रहीत करता है। हम विशिष्ट कार्यान्वयन की परवाह नहीं करते हैं। हो गया के रूप में किया - यह विरासत कोड है। अब हमें यहां एक नया व्यवहार पेश करने की आवश्यकता है:कार्ट की लागत $1000 से अधिक होने की स्थिति में लेखा विभाग को एक सूचना भेजें। यहां वह कोड है जिसे हम देखते हैं। परिवर्तन का परिचय कैसे दें?

public class EuropeShop : Shop
{
    public override void CreateSale()
    {
        var items = LoadSelectedItemsFromDb();
        var taxes = new EuropeTaxes();
        var saleItems = items.Select(item => taxes.ApplyTaxes(item)).ToList();
        var cart = new Cart();
        cart.Add(saleItems);
        taxes.ApplyTaxes(cart);
        SaveToDb(cart);
    }
}

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

public class EuropeShop : Shop
{
    public override void CreateSale()
    {
        var items = LoadSelectedItemsFromDb();
        var taxes = new EuropeTaxes();
        var saleItems = items.Select(item => taxes.ApplyTaxes(item)).ToList();
        var cart = new Cart();
        cart.Add(saleItems);
        taxes.ApplyTaxes(cart);

        // NEW FEATURE
        new EuropeShopNotifier().Send(cart);

        SaveToDb(cart);
    }
}

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

नियम 3:हम केवल आवश्यकताओं का परीक्षण करते हैं

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

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

उदाहरण

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

public class EuropeShop : Shop
{
    public override void CreateSale()
    {
        // 1) load from DB
        var items = LoadSelectedItemsFromDb();

        // 2) Tax-object creates SaleItem and
        // 4) goes through items and apply taxes
        var taxes = new EuropeTaxes();
        var saleItems = items.Select(item => taxes.ApplyTaxes(item)).ToList();

        // 3) creates a cart and 4) applies taxes
        var cart = new Cart();
        cart.Add(saleItems);
        taxes.ApplyTaxes(cart);

        new EuropeShopNotifier().Send(cart);

        // 4) store to DB
        SaveToDb(cart);
    }
}

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

public class EuropeShop : Shop
{
    public override void CreateSale()
    {
        // 1) extracted to a repository
        var itemsRepository = new ItemsRepository();
        var items = itemsRepository.LoadSelectedItems();
			
        // 2) extracted to a mapper
        var saleItems = items.ConvertToSaleItems();
			
        // 3) still creates a cart
        var cart = new Cart();
        cart.Add(saleItems);
			
        // 4) all routines to apply taxes are extracted to the Tax-object
        new EuropeTaxes().ApplyTaxes(cart);
			
        new EuropeShopNotifier().Send(cart);
			
        // 5) extracted to a repository
        itemsRepository.Save(cart);
    }
}

परीक्षणों के लिए, ये परिदृश्य पर्याप्त होंगे। अब तक, उनके कार्यान्वयन में हमें कोई दिलचस्पी नहीं है।

public class EuropeTaxesTests
{
    public void Should_not_fail_for_null() { }

    public void Should_apply_taxes_to_items() { }

    public void Should_apply_taxes_to_whole_cart() { }

    public void Should_apply_taxes_to_whole_cart_and_change_items() { }
}

public class EuropeShopNotifierTests
{
    public void Should_not_send_when_less_or_equals_to_1000() { }

    public void Should_send_when_greater_than_1000() { }

    public void Should_raise_exception_when_cannot_send() { }
}

नियम 4:केवल परीक्षित कोड जोड़ें

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

स्प्राउट मेथड/क्लास - यह तकनीक आपको एक बहुत ही सुरक्षित नए कोड को पुराने कोड में एम्बेड करने की अनुमति देती है। जिस तरह से मैंने नोटिफ़ायर को जोड़ा, वह इस दृष्टिकोण का एक उदाहरण है।

रैप विधि - थोड़ी अधिक जटिल, लेकिन सार वही है। यह हमेशा काम नहीं करता है, लेकिन केवल उन मामलों में जहां पुराने कोड के पहले/बाद में एक नया कोड कहा जाता है। जिम्मेदारियों को निर्दिष्ट करते समय, ApplyTaxes पद्धति की दो कॉलों को एक कॉल से बदल दिया गया था। इसके लिए दूसरे तरीके को बदलना जरूरी था ताकि लॉजिक ज्यादा न टूटे और उसे चेक किया जा सके। परिवर्तनों से पहले कक्षा इस तरह दिखती थी।

public class EuropeTaxes : Taxes
{
    internal override SaleItem ApplyTaxes(Item item)
    {
        var saleItem = new SaleItem(item)
        {
            SalePrice = item.Price*1.2m
        };
        return saleItem;
    }

    internal override void ApplyTaxes(Cart cart)
    {
        if (cart.TotalSalePrice <= 300m) return;
        var exclusion = 30m/cart.SaleItems.Count;
        foreach (var item in cart.SaleItems)
            if (item.SalePrice - exclusion > 100m)
                item.SalePrice -= exclusion;
    }
}

और यहाँ यह कैसा दिखता है। गाड़ी के तत्वों के साथ काम करने का तर्क थोड़ा बदल गया, लेकिन सामान्य तौर पर, सब कुछ वैसा ही रहा। इस मामले में, पुरानी विधि पहले एक नए ApplyToItems को कॉल करती है, और फिर इसके पिछले संस्करण को। यही इस तकनीक का सार है।

public class EuropeTaxes : Taxes
{
    internal override void ApplyTaxes(Cart cart)
    {
        ApplyToItems(cart);
        ApplyToCart(cart);
    }

    private void ApplyToItems(Cart cart)
    {
        foreach (var item in cart.SaleItems)
            item.SalePrice = item.Price*1.2m;
    }

    private void ApplyToCart(Cart cart)
    {
        if (cart.TotalSalePrice <= 300m) return;
        var exclusion = 30m / cart.SaleItems.Count;
        foreach (var item in cart.SaleItems)
            if (item.SalePrice - exclusion > 100m)
                item.SalePrice -= exclusion;
    }
}

नियम 5:छिपी निर्भरता को "तोड़ें"

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

सबसे पहले, आपको सभी निर्भरताओं के आरंभीकरण को कंस्ट्रक्टर को स्थानांतरित करना होगा। विशेष रूप से, यह नए . पर लागू होता है ऑपरेटरों और वर्गों का निर्माण। यदि आपके पास कक्षाओं के उदाहरण प्राप्त करने के लिए ServiceLocator है, तो आपको इसे कंस्ट्रक्टर को भी हटा देना चाहिए, जहां आप इससे सभी आवश्यक इंटरफेस निकाल सकते हैं।

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

तीसरा, बड़ी विधि शीट न छोड़ें। यह स्पष्ट रूप से दर्शाता है कि विधि अपने नाम में निर्दिष्ट से अधिक करती है। यह सॉलिड, डेमेटर के नियम के संभावित उल्लंघन का भी संकेत है।

उदाहरण

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

public class EuropeShop : Shop
{
    private readonly IItemsRepository _itemsRepository;
    private readonly Taxes.Taxes _europeTaxes;
    private readonly INotifier _europeShopNotifier;

    public EuropeShop()
    {
        _itemsRepository = new ItemsRepository();
        _europeTaxes = new EuropeTaxes();
        _europeShopNotifier = new EuropeShopNotifier();
    }

    public override void CreateSale()
    {
        var items = _itemsRepository.LoadSelectedItems();
        var saleItems = items.ConvertToSaleItems();

        var cart = new Cart();
        cart.Add(saleItems);

        _europeTaxes.ApplyTaxes(cart);
        _europeShopNotifier.Send(cart);
        _itemsRepository.Save(cart);
    }
}SCRIPT

नियम 6:जितने कम बड़े परीक्षण, उतने बेहतर

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

यह समझना आवश्यक है कि किन परीक्षणों की आवश्यकता है और इस समझ का स्पष्ट रूप से पालन करें। यदि आपको एकीकरण जांच की आवश्यकता है, तो सकारात्मक और नकारात्मक इंटरैक्शन परिदृश्यों सहित परीक्षणों का एक न्यूनतम सेट लिखें। यदि आपको एल्गोरिथम का परीक्षण करने की आवश्यकता है, तो यूनिट परीक्षणों का एक न्यूनतम सेट लिखें।

नियम 7:निजी तरीकों का परीक्षण न करें

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

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

उदाहरण

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

public class EuropeTaxes : Taxes
{
    // code skipped

    private void ApplyToCart(Cart cart)
    {
        if (cart.TotalSalePrice <= 300m) return; // <<< I WANT TO TEST THIS CONDIFTION
        var exclusion = 30m / cart.SaleItems.Count;
        foreach (var item in cart.SaleItems)
            if (item.SalePrice - exclusion > 100m)
                item.SalePrice -= exclusion;
    }
}

// test suite
public class EuropeTaxesTests
{
    // code skipped

    [Fact]
    public void Should_apply_taxes_to_cart_greater_300()
    {
        #region arrange
        // list of items which will create a cart greater 300
        var saleItems = new List<Item>(new[]{new Item {Price = 83.34m},
            new Item {Price = 83.34m},new Item {Price = 83.34m}})
            .ConvertToSaleItems();
        var cart = new Cart();
        cart.Add(saleItems);

        const decimal expected = 83.34m*3*1.2m;
        #endregion

        // act
        new EuropeTaxes().ApplyTaxes(cart);

        // assert
        Assert.Equal(expected, cart.TotalSalePrice);
    }
}

नियम 8:विधियों के एल्गोरिथम का परीक्षण न करें

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

और पढ़ें…

नियम 9:परीक्षण के बिना लीगेसी कोड को संशोधित न करें

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

यदि आप टीडीडी का उपयोग करने जा रहे हैं, तो अपनी टीम के साथ इस पर चर्चा करें, इसे पूर्ण की परिभाषा में जोड़ें, और इसे लागू करें। सबसे पहले, यह कठिन होगा, जैसे सब कुछ नया। किसी भी कला की तरह, टीडीडी को निरंतर अभ्यास की आवश्यकता होती है, और जब आप सीखते हैं तो आनंद आता है। धीरे-धीरे, अधिक लिखित इकाई परीक्षण होंगे, आप अपने सिस्टम के "स्वास्थ्य" को महसूस करना शुरू कर देंगे और पहले चरण में आवश्यकताओं का वर्णन करते हुए कोड लिखने की सादगी की सराहना करना शुरू कर देंगे। Microsoft और IBM में वास्तविक बड़ी परियोजनाओं पर TDD अध्ययन किए गए हैं, जो उत्पादन प्रणालियों में त्रुटियों को 40% से 80% तक कम दिखाते हैं (नीचे दिए गए लिंक देखें)।

आगे पढ़ना

  1. माइकल फेदर्स द्वारा "लीगेसी कोड के साथ प्रभावी ढंग से कार्य करना" पुस्तक
  2. टीडीडी जब लीगेसी कोड में आपकी गर्दन तक हो
  3. छिपी हुई निर्भरता को तोड़ना
  4. विरासत कोड जीवनचक्र
  5. क्या आपको किसी कक्षा में निजी विधियों का परीक्षण करना चाहिए?
  6. इकाई परीक्षण आंतरिक
  7. टीडीडी और यूनिट टेस्ट के बारे में 5 आम गलतफहमियां
  8. डेमेटर का नियम

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. टी-एसक्यूएल में किसी तिथि में दिन कैसे जोड़ें

  2. Dundas BI में QuickBooks डेटा का विश्लेषण करना

  3. शीर्ष / शीर्ष अवरोही माध्यिका समाधान में सुधार

  4. स्केलग्रिड शीर्ष 100 क्लाउड सेवा प्रदाताओं में स्थान पर है

  5. शुद्ध नहीं करने की कीमत