Reputation: 321
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
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