断言一个整数在范围内
Posted
技术标签:
【中文标题】断言一个整数在范围内【英文标题】:Assert an integer is within range 【发布时间】:2014-12-19 19:29:43 【问题描述】:我正在 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)
与我的带有 2 个断言的示例相比,这有什么好处吗?
【问题讨论】:
你使用 1 个断言还是 2 个断言取决于你真正想了解和交流的内容。如果您只关心my_integer
是否在限制之间,那么一个断言是一种更简洁、更简洁的方法来测试并将其传达给下一个查看代码的人(可能在 3 个月内)。相反,如果有充分的理由分别知道 my_integer
是否低于 1000 以及知道 my_integer
是否高于 998,那么使用 2 个断言更有意义。
【参考方案1】:
Python 有一个 built in function,您可以使用它:assertAlmostEqual
。
self.assertAlmostEqual(myinteger, 999, delta=1)
# is equivalent to
self.assertTrue(998 <= myinteger <= 1000)
# ... but gives better error messages.
可选参数 delta 指定与您正在测试的值的允许距离。
【讨论】:
【参考方案2】:我认为在内部使用 assertTrue
并进行比较不是一个好主意 -
这样您会丢失 FAIL 消息中的任何信息:
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
【讨论】:
如果您将自定义断言方法放在具有_unittest
全局的模块中,则将省略回溯,并且您将获得使用内置 TestCase.assertX
方法的漂亮干净的回溯。跨度>
【参考方案3】:
self.assertTrue(998 <= my_integer <= 1000)
【讨论】:
【参考方案4】:您可以使用“chained comparison”:
self.assertTrue(998 <= my_integer <= 1000)
【讨论】:
@Yep_It's_Me:你问这两个单独的条件是否有任何好处。是的。它更简洁、更清晰、更高效(一个函数调用而不是两个)。 @JohnZwinck 虽然我同意这更短,但我不认为这是我推荐的,因为它与两个assertTrue
s 具有相同的缺点。您失去了 FAIL 消息的冗长性。使用assertTrue
,您将获得AssertionError: False is not true
,这不是很有帮助。我更喜欢看看哪里出了问题,所以我宁愿使用assertGreaterEqual(my_integer, 998); assertLessEqual(my_integer, 1000)
- 这样你就会立即知道哪里出了问题(例如:AssertionError: 100 not greater or equal to 998
)。
带有此断言的错误消息不会说明my_integer
的值或限制(通常您没有像这样的硬编码限制)。所以我更喜欢@JanSpurny 回答中的 assertBetween 方法。以上是关于断言一个整数在范围内的主要内容,如果未能解决你的问题,请参考以下文章