Fixed #32808 -- Prevented DiscoverRunner.build_suite() from mutating test loader patterns.
Thanks Chris Jerdonek for the report and reviews.
This commit is contained in:
parent
f0d0d29f03
commit
62e8f369c3
|
@ -9,6 +9,7 @@ import pickle
|
|||
import sys
|
||||
import textwrap
|
||||
import unittest
|
||||
from contextlib import contextmanager
|
||||
from importlib import import_module
|
||||
from io import StringIO
|
||||
|
||||
|
@ -598,13 +599,24 @@ class DiscoverRunner:
|
|||
setup_test_environment(debug=self.debug_mode)
|
||||
unittest.installHandler()
|
||||
|
||||
@contextmanager
|
||||
def load_with_patterns(self):
|
||||
original_test_name_patterns = self.test_loader.testNamePatterns
|
||||
self.test_loader.testNamePatterns = self.test_name_patterns
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
# Restore the original patterns.
|
||||
self.test_loader.testNamePatterns = original_test_name_patterns
|
||||
|
||||
def load_tests_for_label(self, label, discover_kwargs):
|
||||
label_as_path = os.path.abspath(label)
|
||||
tests = None
|
||||
|
||||
# If a module, or "module.ClassName[.method_name]", just run those.
|
||||
if not os.path.exists(label_as_path):
|
||||
tests = self.test_loader.loadTestsFromName(label)
|
||||
with self.load_with_patterns():
|
||||
tests = self.test_loader.loadTestsFromName(label)
|
||||
if tests.countTestCases():
|
||||
return tests
|
||||
# Try discovery if "label" is a package or directory.
|
||||
|
@ -626,7 +638,8 @@ class DiscoverRunner:
|
|||
if os.path.isdir(label_as_path) and not self.top_level:
|
||||
kwargs['top_level_dir'] = find_top_level(label_as_path)
|
||||
|
||||
tests = self.test_loader.discover(start_dir=label, **kwargs)
|
||||
with self.load_with_patterns():
|
||||
tests = self.test_loader.discover(start_dir=label, **kwargs)
|
||||
|
||||
# Make unittest forget the top-level dir it calculated from this run,
|
||||
# to support running tests from two different top-levels.
|
||||
|
@ -636,7 +649,6 @@ class DiscoverRunner:
|
|||
def build_suite(self, test_labels=None, extra_tests=None, **kwargs):
|
||||
test_labels = test_labels or ['.']
|
||||
extra_tests = extra_tests or []
|
||||
self.test_loader.testNamePatterns = self.test_name_patterns
|
||||
|
||||
discover_kwargs = {}
|
||||
if self.pattern is not None:
|
||||
|
|
|
@ -26,6 +26,16 @@ def change_cwd(directory):
|
|||
os.chdir(old_cwd)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def change_loader_patterns(patterns):
|
||||
original_patterns = DiscoverRunner.test_loader.testNamePatterns
|
||||
DiscoverRunner.test_loader.testNamePatterns = patterns
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
DiscoverRunner.test_loader.testNamePatterns = original_patterns
|
||||
|
||||
|
||||
class DiscoverRunnerTests(SimpleTestCase):
|
||||
|
||||
@staticmethod
|
||||
|
@ -122,6 +132,28 @@ class DiscoverRunnerTests(SimpleTestCase):
|
|||
).build_suite(['test_runner_apps.simple'])
|
||||
self.assertEqual(expected, self.get_test_methods_names(suite))
|
||||
|
||||
def test_loader_patterns_not_mutated(self):
|
||||
runner = DiscoverRunner(test_name_patterns=['test_sample'], verbosity=0)
|
||||
tests = [
|
||||
('test_runner_apps.sample.tests', 1),
|
||||
('test_runner_apps.sample.tests.Test.test_sample', 1),
|
||||
('test_runner_apps.sample.empty', 0),
|
||||
('test_runner_apps.sample.tests_sample.EmptyTestCase', 0),
|
||||
]
|
||||
for test_labels, tests_count in tests:
|
||||
with self.subTest(test_labels=test_labels):
|
||||
with change_loader_patterns(['UnittestCase1']):
|
||||
count = runner.build_suite([test_labels]).countTestCases()
|
||||
self.assertEqual(count, tests_count)
|
||||
self.assertEqual(runner.test_loader.testNamePatterns, ['UnittestCase1'])
|
||||
|
||||
def test_loader_patterns_not_mutated_when_test_label_is_file_path(self):
|
||||
runner = DiscoverRunner(test_name_patterns=['test_sample'], verbosity=0)
|
||||
with change_cwd('.'), change_loader_patterns(['UnittestCase1']):
|
||||
with self.assertRaises(RuntimeError):
|
||||
runner.build_suite(['test_discover_runner.py'])
|
||||
self.assertEqual(runner.test_loader.testNamePatterns, ['UnittestCase1'])
|
||||
|
||||
def test_file_path(self):
|
||||
with change_cwd(".."):
|
||||
count = DiscoverRunner(verbosity=0).build_suite(
|
||||
|
|
Loading…
Reference in New Issue