summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2015-03-18 22:56:46 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2015-03-18 22:56:46 (GMT)
commitd833779ceaebeb29352488ffddabf5fc2f070364 (patch)
tree83ff79a3d53920897701d6180472e40ec4e72e93
parentc4c19b39381460a2353c2789f13fa2bb1ab565c1 (diff)
downloadcpython-d833779ceaebeb29352488ffddabf5fc2f070364.zip
cpython-d833779ceaebeb29352488ffddabf5fc2f070364.tar.gz
cpython-d833779ceaebeb29352488ffddabf5fc2f070364.tar.bz2
Issue #22903: The fake test case created by unittest.loader when it fails importing a test module is now picklable.
-rw-r--r--Lib/unittest/loader.py29
-rw-r--r--Lib/unittest/test/test_discovery.py9
-rw-r--r--Misc/NEWS3
3 files changed, 32 insertions, 9 deletions
diff --git a/Lib/unittest/loader.py b/Lib/unittest/loader.py
index 808c50e..af39216 100644
--- a/Lib/unittest/loader.py
+++ b/Lib/unittest/loader.py
@@ -19,20 +19,31 @@ __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)
+ return _make_failed_test(name, ImportError(message), suiteClass)
def _make_failed_load_tests(name, exception, suiteClass):
- return _make_failed_test('LoadTestsFailure', name, exception, suiteClass)
+ return _make_failed_test(name, exception, suiteClass)
-def _make_failed_test(classname, methodname, exception, suiteClass):
- def testFailure(self):
- raise exception
- attrs = {methodname: testFailure}
- TestClass = type(classname, (case.TestCase,), attrs)
- return suiteClass((TestClass(methodname),))
+def _make_failed_test(methodname, exception, suiteClass):
+ test = _FailedTest(methodname, exception)
+ return suiteClass((test,))
def _make_skipped_test(methodname, exception, suiteClass):
@case.skip(str(exception))
diff --git a/Lib/unittest/test/test_discovery.py b/Lib/unittest/test/test_discovery.py
index abb9066..f12e898 100644
--- a/Lib/unittest/test/test_discovery.py
+++ b/Lib/unittest/test/test_discovery.py
@@ -2,6 +2,7 @@ import os
import re
import sys
import types
+import pickle
import builtins
from test import support
@@ -216,6 +217,10 @@ class TestDiscovery(unittest.TestCase):
with self.assertRaises(ImportError):
test.test_this_does_not_exist()
+ # 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()
@@ -232,6 +237,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_command_line_handling_parseArgs(self):
program = TestableTestProgram()
diff --git a/Misc/NEWS b/Misc/NEWS
index 90edc96..2ec41cd 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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 #23568: Add rdivmod support to MagicMock() objects.
Patch by Håkan Lövdahl.