Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #30736 > unrolled thread
| Started by | David Banks <amoebae@gmail.com> |
|---|---|
| First post | 2012-10-04 08:53 -0700 |
| Last post | 2012-10-05 11:26 +0200 |
| Articles | 6 — 3 participants |
Back to article view | Back to comp.lang.python
How can I hide my stack frames in a TestCase subclass? David Banks <amoebae@gmail.com> - 2012-10-04 08:53 -0700
Re: How can I hide my stack frames in a TestCase subclass? Peter Otten <__peter__@web.de> - 2012-10-05 00:41 +0200
Re: How can I hide my stack frames in a TestCase subclass? Manuel Pégourié-Gonnard <mpg@elzevir.fr> - 2012-10-05 08:28 +0200
Re: How can I hide my stack frames in a TestCase subclass? Peter Otten <__peter__@web.de> - 2012-10-05 10:12 +0200
Re: How can I hide my stack frames in a TestCase subclass? Manuel Pégourié-Gonnard <mpg@elzevir.fr> - 2012-10-05 10:50 +0200
Re: How can I hide my stack frames in a TestCase subclass? Peter Otten <__peter__@web.de> - 2012-10-05 11:26 +0200
| From | David Banks <amoebae@gmail.com> |
|---|---|
| Date | 2012-10-04 08:53 -0700 |
| Subject | How can I hide my stack frames in a TestCase subclass? |
| Message-ID | <52b17563-966c-46bc-bd77-da29e944c909@googlegroups.com> |
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?
[toc] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2012-10-05 00:41 +0200 |
| Message-ID | <mailman.1826.1349400392.27098.python-list@python.org> |
| In reply to | #30736 |
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)
$
[toc] | [prev] | [next] | [standalone]
| From | Manuel Pégourié-Gonnard <mpg@elzevir.fr> |
|---|---|
| Date | 2012-10-05 08:28 +0200 |
| Message-ID | <k4lum6$c9q$1@thue.elzevir.fr> |
| In reply to | #30767 |
Peter Otten scripsit : > David Banks wrote: > >> 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 > Hum, is it documented somewhere? I can't find it in the doc. Also, I'm curious to know what kind of magic it's using. -- Manuel Pégourié-Gonnard - http://people.math.jussieu.fr/~mpg/
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2012-10-05 10:12 +0200 |
| Message-ID | <mailman.1841.1349424768.27098.python-list@python.org> |
| In reply to | #30782 |
Manuel Pégourié-Gonnard wrote: > Peter Otten scripsit : > >> David Banks wrote: >> >>> 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 >> > Hum, is it documented somewhere? I can't find it in the doc. Also, I'm > curious to know what kind of magic it's using. I took advantage of the fact that Python is open source and had a look into the source code ;) $ cd /usr/lib/python2.7/unittest $ grep frame *.py -C2 ... result.py- result.py- def _is_relevant_tb_level(self, tb): result.py: return '__unittest' in tb.tb_frame.f_globals result.py- ... $ grep _is_relevant_tb_level *.py -C5 result.py- result.py- def _exc_info_to_string(self, err, test): result.py- """Converts a sys.exc_info()-style tuple of values into a string.""" result.py- exctype, value, tb = err result.py- # Skip test runner traceback levels result.py: while tb and self._is_relevant_tb_level(tb): result.py- tb = tb.tb_next result.py- ... And so on. I actually used an editor, not grep -- but you get the idea.
[toc] | [prev] | [next] | [standalone]
| From | Manuel Pégourié-Gonnard <mpg@elzevir.fr> |
|---|---|
| Date | 2012-10-05 10:50 +0200 |
| Message-ID | <k4m715$74m$1@thue.elzevir.fr> |
| In reply to | #30787 |
Peter Otten scripsit : > Manuel Pégourié-Gonnard wrote: > >> Peter Otten scripsit : >> >>> __unittest = True >>> >> Hum, is it documented somewhere? I can't find it in the doc. Also, I'm >> curious to know what kind of magic it's using. > > I took advantage of the fact that Python is open source and had a look into > the source code ;) > Fair enough. However, there was an implied question in the "documented" part: can we rely on it? Isn't it considered an implementation detail (names starting with underscores)? > $ cd /usr/lib/python2.7/unittest > $ grep frame *.py -C2 > ... > result.py- > result.py- def _is_relevant_tb_level(self, tb): > result.py: return '__unittest' in tb.tb_frame.f_globals > result.py- > ... > > $ grep _is_relevant_tb_level *.py -C5 > result.py- > result.py- def _exc_info_to_string(self, err, test): > result.py- """Converts a sys.exc_info()-style tuple of values into a > string.""" > result.py- exctype, value, tb = err > result.py- # Skip test runner traceback levels > result.py: while tb and self._is_relevant_tb_level(tb): > result.py- tb = tb.tb_next > result.py- > ... > > And so on. I actually used an editor, not grep -- but you get the idea. Sure, thanks. -- Manuel Pégourié-Gonnard - http://people.math.jussieu.fr/~mpg/
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2012-10-05 11:26 +0200 |
| Message-ID | <mailman.1846.1349429195.27098.python-list@python.org> |
| In reply to | #30794 |
Manuel Pégourié-Gonnard wrote: > However, there was an implied question in the "documented" part: can > we rely on it? Isn't it considered an implementation detail (names > starting with underscores)? "Not documented" was my implied answer. I think you have a valid use case, though, so you could make a feature request for an official way to hide stack frames on the bugtracker http://bugs.python.org or the python-ideas mailing list.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web