0

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

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

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

现在我想为所有这些类编写单元测试。当然,我可以为每个 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)

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

4

3 回答 3

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__))
于 2013-04-05T06:11:35.840 回答
0

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

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)

无论如何,感谢其他答案,很抱歉一开始没有找到这种方式。

于 2013-04-05T06:45:42.667 回答
0

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

一个测试方法应该只做一个测试,而不是循环几个assert*调用。否则,在失败的情况下,您将无法轻松判断哪个测试失败。毕竟这就是进行单元测试的全部意义所在。

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

对于具有相同方法的多个类(考虑在多个派生类中实现一个公共接口),将接口的公共属性的所有测试放在一个基类中,然后为每个基类派生单独的测试类可能很有用正在测试的班级。然后,那些派生类将实现合适setUp的 和tearDown方法。他们还可以添加更多特定于被测类的测试用例。

于 2013-04-05T07:08:12.727 回答