如何使用python在模块中使用相同的公共API对每个类进行单元测试?

时间:2013-05-16 15:17:07

标签: python unit-testing python-unittest

我有一个解析不同文件格式的模块,如CSV,XLS,HTML等。
不同的格式包含完全相同的信息,因此我为解析不同的文件类型创建了不同的类。这些类具有完全相同的公共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())

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

的情况下使用相同的TestCases对所有这些进行单元测试
    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 个答案:

答案 0 :(得分: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()