Than21
Than21

Reputation: 321

Python unittest expected failures ignored in Python3

I would like to upgrade my python test harness - which is based on Python's unittest module - from Python2 to Python3. However, the unittest.expectedFailure decorator doesn't seem to have the same effect anymore. In particular, the following code has different behavior depending on the Python version even though the specifications are virtually identical:

#!/usr/bin/env python2
#!/usr/bin/env python3
# Switch between the two lines above to get the different outcome

import unittest

class ComparisonTests(unittest.TestCase):

    def runTest(self):
        """ This method is needed even if empty """

    def add_test(self, the_suite):
        def testMain():
            self.testFunc()
        testMain = unittest.expectedFailure(testMain)
        the_case = unittest.FunctionTestCase(testMain)
        the_suite.addTest(the_case)

    def testFunc(self):
        self.assertTrue(False)

if __name__ == '__main__':
    SUITE = unittest.TestSuite()
    ComparisonTests().add_test(SUITE)

    the_runner = unittest.TextTestRunner(verbosity=2)
    the_runner.run(SUITE)

If I keep the first line (#!/usr/bin/env python2) and run on MacOS 10.14.1 and Python 2.7.15 then the output is the following:

unittest.case.FunctionTestCase (testMain) ... expected failure

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

OK (expected failures=1)

This is the behavior I expect. However, if I switch to the second line (#!/usr/bin/env python3) which will use Python 3.7.3 I get the following:

unittest.case.FunctionTestCase (testMain) ... FAIL

======================================================================
FAIL: unittest.case.FunctionTestCase (testMain)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./unittest_test_2.py", line 12, in testMain
    self.testFunc()
  File "./unittest_test_2.py", line 18, in testFunc
    self.assertTrue(False)
AssertionError: False is not true

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

FAILED (failures=1)

It looks like the unittest.expectedFailure decorator was ignored. Looking at the source code I can see a clear difference:

# Python 3.7 source:
def expectedFailure(test_item):
    test_item.__unittest_expecting_failure__ = True
    return test_item

# Python 2.7 source:
def expectedFailure(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        try:
            func(*args, **kwargs)
        except Exception:
            raise _ExpectedFailure(sys.exc_info())
        raise _UnexpectedSuccess
    return wrapper

How can I define expected failures in the Python3 version of unittest ?

Upvotes: 3

Views: 1026

Answers (1)

Than21
Than21

Reputation: 321

The Python 3 version of the unittest.expectedFailure decorator is expected to operate on a unittest test case and not on a method as it did in Python 2. So in order for the above test harness to work with Python 3 one needs to use the expectedFalure decorator on the_case as follows:

the_case = unittest.FunctionTestCase(testMain)
the_case = unittest.expectedFailure(the_case)

Upvotes: 1

Related Questions