我有一堆应用于相似对象的函数,例如代表n维盒子的Numpy数组:
# 3-D box parameterized as:
# box[0] = 3-D min coordinate
# box[1] = 3-D max coordinate
box = np.array([
[1, 3, 0],
[4, 5, 7]
])
现在,我有很多功能要在盒子列表上运行,例如。 volumes
,intersection
,smallest_containing_box
等。在我看来,这是我希望设置的方式:
# list of test functions:
test_funcs = [volume, intersection, smallest_containing_box, ...]
# manually create a bunch of inputs and outputs
test_set_1 = (
input = [boxA, boxB, ...], # where each of these are np.Array objects
output = [
[volA, volB, ...], # floats I calculated manually
intersection, # np.Array representing the correct intersection
smallest_containing_box, # etc.
]
)
# Create a bunch of these, eg. test_set_2, test_set_3, etc. and bundle them in a list:
test_sets = [test_set_1, ...]
# Now run the set of tests over each of these:
test_results = [[assertEqual(test(t.input), t.output) for test in test_funcs] for t in test_sets]
我要以这种方式进行构造的原因是,我可以创建多组(输入,答案)对,并仅对每对进行所有测试。除非我丢失了某些内容,否则unittest
的结构似乎不适用于这种方法。相反,似乎要我为每对函数和输入(即
class TestCase1(unittest.TestCase):
def setUp(self):
self.input = [...]
self.volume = [volA, volB, ...]
self.intersection = ...
# etc.
def test_volume(self):
self.assertEqual(volume(self.input), self.volume)
def test_intersection(self):
self.assertEqual(intersection(self.input), self.output)
# etc.
# Repeat this for every test case!?
这似乎是疯狂的样板。我想念什么吗?
答案 0 :(得分:0)
让我们尝试描述我如何理解您的方法:您实现了许多具有相似性的不同功能,即它们对相同类型的输入数据进行操作。在测试中,您尝试利用这种相似性:创建一些输入数据并将该输入数据传递给所有函数。
这种以测试数据为中心的方法是不寻常的。典型的单元测试方法是以代码为中心的。原因是,单元测试的一个主要目标是发现代码中的错误。不同的功能(显然)具有不同的代码,因此,错误的类型可能不同。因此,通常精心设计测试数据以识别相应代码中的某些类型的错误。测试设计方法是有条理地设计测试用例的方法,理想情况下可以检测到所有可能的错误。
我怀疑,以您的测试数据为中心的方法,您将同样成功地找到不同功能中的错误:对于volume
功能,可能会有一些不存在的上溢情况(以及下溢情况)。 t申请intersection
或smallest_containing_box
。相比之下,将必须有空的相交,单点相交等。因此,似乎每个功能可能都需要专门设计的测试方案。
关于似乎是以代码为中心的单元测试的结果的样板代码:有几种方法可以限制这种情况。您将同意针对不同的被测功能使用不同的测试方法。但是您可以使用参数化测试来避免进一步的代码重复。并且,对于仍然可以看到(至少有时)对不同功能使用通用测试数据的情况:对于这种情况,可以使用创建测试数据的工厂函数,并可以从不同测试用例中调用。例如,您可能有一个工厂函数make-unit-cube
,可以在不同的测试中使用。
答案 1 :(得分:0)
尝试unittest.TestSuite()
。这为您提供了一个可以在其中添加测试用例的对象。在您的情况下,请创建套件,然后遍历您的列表,创建TestCase
的实例,这些实例都只有一个测试方法。将测试数据传递给构造函数,然后将其保存到那里的属性中,而不是放在setUp()
中。
当您使用名为suite()
的方法创建套件并运行所有套件时,单元测试运行器将检测到套件。
注意:为每个TestCase
实例分配一个名称,否则很难找出哪个失败。