mirror of
https://github.com/python/cpython.git
synced 2025-09-27 10:50:04 +00:00
[3.12] gh-84867: Do not load tests from TestCase and FunctionTestCase (GH-100497) (#109327)
gh-84867: Do not load tests from TestCase and FunctionTestCase (GH-100497)
(cherry picked from commit 66d1d7eb06
)
Co-authored-by: Nikita Sobolev <mail@sobolevn.me>
This commit is contained in:
parent
a8431123c2
commit
2fb39f73ed
3 changed files with 48 additions and 5 deletions
|
@ -82,6 +82,22 @@ class Test_TestLoader(unittest.TestCase):
|
||||||
self.assertIsInstance(suite, loader.suiteClass)
|
self.assertIsInstance(suite, loader.suiteClass)
|
||||||
self.assertEqual(list(suite), [Foo('runTest')])
|
self.assertEqual(list(suite), [Foo('runTest')])
|
||||||
|
|
||||||
|
# "Do not load any tests from `TestCase` class itself."
|
||||||
|
def test_loadTestsFromTestCase__from_TestCase(self):
|
||||||
|
loader = unittest.TestLoader()
|
||||||
|
|
||||||
|
suite = loader.loadTestsFromTestCase(unittest.TestCase)
|
||||||
|
self.assertIsInstance(suite, loader.suiteClass)
|
||||||
|
self.assertEqual(list(suite), [])
|
||||||
|
|
||||||
|
# "Do not load any tests from `FunctionTestCase` class."
|
||||||
|
def test_loadTestsFromTestCase__from_FunctionTestCase(self):
|
||||||
|
loader = unittest.TestLoader()
|
||||||
|
|
||||||
|
suite = loader.loadTestsFromTestCase(unittest.FunctionTestCase)
|
||||||
|
self.assertIsInstance(suite, loader.suiteClass)
|
||||||
|
self.assertEqual(list(suite), [])
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
### /Tests for TestLoader.loadTestsFromTestCase
|
### /Tests for TestLoader.loadTestsFromTestCase
|
||||||
|
|
||||||
|
@ -103,6 +119,19 @@ class Test_TestLoader(unittest.TestCase):
|
||||||
expected = [loader.suiteClass([MyTestCase('test')])]
|
expected = [loader.suiteClass([MyTestCase('test')])]
|
||||||
self.assertEqual(list(suite), expected)
|
self.assertEqual(list(suite), expected)
|
||||||
|
|
||||||
|
# "This test ensures that internal `TestCase` subclasses are not loaded"
|
||||||
|
def test_loadTestsFromModule__TestCase_subclass_internals(self):
|
||||||
|
# See https://github.com/python/cpython/issues/84867
|
||||||
|
m = types.ModuleType('m')
|
||||||
|
# Simulate imported names:
|
||||||
|
m.TestCase = unittest.TestCase
|
||||||
|
m.FunctionTestCase = unittest.FunctionTestCase
|
||||||
|
|
||||||
|
loader = unittest.TestLoader()
|
||||||
|
suite = loader.loadTestsFromModule(m)
|
||||||
|
self.assertIsInstance(suite, loader.suiteClass)
|
||||||
|
self.assertEqual(list(suite), [])
|
||||||
|
|
||||||
# "This method searches `module` for classes derived from TestCase"
|
# "This method searches `module` for classes derived from TestCase"
|
||||||
#
|
#
|
||||||
# What happens if no tests are found (no TestCase instances)?
|
# What happens if no tests are found (no TestCase instances)?
|
||||||
|
|
|
@ -84,9 +84,13 @@ class TestLoader(object):
|
||||||
raise TypeError("Test cases should not be derived from "
|
raise TypeError("Test cases should not be derived from "
|
||||||
"TestSuite. Maybe you meant to derive from "
|
"TestSuite. Maybe you meant to derive from "
|
||||||
"TestCase?")
|
"TestCase?")
|
||||||
testCaseNames = self.getTestCaseNames(testCaseClass)
|
if testCaseClass in (case.TestCase, case.FunctionTestCase):
|
||||||
if not testCaseNames and hasattr(testCaseClass, 'runTest'):
|
# We don't load any tests from base types that should not be loaded.
|
||||||
testCaseNames = ['runTest']
|
testCaseNames = []
|
||||||
|
else:
|
||||||
|
testCaseNames = self.getTestCaseNames(testCaseClass)
|
||||||
|
if not testCaseNames and hasattr(testCaseClass, 'runTest'):
|
||||||
|
testCaseNames = ['runTest']
|
||||||
loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
|
loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
|
||||||
return loaded_suite
|
return loaded_suite
|
||||||
|
|
||||||
|
@ -95,7 +99,11 @@ class TestLoader(object):
|
||||||
tests = []
|
tests = []
|
||||||
for name in dir(module):
|
for name in dir(module):
|
||||||
obj = getattr(module, name)
|
obj = getattr(module, name)
|
||||||
if isinstance(obj, type) and issubclass(obj, case.TestCase):
|
if (
|
||||||
|
isinstance(obj, type)
|
||||||
|
and issubclass(obj, case.TestCase)
|
||||||
|
and obj not in (case.TestCase, case.FunctionTestCase)
|
||||||
|
):
|
||||||
tests.append(self.loadTestsFromTestCase(obj))
|
tests.append(self.loadTestsFromTestCase(obj))
|
||||||
|
|
||||||
load_tests = getattr(module, 'load_tests', None)
|
load_tests = getattr(module, 'load_tests', None)
|
||||||
|
@ -164,7 +172,11 @@ class TestLoader(object):
|
||||||
|
|
||||||
if isinstance(obj, types.ModuleType):
|
if isinstance(obj, types.ModuleType):
|
||||||
return self.loadTestsFromModule(obj)
|
return self.loadTestsFromModule(obj)
|
||||||
elif isinstance(obj, type) and issubclass(obj, case.TestCase):
|
elif (
|
||||||
|
isinstance(obj, type)
|
||||||
|
and issubclass(obj, case.TestCase)
|
||||||
|
and obj not in (case.TestCase, case.FunctionTestCase)
|
||||||
|
):
|
||||||
return self.loadTestsFromTestCase(obj)
|
return self.loadTestsFromTestCase(obj)
|
||||||
elif (isinstance(obj, types.FunctionType) and
|
elif (isinstance(obj, types.FunctionType) and
|
||||||
isinstance(parent, type) and
|
isinstance(parent, type) and
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
:class:`unittest.TestLoader` no longer loads test cases from exact
|
||||||
|
:class:`unittest.TestCase` and :class:`unittest.FunctionTestCase` classes.
|
Loading…
Add table
Add a link
Reference in a new issue