2008-08-10 9 views
8

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

उत्तर

5

सबसे पहले, here's a great article with tips on unit testing। दूसरा, मुझे पुराने कोड में कई बदलाव करने से बचने का एक शानदार तरीका मिल गया है, जब तक कि आप इसका परीक्षण नहीं कर लेते, इसे थोड़ा सा रिफैक्टर करें। ऐसा करने का एक आसान तरीका निजी सदस्यों को सुरक्षित बनाना है, और फिर संरक्षित क्षेत्र को ओवरराइड करना है।

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

public class MyClass { 
    public MyClass() { 
     // undesirable DB logic 
    } 
} 

public class MyClass { 
    public MyClass() { 
     loadFromDB(); 
    } 

    protected void loadFromDB() { 
     // undesirable DB logic 
    } 
} 

हो जाता है और फिर अपने परीक्षण इस तरह दिखता है:

public class MyClassTest { 
    public void testSomething() { 
     MyClass myClass = new MyClassWrapper(); 
     // test it 
    } 

    private static class MyClassWrapper extends MyClass { 
     @Override 
     protected void loadFromDB() { 
      // some mock logic 
     } 
    } 
} 

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

यदि आप एक ढांचा लिख ​​रहे हैं, तो मैं इस समाधान के खिलाफ अनुशंसा करता हूं, जब तक कि आप वास्तव में सदस्यों को अपने ढांचे के उपयोगकर्ताओं को उजागर नहीं करते।

यह एक हैक का थोड़ा सा है, लेकिन मुझे यह काफी उपयोगी पाया गया है।

0

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

यदि आप जावा लिख ​​रहे हैं (संभावनाएं हैं), http://www.easymock.org/ देखें - परीक्षण उद्देश्यों के लिए युग्मन को कम करने के लिए उपयोगी हो सकता है।

3

@valters

मैं अपने बयान है कि परीक्षण के निर्माण को तोड़ने नहीं करना चाहिए से असहमत हैं। परीक्षण एक संकेत होना चाहिए कि एप्लिकेशन की कार्यक्षमता के लिए नई बग पेश नहीं की गई है (और एक मिली बग एक लापता परीक्षण का संकेत है)।

यदि परीक्षण बिल्ड को तोड़ नहीं देते हैं, तो आप आसानी से उस स्थिति में भाग सकते हैं जहां नया कोड निर्माण को तोड़ देता है और यह थोड़ी देर के लिए ज्ञात नहीं है, भले ही एक परीक्षण इसे कवर करता है। एक असफल परीक्षण लाल झंडा होना चाहिए कि या तो परीक्षण या कोड को ठीक किया जाना चाहिए।

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

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

मुझे दृढ़ विश्वास है कि एक असफल परीक्षण ASAP को ठीक किया जाना चाहिए, जैसे आप ASAP संकलित करने में विफल होने वाले कोड को ठीक करेंगे।

0

मैंने विरासत संहिता के साथ प्रभावी ढंग से कार्य पढ़ा है, और मैं मानता हूं कि यह "अवांछित" कोड से निपटने के लिए बहुत उपयोगी है।

कुछ तकनीकें केवल संकलित भाषाओं पर लागू होती हैं (मैं "पुराने" PHP ऐप्स पर काम कर रहा हूं), लेकिन मैं कहूंगा कि अधिकांश पुस्तक किसी भी भाषा पर लागू होती है।

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

मुझे यह उल्लेख करना चाहिए कि मुझे संपादक से कोई पैसा नहीं मिला है और न ही इस पुस्तक के लेखक;), लेकिन मुझे यह बहुत दिलचस्प लगता है, क्योंकि विरासत कोड (और विशेष रूप से मेरी भाषा में संसाधनों की कमी है) फ्रेंच, लेकिन यह एक और कहानी है)।

संबंधित मुद्दे