我正在使用Python的unittest
为我的应用程序编写一些测试用例。现在我需要将一个对象列表与另一个对象列表进行比较,以检查第一个列表中的对象是否是我所期望的。
如何编写自定义.assertFoo()
方法?它该怎么办?它应该在失败时引发异常吗?如果是,哪个例外?以及如何传递错误信息?错误消息应该是unicode字符串还是字节串?
不幸的是,official documentation没有解释如何编写自定义断言方法。
如果你需要一个真实的例子,请继续阅读。
我写的代码有点像这样:
def assert_object_list(self, objs, expected):
for index, (item, values) in enumerate(zip(objs, expected)):
self.assertEqual(
item.foo, values[0],
'Item {0}: {1} != {2}'.format(index, item.foo, values[0])
)
self.assertEqual(
item.bar, values[1],
'Item {0}: {1} != {2}'.format(index, item.bar, values[1])
)
def test_foobar(self):
objs = [...] # Some processing here
expected = [
# Expected values for ".foo" and ".bar" for each object
(1, 'something'),
(2, 'nothing'),
]
self.assert_object_list(objs, expected)
这种方法可以非常轻松地以非常紧凑的方式描述每个对象的预期值,而无需实际创建完整的对象。
然而......当一个对象未通过断言时,不会比较其他对象,这会使调试变得更加困难。我想编写一个自定义方法,无条件地比较所有对象,然后显示所有失败的对象,而不是仅显示第一个。
答案 0 :(得分:33)
在这些情况下我使用多重继承。例如:
首先。我定义了一个包含方法的类。
import os
class CustomAssertions:
def assertFileExists(self, path):
if not os.path.lexists(path):
raise AssertionError('File not exists in path "' + path + '".')
现在我定义一个继承自unittest.TestCase和CustomAssertion
的类import unittest
class MyTest(unittest.TestCase, CustomAssertions):
def test_file_exists(self):
self.assertFileExists('any/file/path')
if __name__ == '__main__':
unittest.main()
答案 1 :(得分:18)
您应该创建自己的TestCase类,派生自unittest.TestCase。然后将自定义断言方法放入该测试用例类中。如果测试失败,请引发AssertionError。您的消息应该是一个字符串。如果要测试列表中的所有对象而不是停止失败,则收集失败索引列表,并在遍历所有对象之后,构建一个汇总消息,总结您的发现。
答案 2 :(得分:1)
只是一个例子来总结一个numpy comparaison unittest
import numpy as np
class CustomTestCase(unittest.TestCase):
def npAssertAlmostEqual(self, first, second, rtol=1e-06, atol=1e-08):
np.testing.assert_allclose(first, second, rtol=rtol, atol=atol)
class TestVector(CustomTestCase):
def testFunction(self):
vx = np.random.rand(size)
vy = np.random.rand(size)
self.npAssertAlmostEqual(vx, vy)