Python的unittest和动态创建测试用例

24 投票
2 回答
15097 浏览
提问于 2025-04-15 13:13

可能重复的问题:
如何在Python中生成动态(参数化)单元测试?

有没有办法动态创建 unittest 测试用例?我尝试了以下方法...

class test_filenames(unittest.TestCase):

    def setUp(self):
        for category, testcases in files.items():
            for testindex, curtest in enumerate(testcases):
                def thetest():
                    parser = FileParser(curtest['input'])
                    theep = parser.parse()
                    self.assertEquals(theep.episodenumber, curtest['episodenumber'])

                setattr(self, 'test_%s_%02d' % (category, testindex), thetest)

..这个方法能正确创建所有的方法(它们在 dir() 中能看到,并且可以调用),但是unittest的测试检测器和 nosetest 都没有执行它们(显示“运行了0个测试...”)

因为我可能问错了问题——我想实现的目标是:

我有一个文件,里面包含测试数据,还有一系列输入文件名和预期数据(在上面的代码中简化为 episodenumber),这些数据存储在一个Python字典里。字典的键是类别,值是测试用例的列表,比如...

test_cases = {}
test_cases['example_1'] = [
    {'input': 'test.01',
    'episodenumber': 1},
    {'input': 'test.02',
    'episodenumber': 2}
]

test_cases['example_2'] = [
    {'input': 'another.123',
    'episodenumber': 123},
    {'input': 'test.e42',
    'episodenumber': 32}
]

目前我只是遍历所有数据,对每个测试调用 self.assertEquals。问题是,如果有一个测试失败了,我就看不到其他的失败,因为它们都被归为一个测试,当其中一个断言失败时,这个测试就会中止。

我想的解决办法是(动态地)为每个测试用例创建一个函数,也许还有更好的方法?

2 个回答

25

在下面的解决方案中,类 Tests 包含了一个辅助方法 check,但没有静态定义的测试用例。接下来,我使用 setattr 动态地为这个类添加测试用例。在下面的例子中,我生成了测试用例 test_<i>_<j>,其中 i 的范围是 [1,3],j 的范围是 [2,5]。这些测试用例会用不同的 i 和 j 值来调用辅助方法 check

class Tests(unittest.TestCase):
    def check(self, i, j):
        self.assertNotEquals(0, i-j)



for i in xrange(1, 4):
    for j in xrange(2, 6):
        def ch(i, j):
            return lambda self: self.check(i, j)
        setattr(Tests, "test_%r_%r" % (i, j), ch(i, j))
12

为了实现这个,你应该在 nose 中使用测试 生成器。你只需要返回一个元组,第一个元素是一个函数,后面的元素是参数。下面是文档中的一个例子。

def test_evens():
    for i in range(0, 5):
        yield check_even, i, i*3

def check_even(n, nn):
    assert n % 2 == 0 or nn % 2 == 0

撰写回答