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@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) $ -- http://mail.python.org/mailman/listinfo/python-list