问题
I am writing some unittests in python that are testing if I receive an integer. However sometimes this integer can be off by 1 or 2 and I don't really care. Essentially I want to be able to assert that the received integer is within a certain range, something like:
self.assertBetween(998, 1000, my_integer)
Is there an accepted way of doing this? Or will I have to do something like this:
self.assertTrue(998 <= my_integer)
self.assertTrue(my_integer <= 1000)
EDIT The answers so far suggest:
self.assertTrue(998 <= my_integer <= 1000)
Is there any benefit of this over my example with 2 asserts?
回答1:
You can use a "chained comparison":
self.assertTrue(998 <= my_integer <= 1000)
回答2:
Python has a built in function you may use for this: assertAlmostEqual
.
self.assertAlmostEqual(myinteger, 999, delta=1)
# is equivalent to
self.assertTrue(998 <= myinteger <= 1000)
# ... but gives better error messages.
The optional parameter delta specifies the allowed distance from the value you're testing.
回答3:
I don't think it's a good idea to use assertTrue
with comparison inside -
that way you lose any information in FAIL message:
AssertionError: False is not true
Which is not helpful at all and you're basicaly back to "raw" assert
and you are losing a lot of unittest
's methods benefits.
I would recommend either:
Creating your own custom assert
in which you can print more meaningful message. For example:
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()
then you'll have following output (shortened):
======================================================================
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
----------------------------------------------------------------------
Or use assertLessEqual
and assertGreaterEqual
if you don't want custom assert (which does add another traceback record and several lines of code):
...
def test_no_custom_assert(self):
my_integer = 100
self.assertGreaterEqual(my_integer, 998)
self.assertLessEqual(my_integer, 1000)
...
which is a bit longer (it may be shorter in total than adding custom assert if it's used only once) than assertTrue(998 <= my_integer <= 1000)
but you'll still get nice fail messages (also without additional traceback record):
======================================================================
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
回答4:
self.assertTrue(998 <= my_integer <= 1000)
来源:https://stackoverflow.com/questions/26539799/assert-an-integer-is-within-range