Skip to main content
 首页 » 编程设计

python之如何使用 python 对模块中具有相同公共(public) API 的每个类进行单元测试

2025年05月04日11wuhuacong

我有一个模块可以解析不同的文件格式,例如 CSV、XLS、HTML 等。
不同的格式包含完全相同的信息,所以我制作了不同的类来解析不同的文件类型。这些类具有完全相同的公共(public) 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()) 

这样做可以吗?如果是,如何在没有

    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()) 

适用于每个 类(class)。可能吗?

请您参考如下方法:

您是否考虑过创建一个基础 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()