从函数和值的字典中进行Unittest



我是Python中unittests模块的新手,所以答案可能是显而易见的。我有一堆属性要检查它们都存储在字典里了

petersen_prop = {
    "n_vertex" : 10,
    "n_edge"   : 15,
    ...
}

每个"键"是函数的名称,值是我想要单元测试验证的目标。工作的是相当冗长的代码:

import unittest
class PetersenGraph(unittest.TestCase):
    def setUp(self):
        # Create the graph here (not important to the question)
        self.args = args
        self.adj = adj
    def test_n_vertex(self):
        self.assertTrue(n_vertex(self.adj,**self.args) == 
                        petersen_prop["n_vertex"])
    def test_n_edge(self):
        self.assertTrue(n_edge(self.adj,**self.args) == 
                        petersen_prop["n_edge"])
    # ..... hundreds of similar looking code blocks

unittest.main(verbosity=2)

似乎我违反了DRY,我必须一遍又一遍地复制和粘贴相同的代码块。是否有一种方法可以通过编程方式添加这些代码块,从而使单元测试按预期工作?为了清楚起见,我希望输入是上面的字典,输出是工作方式相同的unittest对象。

您可以遍历petersen_prop字典中的键,并根据键名调用正确的函数。

def test_n_props(self):
    for cur_prop in petersen_prop:
        func = globals()[cur_prop]
        self.assertTrue(func(self.adj,**self.args) == 
                        petersen_prop[cur_prop])
或者,如果您没有将所有函数名导入到测试模块的命名空间中,像这样:
def test_n_props(self):
    for cur_prop in petersen_prop:
        func = getattr(myfuncs, cur_prop)
        self.assertTrue(func(self.adj,**self.args) == 
                        petersen_prop[cur_prop])

您也可以将实际的函数对象存储在petersen_prop字典中:

petersen_prop = {
    "n_vertex" : (10, n_vertex)
    "n_edge"   : (15, n_edge)
    ...
}
def test_n_props(self):
    for cur_prop in petersen_prop:
        func = petersen_map[cur_prop][1]
        self.assertTrue(func(self.adj,**self.args) == 
                        petersen_prop[cur_prop][0])
编辑:

下面是使用元类为字典中的每个条目添加唯一测试的方法:

class TestMaker(type):
    def __new__(cls, clsname, bases, dct):
        # Add a method to the class' __dict__ for every key in
        # the petersen_prop dict.
        for prop in petersen_prop:
            dct['test_{}'.format(prop)] = cls.make_test(prop)
        return super(TestMaker, cls).__new__(cls, clsname, bases, dct)
    @staticmethod
    def make_test(prop):
        # test_wrap is the method body that will be used for each
        # test
        def test_wrap(self):
            func = getattr(myfuncs, prop)
            self.assertTrue(func(self.adj, **self.args) ==
                    petersen_prop[prop])
        return test_wrap
class PetersenGraph(unittest.TestCase):
   __metaclass__ = TestMaker

当您运行此操作时,您将为每个项目获得一个单独的测试用例。例如,在我的测试代码中,我让每个测试都失败:

======================================================================
FAIL: test_n_edge (__main__.PetersenGraph)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "un.py", line 26, in test_wrap
    petersen_prop[prop])
AssertionError: False is not true
======================================================================
FAIL: test_n_vertex (__main__.PetersenGraph)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "un.py", line 26, in test_wrap
    petersen_prop[prop])
AssertionError: False is not true

Python没有从函数内部获取函数名的功能。你能做的是test_n_vertex.__name__,它会给你'test_n_vertex'作为一个字符串。你可以使用基本的字符串函数来做你需要做的事情。但是你所期望的确切功能并不存在。

查看这里了解更多信息从函数内部确定函数名(不使用traceback)

相关内容

  • 没有找到相关文章

最新更新