How can I hide my stack frames in a TestCase subclass?
Peter Otten
__peter__ at web.de
Thu Oct 4 18:41:24 EDT 2012
David Banks wrote:
> I want to add a custom assert method to a TestCase subclass. I tried to
> copy my implementation from the unittest module so that it would match
> the behaviour of the regular TestCase as closely as possible. (I would
> prefer to just delegate to self.assertEqual() but this causes even more
> backtrace noise, see below.) The unittest module seems to automatically
> hide some internal details of its implementation when reporting failed
> assertions.
>
> import unittest
>
> class MyTestCase(unittest.TestCase):
> def assertLengthIsOne(self, sequence, msg=None):
> if len(sequence) != 1:
> msg = self._formatMessage(msg, "length is not one")
> raise self.failureException(msg)
>
> class TestFoo(MyTestCase):
> seq = (1, 2, 3, 4, 5)
>
> def test_stock_unittest_assertion(self):
> self.assertEqual(len(self.seq), 1)
>
> def test_custom_assertion(self):
> self.assertLengthIsOne(self.seq)
>
>
> unittest.main()
>
> The output of this is as such:
>
> amoe at vuurvlieg $ python unittest-demo.py
> FF
> ======================================================================
> FAIL: test_custom_assertion (__main__.TestFoo)
> ----------------------------------------------------------------------
> Traceback (most recent call last):
> File "unittest-demo.py", line 16, in test_custom_assertion
> self.assertLengthIsOne(self.seq)
> File "unittest-demo.py", line 7, in assertLengthIsOne
> raise self.failureException(msg)
> AssertionError: length is not one
>
> ======================================================================
> FAIL: test_stock_unittest_assertion (__main__.TestFoo)
> ----------------------------------------------------------------------
> Traceback (most recent call last):
> File "unittest-demo.py", line 13, in test_stock_unittest_assertion
> self.assertEqual(len(self.seq), 1)
> AssertionError: 5 != 1
>
> ----------------------------------------------------------------------
> Ran 2 tests in 0.000s
>
> FAILED (failures=2)
>
> Note that the custom assert method causes a stack trace with two frames,
> one inside the method itself, whereas the stock unittest method only has
> one frame, the relevant line in the user's code. How can I apply this
> frame-hiding behaviour to my own method?
Move MyTestCase in a separate module and define a global variable
__unittest = True
$ cat mytestcase.py
import unittest
__unittest = True
class MyTestCase(unittest.TestCase):
def assertLengthIsOne(self, sequence, msg=None):
if len(sequence) != 1:
msg = self._formatMessage(msg, "length is not one")
raise self.failureException(msg)
$ cat mytestcase_demo.py
import unittest
from mytestcase import MyTestCase
class TestFoo(MyTestCase):
seq = (1, 2, 3, 4, 5)
def test_stock_unittest_assertion(self):
self.assertEqual(len(self.seq), 1)
def test_custom_assertion(self):
self.assertLengthIsOne(self.seq)
if __name__ == "__main__":
unittest.main()
$ python mytestcase_demo.py
FF
======================================================================
FAIL: test_custom_assertion (__main__.TestFoo)
----------------------------------------------------------------------
Traceback (most recent call last):
File "mytestcase_demo.py", line 11, in test_custom_assertion
self.assertLengthIsOne(self.seq)
AssertionError: length is not one
======================================================================
FAIL: test_stock_unittest_assertion (__main__.TestFoo)
----------------------------------------------------------------------
Traceback (most recent call last):
File "mytestcase_demo.py", line 8, in test_stock_unittest_assertion
self.assertEqual(len(self.seq), 1)
AssertionError: 5 != 1
----------------------------------------------------------------------
Ran 2 tests in 0.000s
FAILED (failures=2)
$
More information about the Python-list
mailing list