断言整数在范围内
我正在用Python写一些单元测试,主要是测试我收到的是否是一个整数。不过,有时候这个整数可能会偏差1或2,我对此并不太在意。简单来说,我想确认收到的整数是在一个特定的范围内,类似于这样:
self.assertBetween(998, 1000, my_integer)
有没有什么被广泛接受的方法来做到这一点?还是说我得像这样做:
self.assertTrue(998 <= my_integer)
self.assertTrue(my_integer <= 1000)
编辑 到目前为止,大家的回答建议:
self.assertTrue(998 <= my_integer <= 1000)
这样做相比我用两个断言的例子有什么好处吗?
5 个回答
另一种解决方案是下面这个类,如果你想在一个 dict
中轻松比较数字,它会非常有用:
@dataclass
class IsBetweenOrEqual:
lower_bound: float
upper_bound: float
def __eq__(self, actual) -> bool:
return self.lower_bound <= actual <= self.upper_bound
这个类的使用示例:
3 == IsBetweenOrEqual(2, 3)
>>> True
3 == IsBetweenOrEqual(2, 2.5)
>>> False
在 dict
中比较数字:
allowed_dict = {"num1": IsBetweenOrEqual(0, 2), "num2": 2}
test_dict1 = {"num1": 1, "num2": 2}
test_dict2 = {"num1": 10, "num2": 2}
test_dict1 == allowed_dict
>>> True
test_dict2 == allowed_dict
>>> False
在编程中,有时候你会遇到一些问题,比如代码运行不正常或者出现错误。这种情况下,很多人会去StackOverflow这个网站寻求帮助。这个网站就像一个大型的问答社区,程序员们可以在这里提问,也可以回答别人的问题。
当你在这个网站上提问时,最好把你的问题描述得清楚明白。比如,你可以告诉大家你在做什么,遇到了什么问题,错误信息是什么,甚至可以把相关的代码贴出来。这样,其他人才能更好地理解你的问题,并给出有效的建议。
如果你看到别人提问时没有提供足够的信息,可能会导致他们得不到帮助。所以,记得在提问时尽量详细,这样大家才能更快地帮到你。
总之,StackOverflow是一个很有用的地方,能帮助你解决编程中的各种问题,只要你提问得当,大家都会乐意帮忙。
self.assertTrue(998 <= my_integer <= 1000)
我觉得在使用 assertTrue
时直接进行比较并不是个好主意——这样会让失败信息变得不清楚:
AssertionError: False is not true
这根本没有帮助,你基本上又回到了“原始”的 assert
,而且你失去了很多 unittest
的好处。
我建议你可以选择以下两种方法:
创建你自己的自定义断言
这样你可以打印出更有意义的信息。例如:
import unittest
class BetweenAssertMixin(object):
def assertBetween(self, x, lo, hi):
if not (lo <= x <= hi):
raise AssertionError('%r not between %r and %r' % (x, lo, hi))
class Test1(unittest.TestCase, BetweenAssertMixin):
def test_between(self):
self.assertBetween(999, 998, 1000)
def test_too_low(self):
self.assertBetween(997, 998, 1000)
def test_too_high(self):
self.assertBetween(1001, 998, 1000)
if __name__ == '__main__':
unittest.main()
这样你会得到以下输出(简化版):
======================================================================
FAIL: test_too_high (__main__.Test1)
----------------------------------------------------------------------
Traceback (most recent call last):
File "example.py", line 19, in test_too_high
self.assertBetween(1001, 998, 1000)
File "example.py", line 8, in assertBetween
raise AssertionError('%r is not between %r and %r' % (x, lo, hi))
AssertionError: 1001 is not between 998 and 1000
======================================================================
FAIL: test_too_low (__main__.Test1)
----------------------------------------------------------------------
Traceback (most recent call last):
File "example.py", line 16, in test_too_low
self.assertBetween(997, 998, 1000)
File "example.py", line 8, in assertBetween
raise AssertionError('%r is not between %r and %r' % (x, lo, hi))
AssertionError: 997 is not between 998 and 1000
----------------------------------------------------------------------
或者使用 assertLessEqual
和 assertGreaterEqual
如果你不想使用自定义断言(虽然自定义断言会增加另一个错误追踪记录和几行代码):
...
def test_no_custom_assert(self):
my_integer = 100
self.assertGreaterEqual(my_integer, 998)
self.assertLessEqual(my_integer, 1000)
...
这样写会稍微长一些(如果只用一次,可能总的代码量还不如自定义断言短)比 assertTrue(998 <= my_integer <= 1000)
要长,但你仍然会得到很好的失败信息(而且没有额外的错误追踪记录):
======================================================================
FAIL: test_no_custom_assert (__main__.Test1)
----------------------------------------------------------------------
Traceback (most recent call last):
File "example.py", line 23, in test_no_custom_assert
self.assertGreaterEqual(my_integer, 998)
AssertionError: 100 not greater than or equal to 998
Python里面有一个内置的函数可以用来做这个事情:assertAlmostEqual
。
self.assertAlmostEqual(myinteger, 999, delta=1)
# is equivalent to
self.assertTrue(998 <= myinteger <= 1000)
# ... but gives better error messages.
这个函数有一个可选的参数叫做delta,它用来指定你测试的值和期望值之间允许的差距。
你可以使用一种叫做“链式比较”的方法:
self.assertTrue(998 <= my_integer <= 1000)