mirror of
https://github.com/django/django.git
synced 2024-12-23 01:25:58 +00:00
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 sys
|
||||||
import textwrap
|
import textwrap
|
||||||
import unittest
|
import unittest
|
||||||
|
from contextlib import contextmanager
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
|
||||||
@ -598,12 +599,23 @@ class DiscoverRunner:
|
|||||||
setup_test_environment(debug=self.debug_mode)
|
setup_test_environment(debug=self.debug_mode)
|
||||||
unittest.installHandler()
|
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):
|
def load_tests_for_label(self, label, discover_kwargs):
|
||||||
label_as_path = os.path.abspath(label)
|
label_as_path = os.path.abspath(label)
|
||||||
tests = None
|
tests = None
|
||||||
|
|
||||||
# If a module, or "module.ClassName[.method_name]", just run those.
|
# If a module, or "module.ClassName[.method_name]", just run those.
|
||||||
if not os.path.exists(label_as_path):
|
if not os.path.exists(label_as_path):
|
||||||
|
with self.load_with_patterns():
|
||||||
tests = self.test_loader.loadTestsFromName(label)
|
tests = self.test_loader.loadTestsFromName(label)
|
||||||
if tests.countTestCases():
|
if tests.countTestCases():
|
||||||
return tests
|
return tests
|
||||||
@ -626,6 +638,7 @@ class DiscoverRunner:
|
|||||||
if os.path.isdir(label_as_path) and not self.top_level:
|
if os.path.isdir(label_as_path) and not self.top_level:
|
||||||
kwargs['top_level_dir'] = find_top_level(label_as_path)
|
kwargs['top_level_dir'] = find_top_level(label_as_path)
|
||||||
|
|
||||||
|
with self.load_with_patterns():
|
||||||
tests = self.test_loader.discover(start_dir=label, **kwargs)
|
tests = self.test_loader.discover(start_dir=label, **kwargs)
|
||||||
|
|
||||||
# Make unittest forget the top-level dir it calculated from this run,
|
# Make unittest forget the top-level dir it calculated from this run,
|
||||||
@ -636,7 +649,6 @@ class DiscoverRunner:
|
|||||||
def build_suite(self, test_labels=None, extra_tests=None, **kwargs):
|
def build_suite(self, test_labels=None, extra_tests=None, **kwargs):
|
||||||
test_labels = test_labels or ['.']
|
test_labels = test_labels or ['.']
|
||||||
extra_tests = extra_tests or []
|
extra_tests = extra_tests or []
|
||||||
self.test_loader.testNamePatterns = self.test_name_patterns
|
|
||||||
|
|
||||||
discover_kwargs = {}
|
discover_kwargs = {}
|
||||||
if self.pattern is not None:
|
if self.pattern is not None:
|
||||||
|
@ -26,6 +26,16 @@ def change_cwd(directory):
|
|||||||
os.chdir(old_cwd)
|
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):
|
class DiscoverRunnerTests(SimpleTestCase):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -122,6 +132,28 @@ class DiscoverRunnerTests(SimpleTestCase):
|
|||||||
).build_suite(['test_runner_apps.simple'])
|
).build_suite(['test_runner_apps.simple'])
|
||||||
self.assertEqual(expected, self.get_test_methods_names(suite))
|
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):
|
def test_file_path(self):
|
||||||
with change_cwd(".."):
|
with change_cwd(".."):
|
||||||
count = DiscoverRunner(verbosity=0).build_suite(
|
count = DiscoverRunner(verbosity=0).build_suite(
|
||||||
|
Loading…
Reference in New Issue
Block a user