Assert an integer is within range

后端 未结 4 1706
故里飘歌
故里飘歌 2021-01-07 17:09

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 w

相关标签:
4条回答
  • 2021-01-07 17:42
    self.assertTrue(998 <= my_integer <= 1000)
    
    0 讨论(0)
  • 2021-01-07 17:43

    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.

    0 讨论(0)
  • 2021-01-07 17:47

    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
    
    0 讨论(0)
  • 2021-01-07 17:55

    You can use a "chained comparison":

    self.assertTrue(998 <= my_integer <= 1000)
    
    0 讨论(0)
提交回复
热议问题