2013-05-16 15 views
2

我有一個解析CSV,XLS,HTML等不同文件格式的模塊。
不同的格式包含完全相同的信息,所以我做了不同的類來解析不同的文件類型。這些類具有完全相同的公共API,顯然具有相同的基類是這樣的:如何使用python在模塊中使用相同的公共API對每個類進行單元測試?

class BaseParser(object): 
    def countTotalValues(self): 
     pass 

    def countItems(self): 
     pass 

class CSVParser(BaseParser): 
    def __init__(self): 
     """Init data, check for errors, etc..""" 

    def parse(self): 
     """ parses the data and set the result dictionaries like self.values, self.items, etc.""" 

class XLSParser(BaseParser): 
    """ Ha exactly the same public API as CSVParser and set the same inner values. """ 
    pass 

它是在與相同的值一次一個好主意,每個類的單元測試? 我一直在做這樣的:

class TestParserClasses(unittest.TestCase): 
    def setUp(self): 
     self.instances = [] 
     for class_, file_ in PARSER_CLASSES: 
      self.instances.append(class_(file_)) 

    def tearDown(self): 
     del self.instances 

,並定義單元測試是這樣的:

def test_count_total_values_without_parameter(self): 
     for parser in self.instances: 
      parser.parse() 
      self.assertEqual(Decimal('9216.84'), parser.countTotalValues()) 

    def test_count_items_without_parameter(self): 
     for parser in self.instances: 
      parser.parse() 
      self.assertEqual(128, parser.countItems()) 

是否好做呢?如果是,如何進行單元測試所有的人,一次與相同的TestCase沒有

for parser in self.instances: 
     parser.parse() 

所以我想要寫單元測試是這樣的:應用於

def test_count_total_values_without_parameter(self): 
    self.assertEqual(Decimal('9216.84'), parser.countTotalValues()) 

def test_count_items_without_parameter(self): 
    self.assertEqual(128, parser.countItems()) 

。可能嗎 ?

+1

這似乎或多或少類似於http://stackoverflow.com/questions/16305985/unit-test-suite-in-python。要回答你的問題,如果你應該在一次測試中測試多個實現,我會說不,因爲這不會告訴你哪個失敗,哪些沒有失敗。 –

回答

1

您是否考慮過創建一個基地TestCase並對您想要測試的每個類進行子類化?

這樣創建的,包含你的實際測試方法,並將其存放在一個獨立的模塊,不測試模塊模式相匹配(by default, test*.py),所以unittest不會發現它:

import unittest 

class BaseTestCase(unittest.TestCase): 
    def test_count_total_values_without_parameter(self): 
     self.assertEqual(Decimal('9216.84'), self.parser.countTotalValues()) 

    # …more tests… 

現在,在您的測試模塊中,執行如下操作:

import basetest 

class TestCSVParser(basetest.BaseTestCase): 
    def setUp(self): 
     self.parser = CSVParser() 

class TestXLSParser(basetest.BaseTestCase): 
    def setUp(self): 
     self.parser = XLSParser() 
+0

這將運行三個測試:'BaseTestCase.test_count ...','TestCSVParser.test_count ...'和'TestXLSParser.test_count ...',因爲'BaseTestCase'將被自動檢測爲testcase本身。簡單的補救措施是使用'test_count _...'函數編寫mixin類,並使用'unittest.TestCase'和'baseTestCase'中的多重繼承。 –

+0

@UlrichEckhardt這就是爲什麼我把'BaseTestCase'放在一個單獨的模塊中。我創建了一個更簡單的版本,以便在我的帖子和'python -m unittest discover'沒有選擇'basetest'模塊之前進行驗證;只有'test'模塊中的子測試用例被挑選出來,因爲它與'test * .py' glob(見http://docs.python.org/2/library/unittest.html#test-discovery) – zigg

+0

用@ UlrichEckhardt的建議,這太好了! – kissgyorgy

相關問題