I am looking for a method (if available) that can compare two values and raise an assertion error with a meaningful message when the comparison fails.
If I use assert
, the failure message does not contain what values were compared when then assertion failed.
>>> a = 3
>>> b = 4
>>> assert a == b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
>>>
If I use the assertEqual()
method from the unittest.TestCase
package, the assertion message contains the values that were compared.
a = 3
b = 4
> self.assertEqual(a, b)
E AssertionError: 3 != 4
Note that, here, the assertion error message contains the values that were compared. That is very useful in real-life scenarios and hence necessary for me. The plain assert
(see above) does not do that.
However, so far, I could use assertEqual()
only in the class that inherits from unittest.TestCase
and provides few other required methods like runTest()
. I want to use assertEqual()
anywhere, not only in the inherited classes. Is that possible?
I tried the following but they did not work.
>>> import unittest
>>> unittest.TestCase.assertEqual(a, b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method failUnlessEqual() must be called with TestCase instance as first argument (got int instance instead)
>>>
>>>
>>> tc = unittest.TestCase()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.6/unittest.py", line 215, in __init__
(self.__class__, methodName)
ValueError: no such test method in <class 'unittest.TestCase'>: runTest
>>>
Is there any other package or library that offers similar methods like assertEqual()
that can be easily used without additional constraints?
It is possible to create a "helper" new module that provides access to the assert functions. AssertsAccessor
in this case:
from unittest import TestCase
# Dummy TestCase instance, so we can initialize an instance
# and access the assert instance methods
class DummyTestCase(TestCase):
def __init__(self):
super(DummyTestCase, self).__init__('_dummy')
def _dummy(self):
pass
# A metaclass that makes __getattr__ static
class AssertsAccessorType(type):
dummy = DummyTestCase()
def __getattr__(cls, key):
return getattr(AssertsAccessor.dummy, key)
# The actual accessor, a static class, that redirect the asserts
class AssertsAccessor(object):
__metaclass__ = AssertsAccessorType
The module needs to be created just once, and then all asserts from the unittest
package are accessible, e.g.:
AssertsAccessor.assertEquals(1, 2)
AssertionError: 1 != 2
Or another example:
AssertsAccessor.assertGreater(1, 2)
Which results:
AssertionError: 1 not greater than 2
Assuming the module created for the accessor is named assertions
, the common usage in the code would look like:
from assertions import AssertsAccessor
def foo(small_arg, big_arg):
AssertsAccessor.assertGreater(big_arg, small_arg)
# some logic here