Commit c977f121 authored by Antoine Pitrou's avatar Antoine Pitrou

Issue #22903: The fake test case created by unittest.loader when it fails...

Issue #22903: The fake test case created by unittest.loader when it fails importing a test module is now picklable.
parents c6560364 3eb495d3
......@@ -20,23 +20,34 @@ __unittest = True
VALID_MODULE_NAME = re.compile(r'[_a-z]\w*\.py$', re.IGNORECASE)
class _FailedTest(case.TestCase):
_testMethodName = None
def __init__(self, method_name, exception):
self._exception = exception
super(_FailedTest, self).__init__(method_name)
def __getattr__(self, name):
if name != self._testMethodName:
return super(_FailedTest, self).__getattr__(name)
def testFailure():
raise self._exception
return testFailure
def _make_failed_import_test(name, suiteClass):
message = 'Failed to import test module: %s\n%s' % (
name, traceback.format_exc())
return _make_failed_test('ModuleImportFailure', name, ImportError(message),
suiteClass, message)
return _make_failed_test(name, ImportError(message), suiteClass, message)
def _make_failed_load_tests(name, exception, suiteClass):
message = 'Failed to call load_tests:\n%s' % (traceback.format_exc(),)
return _make_failed_test(
'LoadTestsFailure', name, exception, suiteClass, message)
name, exception, suiteClass, message)
def _make_failed_test(classname, methodname, exception, suiteClass, message):
def testFailure(self):
raise exception
attrs = {methodname: testFailure}
TestClass = type(classname, (case.TestCase,), attrs)
return suiteClass((TestClass(methodname),)), message
def _make_failed_test(methodname, exception, suiteClass, message):
test = _FailedTest(methodname, exception)
return suiteClass((test,)), message
def _make_skipped_test(methodname, exception, suiteClass):
@case.skip(str(exception))
......@@ -169,7 +180,7 @@ class TestLoader(object):
else:
# Otherwise, we signal that an AttributeError has occurred.
error_case, error_message = _make_failed_test(
'AttributeError', part, e, self.suiteClass,
part, e, self.suiteClass,
'Failed to access attribute:\n%s' % (
traceback.format_exc(),))
self.errors.append(error_message)
......
......@@ -3,6 +3,7 @@ from os.path import abspath
import re
import sys
import types
import pickle
import builtins
from test import support
......@@ -482,6 +483,10 @@ class TestDiscovery(unittest.TestCase):
test.my_package()
self.assertEqual(import_calls, ['my_package'])
# Check picklability
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
pickle.loads(pickle.dumps(test, proto))
def test_discover_with_module_that_raises_SkipTest_on_import(self):
loader = unittest.TestLoader()
......@@ -498,6 +503,10 @@ class TestDiscovery(unittest.TestCase):
suite.run(result)
self.assertEqual(len(result.skipped), 1)
# Check picklability
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
pickle.loads(pickle.dumps(suite, proto))
def test_discover_with_init_module_that_raises_SkipTest_on_import(self):
vfs = {abspath('/foo'): ['my_package'],
abspath('/foo/my_package'): ['__init__.py', 'test_module.py']}
......@@ -518,6 +527,10 @@ class TestDiscovery(unittest.TestCase):
self.assertEqual(result.testsRun, 1)
self.assertEqual(import_calls, ['my_package'])
# Check picklability
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
pickle.loads(pickle.dumps(suite, proto))
def test_command_line_handling_parseArgs(self):
program = TestableTestProgram()
......
......@@ -18,6 +18,9 @@ Core and Builtins
Library
-------
- Issue #22903: The fake test case created by unittest.loader when it fails
importing a test module is now picklable.
- Issue #22181: On Linux, os.urandom() now uses the new getrandom() syscall if
available, syscall introduced in the Linux kernel 3.17. It is more reliable
and more secure, because it avoids the need of a file descriptor and waits
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment