2010-02-17 8 views
9

मेरे पास दो फ़ंक्शन हैं- एक जो फाइलों के सेट के लिए पथ बनाता है और अन्य जो फ़ाइलों को पढ़ता है। नीचे दो कार्य हैं:यूनिट परीक्षण फ़ंक्शन जो फ़ाइलों को एक्सेस करते हैं

def pass_file_name(self): 
    self.log_files= [] 
    file_name = self.path+"\\access_"+self.appliacation+".log" 
    if os.path.isfile(file_name): 
     self.log_files.append(file_name) 
    for i in xrange(7): 
     file_name = self.path+"\\access_"+self.appliacation+".log"+"."+str(i+1) 
     if os.path.isfile(file_name): 
      self.log_files.append(file_name) 
    return self.log_files 


def read_log_files (self, log_file_names): 
    self.log_entrys = [] 
    self.log_line = [] 
    for i in log_file_names: 
     self.f = open(i) 
     for line in self.f: 
      self.log_line = line.split(" ") 
      #print self.log_line 
      self.log_entrys.append(self.log_line) 
    return self.log_entrys 

क्या इकाई परीक्षण इन दोनों कार्यों के लिए सबसे अच्छा तरीका क्या होगा?

उत्तर

8

आप दो इकाइयों यहाँ हैं:

  • एक यह है कि फ़ाइल पथ
  • दूसरा कि उन्हें पढ़ता

दो प्रकार होना चाहिए इकाई-परीक्षण मामलों (यानी वर्गों के साथ उत्पन्न परीक्षण)। पहले केवल फाइल पथ पीढ़ी का परीक्षण करेंगे। दूसरा परीक्षण निर्देशिका की विशेष उपनिर्देशिका में तैयार की गई फ़ाइलों के पूर्वनिर्धारित सेट से पढ़ने का परीक्षण करेगा, इसे पहले टेस्ट केस से अलगाव में परीक्षण करना चाहिए।

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

from cStringIO import StringIO 

# ... 
def test_some_log_reading_scenario(self): 
    log1 = '\n'.join([ 
     'log line', 
     'another log line' 
    ]) 
    log2 = '\n'.join([ 
     'another log another line', 
     'lala blah blah' 
    ]) 
    # ... 
    result = myobj.read_log_files([StringIO(log1), StringIO(log2)]) 
    # assert result 
+1

"... इसलिए यह फ़ाइल नाम या फ़ाइल जैसी वस्तु ले सकता है" मैं यह कैसे कर सकता हूं? Str (एक फ़ाइल नाम) के उदाहरण के लिए जांचें, अन्यथा मान लें कि यह एक आईओ ऑब्जेक्ट है? – Symmitchry

1

मॉड्यूल में open नाम को उस फ़ाइल में खोलें जो फ़ाइल खोलने से मेल खाता है।

+0

खेद पूरी तरह से नया। मैं इसे कैसे करूं? फाइल खोलने का मज़ाक उड़ाते हुए? –

+0

एक फ़ाइल जैसी वस्तु लिखें जो आपके कोड द्वारा आवश्यक विभिन्न 'फ़ाइल' विधियों को लागू करती है, फिर बस अपने' fake_open() 'फ़ंक्शन से एक उदाहरण लौटाएं। मॉड्यूल आयात करें फिर 'somemodule।खुला = fake_open'। –

2

व्यक्तिगत रूप से, मैं एक परीक्षण दोहन का निर्माण करता हूं जो उन दो कार्यों का परीक्षण करने से पहले आवश्यक फ़ाइलों को स्थापित करता है।

प्रत्येक टेस्ट केस के लिए (जहां आप फ़ाइल मौजूद होने की उम्मीद करते हैं - असफलता मामलों का भी परीक्षण करना याद रखें!), उचित नामित फ़ाइलों में कुछ ज्ञात लॉग लिखें; फिर परीक्षण के तहत कार्यों को कॉल करें और परिणामों की जांच करें।

2

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

def pass_file_name(base_filename, exists): 
    """return a list of filenames that exist 
     based upon `base_filename`. 
     use `os.path.isfile` for `exists`""" 

    log_files = [] 
    if exists(base_filename): 
     log_files.append(base_filename) 
    for i in range(1, 8): 
     filename = base_filename + "." + str(i) 
     if exists(filename): 
      log_files.append(filename) 
    return log_files 

def read_log_files (self, log_files): 
    """read and parse each line from log_files 
     use `pass_file_name` for `log_files`""" 

    log_entrys = [] 
    for filename in log_files: 
     with open(filename) as myfile: 
      for line in myfile: 
       log_entrys.append(line.split()) 
    return log_entrys 

अब हम आसानी से exists के लिए एक कस्टम समारोह में पारित करके pass_file_name परीक्षण कर सकते हैं।

class Test_pass_file_name(unittest.TestCase): 
    def test_1(self): 
     """assume every file exists 
      make sure all logs file are there""" 
     exists = lambda _: True 
     log_files = pass_file_name("a", exists) 
     self.assertEqual(log_files, 
        ["a", "a.1", "a.2", "a.3", 
        "a.4", "a.5", "a.6", "a.7"]) 

    def test_2(self): 
     """assume no files exists 
      make sure nothing returned""" 
     exists = lambda _: False 
     log_files = pass_file_name("a", exists) 
     self.assertEqual(log_files, []) 

    # ...more tests here ... 

हम os.path.isfile काम करता है मान लेते हैं जैसा कि हम पहले समारोह की बहुत अच्छी परीक्षण मिल गया है चाहिए। यद्यपि आप हमेशा परीक्षण कर सकते हैं वास्तव में कुछ फाइलें बनाते हैं तो pass_file_nameexists = os.path.isfile पर कॉल करें।

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

How do I mock an open used in a with statement (using the Mock framework in Python)?

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