测试包含浮点数的元组断言
我有一个函数,它返回一个元组,这个元组里包含了一个浮点数值。通常我会用 assertAlmostEquals
来比较这些浮点数,但这个方法不适用于元组。而且,这个元组里还有其他类型的数据。目前我是在逐个检查元组里的每个元素,但这样做对于一大堆这样的元组来说实在是太麻烦了。有没有什么好的方法可以写出这样的断言呢?
考虑这个函数:
def f(a):
return [(1.0/x, x * 2) for x in a]
现在我想为它写一个测试:
def testF(self):
self.assertEqual(f(range(1,3)), [(1.0, 2), (0.5, 4)])
这个测试会失败,因为 1.0/2
的结果并不完全等于 0.5
。有没有人能推荐一种更好、更易读的方式来写这样的断言呢?
编辑:其实 1.0/2
确实是等于 0.5
,不过你明白我的意思。
3 个回答
2
我过去做的事情是写一个自定义函数,用来检查一个复杂数据类型的有效性,然后使用 assert( IsFooValid( foo ) )
来验证。这个有效性检查函数可以简单地返回真或假,但通常更好的是它能抛出一个AssertionError,并附上合适的错误信息。
3
我可能会定义一个递归函数。
from collections import Iterable;
def recursiveAssertAlmostEqual(testCase, first, second, *args, **kwargs):
if isinstance(first, Iterable) and isinstance(second, Iterable):
for a, b in zip(first, second):
recursiveAssertAlmostEqual(testCase, a, b, *args, **kwargs)
else:
testCase.assertAlmostEqual(first, second, *args, **kwargs)
(注意,它会检查 (1, 2)
和 [1, 2]
是否相等。)
8
那么,如何让你的函数更酷一些呢?可以试试用几个 zip:
def testF(self):
for tuple1, tuple2 in zip(f(range(1,3)), [(1.0, 2), (0.5, 4)]):
for val1, val2 in zip(tuple1, tuple2):
if type(val2) is float:
self.assertAlmostEquals(val1, val2, 5)
else:
self.assertEquals(val1, val2)
我的观点是,在循环中使用多个断言(assert)会更好,这样可以准确找到出错的具体值,而不是用一个断言配合 all()。
另外,如果你有其他数字类型想用 assertAlmostEquals 来检查,可以把上面的 if 改成,比如 if type(val2) in [float, decimal.Decimal]:
。