unittest: Proposal to add failUnlessNear
Bengt Richter
bokr at oz.net
Mon Jul 19 13:34:08 EDT 2004
On 19 Jul 2004 11:06:47 GMT, Antoon Pardon <apardon at forel.vub.ac.be> wrote:
>I have been working with unittests lately and found that the
>self.failUnlessAlmostEqual, isn't as usefull as it could be.
>
>My main problem is, that it is only usefull with objects
>that can be converted to floats, while there are a whole
>bunch of objects that can be almost equal but not so
>convertable. The first example coming to mind being
>complex numbers.
>
>A secondary objection is that you are limited to
>a very specific set of tolerances. If for instance
>you want to verify that two numbers differ at most
>by 0.0003 you can't specify that.
>
>So I propose to add the following
>
>
> def failUnlessNear(self, first, second, tolerance=1e-7, msg=None, norm=abs):
> """Fail if the two objects are too far appart as determined
> by the distance between them and the tolerance allowed.
> """
> if norm(second-first) > tolerance:
> raise self.failureException, \
> (msg or '%s != %s within %s tolerance' % (`first`, `second`, `tolerance`))
>
>
>--
>Antoon Pardon
How about a more general solution? E.g., how about an optional keyword arg
cmp=comparison_function
passed to failUnlessAlmostEqual? (I'm guessing here, no time to look at it)
E.g., that way for mixed numbers including complex you could (if you thought
it made sense, which I am not necessarily arguing ;-) use e.g.
def special_cmp(x,y): # untested!
diff = complex(x)-complex(y)
return max(cmp(abs(diff.real), tolerance), cmp(abs(diff.imag), tolerance))
and pass cmp=special_cmp as the kwarg.
For special objects, you could define other kinds of nearness, and raise
appropriate informative exceptions if you get non-comparable arguments.
(obviously tolerance has to be defined, so if you want to vary it conveniently,
you could pass it to a factory function that does the above def and returns
it with tolerance captured in a closure referred to by special_cmp).
Or some other way. The point is you get to define the cmp= function as you please
without modifying the framework (once the optional kwarg is implemented).)
gotta go...
Regards,
Bengt Richter
More information about the Python-list
mailing list