2

I have simple tests in site_tests.py file:

import unittest


class SiteTests(unittest.TestCase):

    def test(self):
        self.assertEqual('a', 'b')

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

When I run "Unittest in test_site.py" with default PyCharm configuration I'm getting:

Testing started at 23:45 ...
C:\Users\testSite\AppData\Local\Programs\Python\Python36-32\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2018.1.3\helpers\pycharm\_jb_unittest_runner.py" --path C:/testSiteDemoTests/site_tests.py
Launching unittests with arguments python -m unittest C:/testSiteDemoTests/site_tests.py in C:\testSiteDemoTests


b != a

Expected :a
Actual   :b
 <Click to see difference>

Traceback (most recent call last):
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.1.3\helpers\pycharm\teamcity\diff_tools.py", line 32, in _patched_equals
    old(self, first, second, msg)
  File "C:\Users\testSite\AppData\Local\Programs\Python\Python36-32\lib\unittest\case.py", line 829, in assertEqual
    assertion_func(first, second, msg=msg)
  File "C:\Users\testSite\AppData\Local\Programs\Python\Python36-32\lib\unittest\case.py", line 1202, in assertMultiLineEqual
    self.fail(self._formatMessage(msg, standardMsg))
  File "C:\Users\testSite\AppData\Local\Programs\Python\Python36-32\lib\unittest\case.py", line 670, in fail
    raise self.failureException(msg)
AssertionError: 'a' != 'b'
- a
+ b


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\testSite\AppData\Local\Programs\Python\Python36-32\lib\unittest\case.py", line 59, in testPartExecutor
    yield
  File "C:\Users\testSite\AppData\Local\Programs\Python\Python36-32\lib\unittest\case.py", line 605, in run
    testMethod()
  File "C:\testSiteDemoTests\site_tests.py", line 7, in test
    self.assertEqual('a', 'b')



Ran 1 test in 0.000s

FAILED (failures=1)

Process finished with exit code 1

The last part is very interesting since running this file without _jb_unittest_runner.py so C:\testSite>python lost_hat_tests.py the output is ok:

F
======================================================================
FAIL: test (__main__.SiteTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lost_hat_tests.py", line 7, in test
    self.assertEqual('a', 'b')
AssertionError: 'a' != 'b'
- a
+ b


----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (failures=1)

Is there simple answer why that second message appearing in PyCharm runner?

I also run the test in console with _jb_unittest_runner.py - hmm two testSuites - interesting

C:\testSiteDemoTests>python "C:\Program Files\JetBrains\PyCharm Community Edition 2018.1.3\helpers\pycharm\_jb_unittest_runner.py" --path C:/testSiteDemoTests/site_tests.py
##teamcity[enteredTheMatrix timestamp='2018-05-20T23:59:59.931']
Launching unittests with arguments python -m unittest C:/testSiteDemoTests/site_tests.py in C:\testSiteDemoTests

##teamcity[testCount timestamp='2018-05-20T23:59:59.946' count='1']
##teamcity[testSuiteStarted timestamp='2018-05-20T23:59:59.946' locationHint='python<C:\testSiteDemoTests>://site_tests' name='site_tests' nodeId='1' parentNodeId='0']
##teamcity[testSuiteStarted timestamp='2018-05-20T23:59:59.946' locationHint='python<C:\testSiteDemoTests>://site_tests.SiteTests' name='SiteTests' nodeId='2' parentNodeId='1']
##teamcity[testStarted timestamp='2018-05-20T23:59:59.962' captureStandardOutput='true' locationHint='python<C:\testSiteDemoTests>://site_tests.SiteTests.test' name='test' nodeId='3' parentNodeId='2']
##teamcity[testFailed timestamp='2018-05-20T23:59:59.977' actual='b' details='Traceback (most recent call last):|n  File "C:\Program Files\JetBrains\PyCharm Community Edition 2018.1.3\helpers\pycharm\teamcity\diff_tools.py", line 32, in _patched_equals|n    old(
self, first, second, msg)|n  File "C:\Users\testSite\AppData\Local\Programs\Python\Python36-32\lib\unittest\case.py", line 829, in assertEqual|n    assertion_func(first, second, msg=msg)|n  File "C:\Users\testSite\AppData\Local\Programs\Python\Python36-32\
lib\unittest\case.py", line 1202, in assertMultiLineEqual|n    self.fail(self._formatMessage(msg, standardMsg))|n  File "C:\Users\testSite\AppData\Local\Programs\Python\Python36-32\lib\unittest\case.py", line 670, in fail|n    raise self.failureException(msg)
|nAssertionError: |'a|' != |'b|'|n- a|n+ b|n|n|nDuring handling of the above exception, another exception occurred:|n|nTraceback (most recent call last):|n  File "C:\Users\testSite\AppData\Local\Programs\Python\Python36-32\lib\unittest\case.py", line 59, in t
estPartExecutor|n    yield|n  File "C:\Users\testSite\AppData\Local\Programs\Python\Python36-32\lib\unittest\case.py", line 605, in run|n    testMethod()|n  File "C:\testSiteDemoTests\site_tests.py", line 7, in test|n    self.assertEqual(|'a|', |'b|')|n' e
xpected='a' locationHint='python<C:\testSiteDemoTests>://site_tests.SiteTests.test' message='|nb != a|n' name='test' nodeId='3' parentNodeId='2' type='comparisonFailure']
##teamcity[testFinished timestamp='2018-05-20T23:59:59.977' duration='30' locationHint='python<C:\testSiteDemoTests>://site_tests.SiteTests.test' name='test' nodeId='3' parentNodeId='2']


Ran 1 test in 0.031s

FAILED (failures=1)
##teamcity[testSuiteFinished timestamp='2018-05-20T23:59:59.977' locationHint='python<C:\testSiteDemoTests>://site_tests.SiteTests' name='SiteTests' nodeId='2' parentNodeId='1']
##teamcity[testSuiteFinished timestamp='2018-05-20T23:59:59.977' locationHint='python<C:\testSiteDemoTests>://site_tests' name='site_tests' nodeId='1' parentNodeId='0']
ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
pbaranski
  • 22,778
  • 19
  • 100
  • 117

1 Answers1

2

This message shows up in exception's formatting in Python 3 if another exception was raised in an exception handler or finally clause for the first one:

A similar mechanism works implicitly if an exception is raised inside an exception handler or a finally clause: the previous exception is then attached as the new exception’s __context__ attribute

Setting a breakpoint on the test in PyCharm, then stepping further into the machinery shows where this second exception is thrown. _jb_unittest_runner patches the assert methods in unittest:

PyCharm Community Edition\helpers\pycharm\_jb_unittest_runner.py:

from teamcity import unittestpy

PyCharm Community Edition\helpers\pycharm\teamcity\unittestpy.py:

def run(self, test):
    <...>
    patch_unittest_diff(subtest_filter)
    <...>

PyCharm Community Edition\helpers\pycharm\teamcity\diff_tools.py:

def patch_unittest_diff(<...>):

    old = unittest.TestCase.assertEqual

    def _patched_equals(self, first, second, msg=None):
        try:
            old(self, first, second, msg)
            return
        except AssertionError as native_error:
            if not test_filter or test_filter(self):
                error = EqualsAssertionError(first, second, msg)
                if error.can_be_serialized():
                    raise error
            raise native_error

    unittest.TestCase.assertEqual = _patched_equals
ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
  • Is there a fix for this? – mr.bjerre Oct 23 '18 at 14:14
  • @mr.bjerre patch `_patched_equals` as per https://stackoverflow.com/questions/30235516/how-to-suppress-displaying-the-parent-exception-the-cause-for-subsequent-excep – ivan_pozdeev Oct 23 '18 at 14:31
  • Not sure if it's that simple when I run my tests using nosetests through Pycharm IDE. – mr.bjerre Oct 23 '18 at 15:11
  • @mr.bjerre Well, [go and check it out, do your homework](http://idownvotedbecau.se/nodebugging/). I wrote what you need to do to step through the test machinery to find for yourself whatever is happening. If other code than what I've cited in the answer is at play in the case of `nosetests`, this question doesn't even apply. – ivan_pozdeev Oct 23 '18 at 15:40
  • @ivan_pozdev well I have the exact same traceback so yes it does apply! I just haven't got experience patching. – mr.bjerre Oct 24 '18 at 16:25