断言整数在范围内

问题描述 投票:0回答:5

我正在用 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 个断言的示例相比,这有什么好处吗?

python unit-testing python-2.7 python-unittest
5个回答
48
投票

您可以使用“链式比较”:

self.assertTrue(998 <= my_integer <= 1000)

29
投票

Python 有一个 内置函数,您可以使用它:

assertAlmostEqual

self.assertAlmostEqual(myinteger, 999, delta=1)
# is equivalent to
self.assertTrue(998 <= myinteger <= 1000)
# ... but gives better error messages.

可选参数 delta 指定与您正在测试的值的允许距离。


18
投票

我认为使用

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

2
投票
self.assertTrue(998 <= my_integer <= 1000)

0
投票

另一个解决方案是下面的类,如果您想轻松比较

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

比较字典中的数字:

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
© www.soinside.com 2019 - 2024. All rights reserved.