如何对多个类似的类进行单元测试

时间:2013-04-05 06:03:20

标签: python unit-testing

我有一个包含多个非常相似类的程序:

class BlackBox1():
    def calc(self, a, b):
        return a + b

class BlackBox2():
    def calc(self, a, b):
        return a * b
...

现在我想为所有这些类编写单元测试。当然,我可以为每个Blackbox编写单独的测试。无论如何,由于每个blackbox都有完全相同的方法calc(a, b)进行测试,我想,如果有类似“最佳实践”的东西,自动将类和预期结果提供给抽象测试框架,比如

import unittest
class TestAbstractBox(unittest.TestCase):
    def setUp(self):
        self.box = blackbox()
        self.param_a = a
        self.param_b = b
        self.expected_result = result

    def test_calc_method(self):
        real_result = self.box.calc(self.param_a, self.param_b)
        self.assertEqual(real_result, self.expected_result, 
                        "{0} gives wrong result".format(self.box.__class__))

TAbstractTest = unittest.defaultTestLoader.loadTestsFromTestCase(TestAbstractBox)

有没有办法将{"blackbox": Blackbox1, "a": 3, "b": 5, "result": 8}{"blackbox": Blackbox2, "a": 4, "b": 7, "result": 28}传递给TestAbstractBox类,而不是多次使用相同的代码,但是有一种简单的方法来测试新的Blackbox?

3 个答案:

答案 0 :(得分:1)

您只需将这些类添加到setUp

即可
class TestAbstractBox(unittest.TestCase):
  def setUp(self):
    self.boxes = [Blackbox1(), Blackbox2()]
    self.param_a = a
    self.param_b = b
    self.expected_result = result

  def test_calc_method(self):
    for box in self.boxes:
      real_result = self.box.calc(self.param_a, self.param_b)
      self.assertEqual(real_result, self.expected_result, 
          "{0} gives wrong result".format(self.box.__class__))

编辑版本2:

class TestAbstractBox(unittest.TestCase):
  def setUp(self):
    self.boxes = [
      { "blackbox":Blackbox1(), "a":a1, "b":b1, "expected_result":result1 },
      { "blackbox":Blackbox2(), "a":a2, "b":b2, "expected_result":result2 },
    ]

  def test_calc_method(self):
    for box in self.boxes:
      real_result = box["blackbox"].calc(box["a"], box["b"])
      self.assertEqual(real_result, box["expected_result"], 
          "{0} gives wrong result".format(box["blackbox"].__class__))

答案 1 :(得分:0)

我想我找到了一个解决方案,基本上遵循this answer

import unittest

class BlackBox1():
    def calc(self, a, b):
        return a + b

class BlackBox2():
    def calc(self, a, b):
        return a * b

class TestBlackBox1(unittest.TestCase):
    test_params = {"blackbox": BlackBox1, "a": 3, "b": 5, "result": 8}
    def setUp(self):
        self.box = self.test_params["blackbox"]()
        self.param_a = self.test_params["a"]
        self.param_b = self.test_params["b"]
        self.expected_result = self.test_params["result"]

    def test_calc_method(self):
        real_result = self.box.calc(self.param_a, self.param_b)
        self.assertEqual(real_result, self.expected_result,
                        "{0} gives wrong result: {1} instead of {2}".format
                        (self.box.__class__, real_result, self.expected_result))

class TestBlackBox2(TestBlackBox1):
    test_params = {"blackbox": BlackBox2, "a": 4, "b": 7, "result": 28}

TBB1 = unittest.defaultTestLoader.loadTestsFromTestCase(TestBlackBox1)
TBB2 = unittest.defaultTestLoader.loadTestsFromTestCase(TestBlackBox2)

无论如何,感谢其他答案,并且抱歉没有找到这种方式。

答案 2 :(得分:0)

我认为这不是一个好方法。

测试方法应该只进行一次测试,而不是循环几次assert*次调用。否则,如果发生故障,您将无法轻易确定哪个测试失败。毕竟这是做单元测试的重点。

此外,您不应冒险通过为新类添加新变体或将现有测试重构为一些常用方法来破坏现有测试。

对于具有相同方法的几个类(考虑在几个派生类中实现公共接口),将接口的公共属性的所有测试放入一个基类然后派生单个测试可能是有用的。每个被测试课程的课程。然后,这些派生类将实现合适的setUptearDown方法。他们还可能会添加更多特定于被测试类的测试用例。