11

I'd like to add some custom assert methods to a TestCase. As a simple example, I've just put one inside the test class below. It works as expected, but when the output is generated the traceback includes the custom assert in the output.

What is the step necessary to make it behave like assertEqual()? The code for assertEqual is in TestCase, but the actual line that raises the assertion does not appear in the traceback. What do I need to do to make test_something2's output look more like test_something1's?

import unittest
class TestCustomAssert(unittest.TestCase):
    def assertSomething(self, s):
        self.assertEqual(s, 'something')
    def test_something1(self):
        self.assertEqual('foo', 'something')
    def test_something2(self):
        self.assertSomething('foo')

if __name__ == '__main__':
    unittest.main()

Output

python3 custom_assert.py 
FF
======================================================================
FAIL: test_something1 (__main__.TestCustomAssert)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "custom_assert.py", line 8, in test_something1
    self.assertEqual('foo', 'something')
AssertionError: 'foo' != 'something'
- foo                                                                                                                    
+ something                                                                                                              


======================================================================                                                   
FAIL: test_something2 (__main__.TestCustomAssert)                                                                        
----------------------------------------------------------------------                                                   
Traceback (most recent call last):                                                                                       
  File "custom_assert.py", line 10, in test_something2                                                                   
    self.assertSomething('foo')                                                                                          
  File "custom_assert.py", line 6, in assertSomething                                                                    
    self.assertEqual(s, 'something')                                                                                     
AssertionError: 'foo' != 'something'                                                                                     
- foo                                                                                                                    
+ something                                                                                                              


----------------------------------------------------------------------                                                   
Ran 2 tests in 0.000s                                                                                                    

FAILED (failures=2)

1 Answer 1

13

unittest doesn't print tracebacks from frames that have __unittest=True in their globals.

From unittest.result:

def _is_relevant_tb_level(self, tb):
    return '__unittest' in tb.tb_frame.f_globals

So, if you make a helper module, you can emulate that behavior:

helper.py:

__unittest = True
def assert_stuff(s):
    assert s == 'something', "%s is not something" % s

Now you can call this helper from your test case.

I guess that one could make a very neat decorator that make such magic more automatic without a helper module but IMHO you shouldn't make effort to reduce the traceback anyway.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.