断言整数在范围内

Yep*_*_Me 15 python unit-testing python-2.7 python-unittest

我正在python中编写一些单元测试,测试是否收到整数.然而,有时这个整数可以关闭1或2,我真的不在乎.基本上我希望能够断言收到的整数在一定范围内,如:

self.assertBetween(998, 1000, my_integer)
Run Code Online (Sandbox Code Playgroud)

这是否有可接受的方式?或者我必须做这样的事情:

self.assertTrue(998 <= my_integer)
self.assertTrue(my_integer <= 1000)
Run Code Online (Sandbox Code Playgroud)

编辑 到目前为止的答案建议:

self.assertTrue(998 <= my_integer <= 1000)
Run Code Online (Sandbox Code Playgroud)

在我的2个断言的例子中,这有什么好处吗?

Joh*_*nck 25

您可以使用" 链式比较 ":

self.assertTrue(998 <= my_integer <= 1000)
Run Code Online (Sandbox Code Playgroud)

  • @JohnZwinck虽然我同意这个更短,我不认为这是我会推荐的东西,因为它有两个`assertTrue的相同缺点.你失去了FAIL消息的冗长.使用`assertTrue`,你会得到`AssertionError:False不是真的`,这不是很有用.我更喜欢看错了,所以我宁愿使用`assertGreaterEqual(my_integer,998); assertLessEqual(my_integer,1000)` - 这样你就会立即知道什么是错的(例如:`AssertionError:100不大于或等于998`). (6认同)
  • @Yep_It's_Me:你问过两个独立的条件对你有什么好处.是.它更简洁,更清晰,更高效(一个函数调用而不是两个). (2认同)

Teo*_*dor 18

Python有一个可用于此的内置函数:assertAlmostEqual.

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

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


Jan*_*rny 8

我不认为使用assertTrue内部比较是一个好主意- 这样你就失去了FAIL消息中的任何信息:

AssertionError: False is not true
Run Code Online (Sandbox Code Playgroud)

这根本没有帮助,你基本上回到"原始" 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()
Run Code Online (Sandbox Code Playgroud)

然后你将有以下输出(缩短):

======================================================================
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
----------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

或者使用assertLessEqualassertGreaterEqual

如果你不想要自定义断言(它确实添加了另一个回溯记录和几行代码):

...
def test_no_custom_assert(self):
    my_integer = 100
    self.assertGreaterEqual(my_integer, 998)
    self.assertLessEqual(my_integer, 1000)
...
Run Code Online (Sandbox Code Playgroud)

这有点长(如果它只使用一次,它可能比添加自定义断言的总长度短)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
Run Code Online (Sandbox Code Playgroud)

  • 如果您将自定义断言方法放在具有 `_unittest` 全局变量的模块中,则回溯将被省略,并且您将获得使用内置 `TestCase.assertX` 方法的漂亮干净的回溯。 (2认同)