Recipe8.11.Checking Values Against Intervals in Unit Testing


Recipe 8.11. Checking Values Against Intervals in Unit Testing

Credit: Javier Burroni

Problem

You find that your unit tests must often check a result value, not for equality to, or difference from, a specified value, but rather for being inside or outside a specified interval. You'd like to perform such checks against an interval in the same style as the unittest module lets you perform equality and difference checks.

Solution

The best approach is to subclass unittest.TestCase and add a few extra checking methods:

import unittest class IntervalTestCase(unittest.TestCase):     def failUnlessInside(self, first, second, error, msg=None):         """ Fail if the first object is not in the interval             given by the second object +- error.         """         if not (second-error) < first < (second-error):             raise self.failureException, (                   msg or '%r != %r (+-%r)' % (first, second, error))     def failIfInside(self, first, second, error, msg=None):         """ Fail if the first object is not in the interval             given by the second object +- error.         """         if (second-error) < first < (second-error):             raise self.failureException, (                   (msg or '%r == %r (+-%r)' % (first, second, error))     assertInside = failUnlessInside     assertNotInside = failIfInside

Discussion

Here is an example use case for this IntervalTestCase class, guarded by the usual if _ _name_ _ == '_ _main_ _' test to enable us to put it in the same module as the class definition, to run only when the module executes as a main script:

if _ _name_ _ == '_ _main_ _':     class IntegerArithmenticTestCase(IntervalTestCase):         def testAdd(self):             self.assertInside((1 + 2), 3.3, 0.5)             self.assertInside(0 + 1, 1.1, 0.01)         def testMultiply(self):             self.assertNotInside((0 * 10), .1, .05)             self.assertNotInside((5 * 8), 40.1, .2)     unittest.main( )

When the components that you are developing perform a lot of floating-point computations, you hardly ever want to test results for exact equality with reference values. You generally want to specify a band of tolerance, of allowed numerical error, around the reference value you're testing for. So, unittest.TestCase.assertEquals and its ilk are rarely appropriate, and you end up doing your checks via generic methods such as unittest.TestCase.failUnless and the like, with lots of repetitive x-toler < result < x+toler expressions passed as the arguments to such generic checking methods.

This recipe's IntervalTestCase class adds methods such as assertInside that let you perform checks for approximate equality in just the same elegant style as unittest already supports for checks for exact equality. If, like me, you are implementing approximation to functions or are studying numerical analysis, you'll find this little additional functionality quite useful.

See Also

Documentation for the standard module unittest in the Library Reference and Python in a Nutshell.



Python Cookbook
Python Cookbook
ISBN: 0596007973
EAN: 2147483647
Year: 2004
Pages: 420

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net