From 8bca838f4a230b78dd44fc1db3c1b81e444c6099 Mon Sep 17 00:00:00 2001 From: Chris Jerdonek Date: Tue, 29 Jun 2021 13:02:57 -0400 Subject: [PATCH] Refs #32655 -- Improved error if iter_test_cases() is passed a string. --- django/test/utils.py | 7 +++++++ tests/test_runner/tests.py | 10 +++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/django/test/utils.py b/django/test/utils.py index e977db8a10..81005d4f8f 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -242,6 +242,13 @@ def iter_test_cases(tests): The tests argument can also be an iterable of TestCase objects. """ for test in tests: + if isinstance(test, str): + # Prevent an unfriendly RecursionError that can happen with + # strings. + raise TypeError( + f'Test {test!r} must be a test case or test suite not string ' + f'(was found in {tests!r}).' + ) if isinstance(test, TestCase): yield test else: diff --git a/tests/test_runner/tests.py b/tests/test_runner/tests.py index 7479b80ef1..6348569dfc 100644 --- a/tests/test_runner/tests.py +++ b/tests/test_runner/tests.py @@ -36,7 +36,7 @@ class MySuite: yield from self.tests -class TestSuiteTests(unittest.TestCase): +class TestSuiteTests(SimpleTestCase): def build_test_suite(self, test_classes, suite=None, suite_class=None): if suite_class is None: suite_class = unittest.TestSuite @@ -89,6 +89,14 @@ class TestSuiteTests(unittest.TestCase): 'Tests1.test1', 'Tests1.test2', 'Tests2.test1', 'Tests2.test2', ]) + def test_iter_test_cases_string_input(self): + msg = ( + "Test 'a' must be a test case or test suite not string (was found " + "in 'abc')." + ) + with self.assertRaisesMessage(TypeError, msg): + list(iter_test_cases('abc')) + def test_iter_test_cases_iterable_of_tests(self): class Tests(unittest.TestCase): def test1(self):