代码之家  ›  专栏  ›  技术社区  ›  Srikanth

如何在Python中生成动态(参数化)单元测试?

  •  366
  • Srikanth  · 技术社区  · 17 年前

    我有一些测试数据,想为每个项目创建一个单元测试。我的第一个想法是这样做:

    import unittest
    
    l = [["foo", "a", "a",], ["bar", "a", "b"], ["lee", "b", "b"]]
    
    class TestSequence(unittest.TestCase):
        def testsample(self):
            for name, a,b in l:
                print "test", name
                self.assertEqual(a,b)
    
    if __name__ == '__main__':
        unittest.main()
    

    这样做的缺点是,它在一个测试中处理所有数据。我想在运行中为每个项目生成一个测试。有什么建议吗?

    25 回复  |  直到 4 年前
        1
  •  2
  •   Peter Mortensen Pieter Jan Bonestroo    4 年前

    这被称为“参数化”。

    有几个工具支持这种方法。例如。:

    生成的代码如下:

    from parameterized import parameterized
    
    class TestSequence(unittest.TestCase):
        @parameterized.expand([
            ["foo", "a", "a",],
            ["bar", "a", "b"],
            ["lee", "b", "b"],
        ])
        def test_sequence(self, name, a, b):
            self.assertEqual(a,b)
    

    这将生成测试:

    test_sequence_0_foo (__main__.TestSequence) ... ok
    test_sequence_1_bar (__main__.TestSequence) ... FAIL
    test_sequence_2_lee (__main__.TestSequence) ... ok
    
    ======================================================================
    FAIL: test_sequence_1_bar (__main__.TestSequence)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/usr/local/lib/python2.7/site-packages/parameterized/parameterized.py", line 233, in <lambda>
        standalone_func = lambda *a: func(*(a + p.args), **p.kwargs)
      File "x.py", line 12, in test_sequence
        self.assertEqual(a,b)
    AssertionError: 'a' != 'b'
    

    由于历史原因,我将在2008年左右留下原始答案):

    我使用这样的东西:

    import unittest
    
    l = [["foo", "a", "a",], ["bar", "a", "b"], ["lee", "b", "b"]]
    
    class TestSequense(unittest.TestCase):
        pass
    
    def test_generator(a, b):
        def test(self):
            self.assertEqual(a,b)
        return test
    
    if __name__ == '__main__':
        for t in l:
            test_name = 'test_%s' % t[0]
            test = test_generator(t[1], t[2])
            setattr(TestSequense, test_name, test)
        unittest.main()
    
    推荐文章