2008-09-20 10 views
22

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

लेकिन फ़ाइल संशोधित फ़ाइल मेरे डेस्कटॉप बॉक्स पर मौजूद नहीं हो सकती है। और शायद मैं इसे अपने डेस्कटॉप पर संशोधित नहीं करना चाहता हूं।

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

हालांकि, हमारे मामले में, हमें यह जांचने की आवश्यकता है कि कार्यक्रम अपने पर्यावरण को सही ढंग से संशोधित कर रहा है। यहां मैं ये आया हूं:

1) मानक स्थान में "मूल" फ़ाइल बनाएं, शायद/tmp।

2) फ़ाइल को संशोधित करने वाले फ़ंक्शन को चलाएं, इसे फ़ाइल में/tmp में पथ से गुजरना।

3) सत्यापित करें कि फ़ाइल में/tmp सही ढंग से बदला गया था; तदनुसार पास/असफल इकाई परीक्षण।

यह मुझे लगता है कि यह मुझे लगता है। (अगर आप यह सत्यापित करना चाहते हैं कि फाइल की बैकअप प्रतियां ठीक से बनाई गई हैं, तो भी क्लेजियर प्राप्त करें आदि) क्या कोई बेहतर तरीके से आ गया है?

उत्तर

14

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

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

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

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

आप पुनरावृत्ति कार्यों को आसान बनाने के लिए परीक्षण टूल भी बना सकते हैं। उदाहरण के लिए, ट्विस्ट built right into its testing tool परीक्षण के लिए अस्थायी फ़ाइलों को बनाने के लिए सुविधाएं प्रदान करता है। उपकरण या बड़ी परियोजनाओं के परीक्षण के लिए यह असामान्य नहीं है कि इस तरह की कार्यक्षमता रखने के लिए अपने स्वयं के परीक्षण पुस्तकालयों के साथ।

2

जब मैं अपने कोड में फ़ाइलों को स्पर्श करता हूं, तो मैं फ़ाइल के वास्तविक पढ़ने और लिखने का मज़ाक उड़ाता हूं ... इसलिए मैं अपनी कक्षाओं को सटीक सामग्री दे सकता हूं जो मैं परीक्षण में चाहता हूं, और फिर परीक्षण करें मैं जिस सामग्री की अपेक्षा करता हूं उसे वापस लिख रहा हूं।

मैंने जावा में यह किया है, और मुझे लगता है कि यह पायथन में काफी सरल है ... लेकिन इसे आपके वर्ग/कार्यों को इस तरह से डिजाइन करने की आवश्यकता हो सकती है कि वास्तविक फ़ाइल के उपयोग को नकल करना आसान हो।

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

1

मुझे लगता है कि आप सही रास्ते पर हैं। chroot आपको जो करने की आवश्यकता है उसके आधार पर आप अपने स्क्रिप के लिए वातावरण स्थापित करने में मदद कर सकते हैं जो वास्तविक दिखता है, लेकिन नहीं।

यदि यह काम नहीं करता है तो आप एक तर्क के रूप में 'रूट' पथ लेने के लिए अपनी स्क्रिप्ट लिख सकते हैं।

एक उत्पादन में रूट रूट बस/है। परीक्षण के लिए आप/shmp/test के अंतर्गत एक छाया वातावरण बनाते हैं और फिर अपनी स्क्रिप्ट को रूट/tmp/test के रूट पथ से चलाते हैं।

7

आपके पास परीक्षण के दो स्तर हैं।

  1. सामग्री फ़िल्टर और संशोधित करना। ये "निम्न-स्तर" संचालन हैं जिन्हें वास्तव में भौतिक फ़ाइल I/O की आवश्यकता नहीं होती है। ये परीक्षण, निर्णय लेने, विकल्प इत्यादि हैं। आवेदन के "तर्क"।

  2. फ़ाइल सिस्टम संचालन। बनाएं, कॉपी करें, नाम बदलें, हटाएं, बैकअप लें। क्षमा करें, लेकिन वे उचित फ़ाइल सिस्टम ऑपरेशंस हैं - अच्छी तरह से - परीक्षण के लिए एक उचित फ़ाइल सिस्टम की आवश्यकता है।

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

फिर आप एक मॉकफाइल सिस्टम बना सकते हैं जो विभिन्न परिचालनों को खत्म कर देता है। आप अपने अन्य वर्गों का परीक्षण करने के लिए इस मॉक ऑब्जेक्ट का उपयोग कर सकते हैं।

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

अपने मॉकोस मॉड्यूल को PYTHONPATH पर रखें और आप वास्तविक ओएस मॉड्यूल को छुपा सकते हैं।

उत्पादन के संचालन के लिए आप अपनी अच्छी तरह से परीक्षण किया "तर्क" वर्गों के साथ साथ अपने FileSystemOperations क्लास का उपयोग (या वास्तविक ओएस मॉड्यूल।)

1

सेट करने के लिए परीक्षण चाहते हो सकता है इतना है कि यह एक सीएचरूट ​​जेल के अंदर चलाता है, तो आपके पास परीक्षण की ज़रूरत वाले सभी पर्यावरण हैं, भले ही पथ और फ़ाइल स्थानों को कोड में हार्डकोड किया गया हो [वास्तव में एक अच्छा अभ्यास नहीं है, लेकिन कभी-कभी किसी को अन्य स्थानों से फ़ाइल स्थान मिलते हैं ...] और फिर बाहर निकलने वाले कोड के माध्यम से परिणाम जांचें ।

3

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

def fake_open(module): 
    """Patch module's `open` builtin so that it returns StringIOs instead of 
    creating real files, which is useful for testing. Returns a dict that maps 
    opened file names to StringIO objects.""" 
    from contextlib import closing 
    from StringIO import StringIO 
    streams = {} 
    def fakeopen(filename,mode): 
     stream = StringIO() 
     stream.close = lambda: None 
     streams[filename] = stream 
     return closing(stream) 
    module.open = fakeopen 
    return streams