diff options
author | django-bot <ops@djangoproject.com> | 2022-02-03 20:24:19 +0100 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2022-02-07 20:37:05 +0100 |
commit | 9c19aff7c7561e3a82978a272ecdaad40dda5c00 (patch) | |
tree | f0506b668a013d0063e5fba3dbf4863b466713ba /tests/test_runner | |
parent | f68fa8b45dfac545cfc4111d4e52804c86db68d3 (diff) | |
download | django-9c19aff7c7561e3a82978a272ecdaad40dda5c00.tar.gz |
Refs #33476 -- Reformatted code with Black.
Diffstat (limited to 'tests/test_runner')
-rw-r--r-- | tests/test_runner/models.py | 4 | ||||
-rw-r--r-- | tests/test_runner/runner.py | 23 | ||||
-rw-r--r-- | tests/test_runner/test_debug_sql.py | 79 | ||||
-rw-r--r-- | tests/test_runner/test_discover_runner.py | 557 | ||||
-rw-r--r-- | tests/test_runner/test_parallel.py | 27 | ||||
-rw-r--r-- | tests/test_runner/test_shuffler.py | 59 | ||||
-rw-r--r-- | tests/test_runner/tests.py | 734 |
7 files changed, 880 insertions, 603 deletions
diff --git a/tests/test_runner/models.py b/tests/test_runner/models.py index 9b26dbfc1e..80bf8dd8c7 100644 --- a/tests/test_runner/models.py +++ b/tests/test_runner/models.py @@ -4,13 +4,13 @@ from django.db import models class Person(models.Model): first_name = models.CharField(max_length=20) last_name = models.CharField(max_length=20) - friends = models.ManyToManyField('self') + friends = models.ManyToManyField("self") # A set of models that use a non-abstract inherited 'through' model. class ThroughBase(models.Model): person = models.ForeignKey(Person, models.CASCADE) - b = models.ForeignKey('B', models.CASCADE) + b = models.ForeignKey("B", models.CASCADE) class Through(ThroughBase): diff --git a/tests/test_runner/runner.py b/tests/test_runner/runner.py index 46660d690b..5c34b343d9 100644 --- a/tests/test_runner/runner.py +++ b/tests/test_runner/runner.py @@ -2,19 +2,28 @@ from django.test.runner import DiscoverRunner class CustomOptionsTestRunner(DiscoverRunner): - - def __init__(self, verbosity=1, interactive=True, failfast=True, - option_a=None, option_b=None, option_c=None, **kwargs): - super().__init__(verbosity=verbosity, interactive=interactive, failfast=failfast) + def __init__( + self, + verbosity=1, + interactive=True, + failfast=True, + option_a=None, + option_b=None, + option_c=None, + **kwargs, + ): + super().__init__( + verbosity=verbosity, interactive=interactive, failfast=failfast + ) self.option_a = option_a self.option_b = option_b self.option_c = option_c @classmethod def add_arguments(cls, parser): - parser.add_argument('--option_a', '-a', default='1'), - parser.add_argument('--option_b', '-b', default='2'), - parser.add_argument('--option_c', '-c', default='3'), + parser.add_argument("--option_a", "-a", default="1"), + parser.add_argument("--option_b", "-b", default="2"), + parser.add_argument("--option_c", "-c", default="3"), def run_tests(self, test_labels, **kwargs): print("%s:%s:%s" % (self.option_a, self.option_b, self.option_c)) diff --git a/tests/test_runner/test_debug_sql.py b/tests/test_runner/test_debug_sql.py index 0e8e4207d6..9957295f01 100644 --- a/tests/test_runner/test_debug_sql.py +++ b/tests/test_runner/test_debug_sql.py @@ -8,21 +8,22 @@ from django.test.runner import DiscoverRunner from .models import Person -@unittest.skipUnless(connection.vendor == 'sqlite', 'Only run on sqlite so we can check output SQL.') +@unittest.skipUnless( + connection.vendor == "sqlite", "Only run on sqlite so we can check output SQL." +) class TestDebugSQL(unittest.TestCase): - class PassingTest(TestCase): def runTest(self): - Person.objects.filter(first_name='pass').count() + Person.objects.filter(first_name="pass").count() class FailingTest(TestCase): def runTest(self): - Person.objects.filter(first_name='fail').count() + Person.objects.filter(first_name="fail").count() self.fail() class ErrorTest(TestCase): def runTest(self): - Person.objects.filter(first_name='error').count() + Person.objects.filter(first_name="error").count() raise Exception class ErrorSetUpTestDataTest(TestCase): @@ -36,18 +37,18 @@ class TestDebugSQL(unittest.TestCase): class PassingSubTest(TestCase): def runTest(self): with self.subTest(): - Person.objects.filter(first_name='subtest-pass').count() + Person.objects.filter(first_name="subtest-pass").count() class FailingSubTest(TestCase): def runTest(self): with self.subTest(): - Person.objects.filter(first_name='subtest-fail').count() + Person.objects.filter(first_name="subtest-fail").count() self.fail() class ErrorSubTest(TestCase): def runTest(self): with self.subTest(): - Person.objects.filter(first_name='subtest-error').count() + Person.objects.filter(first_name="subtest-error").count() raise Exception def _test_output(self, verbosity): @@ -86,34 +87,46 @@ class TestDebugSQL(unittest.TestCase): self.assertIn(output, full_output) expected_outputs = [ - ('''SELECT COUNT(*) AS "__count" ''' - '''FROM "test_runner_person" WHERE ''' - '''"test_runner_person"."first_name" = 'error';'''), - ('''SELECT COUNT(*) AS "__count" ''' - '''FROM "test_runner_person" WHERE ''' - '''"test_runner_person"."first_name" = 'fail';'''), - ('''SELECT COUNT(*) AS "__count" ''' - '''FROM "test_runner_person" WHERE ''' - '''"test_runner_person"."first_name" = 'subtest-error';'''), - ('''SELECT COUNT(*) AS "__count" ''' - '''FROM "test_runner_person" WHERE ''' - '''"test_runner_person"."first_name" = 'subtest-fail';'''), + ( + """SELECT COUNT(*) AS "__count" """ + """FROM "test_runner_person" WHERE """ + """"test_runner_person"."first_name" = 'error';""" + ), + ( + """SELECT COUNT(*) AS "__count" """ + """FROM "test_runner_person" WHERE """ + """"test_runner_person"."first_name" = 'fail';""" + ), + ( + """SELECT COUNT(*) AS "__count" """ + """FROM "test_runner_person" WHERE """ + """"test_runner_person"."first_name" = 'subtest-error';""" + ), + ( + """SELECT COUNT(*) AS "__count" """ + """FROM "test_runner_person" WHERE """ + """"test_runner_person"."first_name" = 'subtest-fail';""" + ), ] verbose_expected_outputs = [ - 'runTest (test_runner.test_debug_sql.TestDebugSQL.FailingTest) ... FAIL', - 'runTest (test_runner.test_debug_sql.TestDebugSQL.ErrorTest) ... ERROR', - 'runTest (test_runner.test_debug_sql.TestDebugSQL.PassingTest) ... ok', + "runTest (test_runner.test_debug_sql.TestDebugSQL.FailingTest) ... FAIL", + "runTest (test_runner.test_debug_sql.TestDebugSQL.ErrorTest) ... ERROR", + "runTest (test_runner.test_debug_sql.TestDebugSQL.PassingTest) ... ok", # If there are errors/failures in subtests but not in test itself, # the status is not written. That behavior comes from Python. - 'runTest (test_runner.test_debug_sql.TestDebugSQL.FailingSubTest) ...', - 'runTest (test_runner.test_debug_sql.TestDebugSQL.ErrorSubTest) ...', - ('''SELECT COUNT(*) AS "__count" ''' - '''FROM "test_runner_person" WHERE ''' - '''"test_runner_person"."first_name" = 'pass';'''), - ('''SELECT COUNT(*) AS "__count" ''' - '''FROM "test_runner_person" WHERE ''' - '''"test_runner_person"."first_name" = 'subtest-pass';'''), + "runTest (test_runner.test_debug_sql.TestDebugSQL.FailingSubTest) ...", + "runTest (test_runner.test_debug_sql.TestDebugSQL.ErrorSubTest) ...", + ( + """SELECT COUNT(*) AS "__count" """ + """FROM "test_runner_person" WHERE """ + """"test_runner_person"."first_name" = 'pass';""" + ), + ( + """SELECT COUNT(*) AS "__count" """ + """FROM "test_runner_person" WHERE """ + """"test_runner_person"."first_name" = 'subtest-pass';""" + ), ] def test_setupclass_exception(self): @@ -130,7 +143,7 @@ class TestDebugSQL(unittest.TestCase): runner.teardown_databases(old_config) output = stream.getvalue() self.assertIn( - 'ERROR: setUpClass ' - '(test_runner.test_debug_sql.TestDebugSQL.ErrorSetUpTestDataTest)', + "ERROR: setUpClass " + "(test_runner.test_debug_sql.TestDebugSQL.ErrorSetUpTestDataTest)", output, ) diff --git a/tests/test_runner/test_discover_runner.py b/tests/test_runner/test_discover_runner.py index dedc36aeb7..f264ad52f8 100644 --- a/tests/test_runner/test_discover_runner.py +++ b/tests/test_runner/test_discover_runner.py @@ -11,7 +11,10 @@ from django.db import connections from django.test import SimpleTestCase from django.test.runner import DiscoverRunner, get_max_test_processes from django.test.utils import ( - NullTimeKeeper, TimeKeeper, captured_stderr, captured_stdout, + NullTimeKeeper, + TimeKeeper, + captured_stderr, + captured_stdout, ) @@ -39,9 +42,9 @@ def change_loader_patterns(patterns): # Isolate from the real environment. @mock.patch.dict(os.environ, {}, clear=True) -@mock.patch.object(multiprocessing, 'cpu_count', return_value=12) +@mock.patch.object(multiprocessing, "cpu_count", return_value=12) # Python 3.8 on macOS defaults to 'spawn' mode. -@mock.patch.object(multiprocessing, 'get_start_method', return_value='fork') +@mock.patch.object(multiprocessing, "get_start_method", return_value="fork") class DiscoverRunnerParallelArgumentTests(SimpleTestCase): def get_parser(self): parser = ArgumentParser() @@ -53,47 +56,45 @@ class DiscoverRunnerParallelArgumentTests(SimpleTestCase): self.assertEqual(result.parallel, 0) def test_parallel_flag(self, *mocked_objects): - result = self.get_parser().parse_args(['--parallel']) - self.assertEqual(result.parallel, 'auto') + result = self.get_parser().parse_args(["--parallel"]) + self.assertEqual(result.parallel, "auto") def test_parallel_auto(self, *mocked_objects): - result = self.get_parser().parse_args(['--parallel', 'auto']) - self.assertEqual(result.parallel, 'auto') + result = self.get_parser().parse_args(["--parallel", "auto"]) + self.assertEqual(result.parallel, "auto") def test_parallel_count(self, *mocked_objects): - result = self.get_parser().parse_args(['--parallel', '17']) + result = self.get_parser().parse_args(["--parallel", "17"]) self.assertEqual(result.parallel, 17) def test_parallel_invalid(self, *mocked_objects): with self.assertRaises(SystemExit), captured_stderr() as stderr: - self.get_parser().parse_args(['--parallel', 'unaccepted']) + self.get_parser().parse_args(["--parallel", "unaccepted"]) msg = "argument --parallel: 'unaccepted' is not an integer or the string 'auto'" self.assertIn(msg, stderr.getvalue()) def test_get_max_test_processes(self, *mocked_objects): self.assertEqual(get_max_test_processes(), 12) - @mock.patch.dict(os.environ, {'DJANGO_TEST_PROCESSES': '7'}) + @mock.patch.dict(os.environ, {"DJANGO_TEST_PROCESSES": "7"}) def test_get_max_test_processes_env_var(self, *mocked_objects): self.assertEqual(get_max_test_processes(), 7) def test_get_max_test_processes_spawn( - self, mocked_get_start_method, mocked_cpu_count, + self, + mocked_get_start_method, + mocked_cpu_count, ): - mocked_get_start_method.return_value = 'spawn' + mocked_get_start_method.return_value = "spawn" self.assertEqual(get_max_test_processes(), 1) - with mock.patch.dict(os.environ, {'DJANGO_TEST_PROCESSES': '7'}): + with mock.patch.dict(os.environ, {"DJANGO_TEST_PROCESSES": "7"}): self.assertEqual(get_max_test_processes(), 1) class DiscoverRunnerTests(SimpleTestCase): - @staticmethod def get_test_methods_names(suite): - return [ - t.__class__.__name__ + '.' + t._testMethodName - for t in suite._tests - ] + return [t.__class__.__name__ + "." + t._testMethodName for t in suite._tests] def test_init_debug_mode(self): runner = DiscoverRunner() @@ -104,9 +105,9 @@ class DiscoverRunnerTests(SimpleTestCase): DiscoverRunner.add_arguments(parser) ns = parser.parse_args([]) self.assertIs(ns.shuffle, False) - ns = parser.parse_args(['--shuffle']) + ns = parser.parse_args(["--shuffle"]) self.assertIsNone(ns.shuffle) - ns = parser.parse_args(['--shuffle', '5']) + ns = parser.parse_args(["--shuffle", "5"]) self.assertEqual(ns.shuffle, 5) def test_add_arguments_debug_mode(self): @@ -127,10 +128,10 @@ class DiscoverRunnerTests(SimpleTestCase): def test_setup_shuffler_shuffle_none(self): runner = DiscoverRunner(shuffle=None) self.assertIsNone(runner.shuffle) - with mock.patch('random.randint', return_value=1): + with mock.patch("random.randint", return_value=1): with captured_stdout() as stdout: runner.setup_shuffler() - self.assertEqual(stdout.getvalue(), 'Using shuffle seed: 1 (generated)\n') + self.assertEqual(stdout.getvalue(), "Using shuffle seed: 1 (generated)\n") self.assertEqual(runner.shuffle_seed, 1) def test_setup_shuffler_shuffle_int(self): @@ -138,111 +139,143 @@ class DiscoverRunnerTests(SimpleTestCase): self.assertEqual(runner.shuffle, 2) with captured_stdout() as stdout: runner.setup_shuffler() - expected_out = 'Using shuffle seed: 2 (given)\n' + expected_out = "Using shuffle seed: 2 (given)\n" self.assertEqual(stdout.getvalue(), expected_out) self.assertEqual(runner.shuffle_seed, 2) def test_load_tests_for_label_file_path(self): - with change_cwd('.'): + with change_cwd("."): msg = ( "One of the test labels is a path to a file: " "'test_discover_runner.py', which is not supported. Use a " "dotted module name or path to a directory instead." ) with self.assertRaisesMessage(RuntimeError, msg): - DiscoverRunner().load_tests_for_label('test_discover_runner.py', {}) + DiscoverRunner().load_tests_for_label("test_discover_runner.py", {}) def test_dotted_test_module(self): - count = DiscoverRunner(verbosity=0).build_suite( - ['test_runner_apps.sample.tests_sample'], - ).countTestCases() + count = ( + DiscoverRunner(verbosity=0) + .build_suite( + ["test_runner_apps.sample.tests_sample"], + ) + .countTestCases() + ) self.assertEqual(count, 4) def test_dotted_test_class_vanilla_unittest(self): - count = DiscoverRunner(verbosity=0).build_suite( - ['test_runner_apps.sample.tests_sample.TestVanillaUnittest'], - ).countTestCases() + count = ( + DiscoverRunner(verbosity=0) + .build_suite( + ["test_runner_apps.sample.tests_sample.TestVanillaUnittest"], + ) + .countTestCases() + ) self.assertEqual(count, 1) def test_dotted_test_class_django_testcase(self): - count = DiscoverRunner(verbosity=0).build_suite( - ['test_runner_apps.sample.tests_sample.TestDjangoTestCase'], - ).countTestCases() + count = ( + DiscoverRunner(verbosity=0) + .build_suite( + ["test_runner_apps.sample.tests_sample.TestDjangoTestCase"], + ) + .countTestCases() + ) self.assertEqual(count, 1) def test_dotted_test_method_django_testcase(self): - count = DiscoverRunner(verbosity=0).build_suite( - ['test_runner_apps.sample.tests_sample.TestDjangoTestCase.test_sample'], - ).countTestCases() + count = ( + DiscoverRunner(verbosity=0) + .build_suite( + ["test_runner_apps.sample.tests_sample.TestDjangoTestCase.test_sample"], + ) + .countTestCases() + ) self.assertEqual(count, 1) def test_pattern(self): - count = DiscoverRunner( - pattern="*_tests.py", - verbosity=0, - ).build_suite(['test_runner_apps.sample']).countTestCases() + count = ( + DiscoverRunner( + pattern="*_tests.py", + verbosity=0, + ) + .build_suite(["test_runner_apps.sample"]) + .countTestCases() + ) self.assertEqual(count, 1) def test_name_patterns(self): all_test_1 = [ - 'DjangoCase1.test_1', 'DjangoCase2.test_1', - 'SimpleCase1.test_1', 'SimpleCase2.test_1', - 'UnittestCase1.test_1', 'UnittestCase2.test_1', + "DjangoCase1.test_1", + "DjangoCase2.test_1", + "SimpleCase1.test_1", + "SimpleCase2.test_1", + "UnittestCase1.test_1", + "UnittestCase2.test_1", ] all_test_2 = [ - 'DjangoCase1.test_2', 'DjangoCase2.test_2', - 'SimpleCase1.test_2', 'SimpleCase2.test_2', - 'UnittestCase1.test_2', 'UnittestCase2.test_2', + "DjangoCase1.test_2", + "DjangoCase2.test_2", + "SimpleCase1.test_2", + "SimpleCase2.test_2", + "UnittestCase1.test_2", + "UnittestCase2.test_2", ] - all_tests = sorted([*all_test_1, *all_test_2, 'UnittestCase2.test_3_test']) + all_tests = sorted([*all_test_1, *all_test_2, "UnittestCase2.test_3_test"]) for pattern, expected in [ - [['test_1'], all_test_1], - [['UnittestCase1'], ['UnittestCase1.test_1', 'UnittestCase1.test_2']], - [['*test'], ['UnittestCase2.test_3_test']], - [['test*'], all_tests], - [['test'], all_tests], - [['test_1', 'test_2'], sorted([*all_test_1, *all_test_2])], - [['test*1'], all_test_1], + [["test_1"], all_test_1], + [["UnittestCase1"], ["UnittestCase1.test_1", "UnittestCase1.test_2"]], + [["*test"], ["UnittestCase2.test_3_test"]], + [["test*"], all_tests], + [["test"], all_tests], + [["test_1", "test_2"], sorted([*all_test_1, *all_test_2])], + [["test*1"], all_test_1], ]: with self.subTest(pattern): suite = DiscoverRunner( test_name_patterns=pattern, verbosity=0, - ).build_suite(['test_runner_apps.simple']) + ).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) + 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), + ("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']): + with change_loader_patterns(["UnittestCase1"]): count = runner.build_suite([test_labels]).countTestCases() self.assertEqual(count, tests_count) - self.assertEqual(runner.test_loader.testNamePatterns, ['UnittestCase1']) + 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']): + 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']) + 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( - ['test_runner_apps/sample/'], - ).countTestCases() + count = ( + DiscoverRunner(verbosity=0) + .build_suite( + ["test_runner_apps/sample/"], + ) + .countTestCases() + ) self.assertEqual(count, 5) @@ -259,16 +292,24 @@ class DiscoverRunnerTests(SimpleTestCase): ) def test_empty_test_case(self): - count = DiscoverRunner(verbosity=0).build_suite( - ['test_runner_apps.sample.tests_sample.EmptyTestCase'], - ).countTestCases() + count = ( + DiscoverRunner(verbosity=0) + .build_suite( + ["test_runner_apps.sample.tests_sample.EmptyTestCase"], + ) + .countTestCases() + ) self.assertEqual(count, 0) def test_discovery_on_package(self): - count = DiscoverRunner(verbosity=0).build_suite( - ['test_runner_apps.sample.tests'], - ).countTestCases() + count = ( + DiscoverRunner(verbosity=0) + .build_suite( + ["test_runner_apps.sample.tests"], + ) + .countTestCases() + ) self.assertEqual(count, 1) @@ -280,34 +321,44 @@ class DiscoverRunnerTests(SimpleTestCase): This results in tests from adjacent modules being run when they should not. The discover runner avoids this behavior. """ - count = DiscoverRunner(verbosity=0).build_suite( - ['test_runner_apps.sample.empty'], - ).countTestCases() + count = ( + DiscoverRunner(verbosity=0) + .build_suite( + ["test_runner_apps.sample.empty"], + ) + .countTestCases() + ) self.assertEqual(count, 0) def test_testcase_ordering(self): with change_cwd(".."): - suite = DiscoverRunner(verbosity=0).build_suite(['test_runner_apps/sample/']) + suite = DiscoverRunner(verbosity=0).build_suite( + ["test_runner_apps/sample/"] + ) self.assertEqual( suite._tests[0].__class__.__name__, - 'TestDjangoTestCase', - msg="TestDjangoTestCase should be the first test case") + "TestDjangoTestCase", + msg="TestDjangoTestCase should be the first test case", + ) self.assertEqual( suite._tests[1].__class__.__name__, - 'TestZimpleTestCase', - msg="TestZimpleTestCase should be the second test case") + "TestZimpleTestCase", + msg="TestZimpleTestCase should be the second test case", + ) # All others can follow in unspecified order, including doctests - self.assertIn('DocTestCase', [t.__class__.__name__ for t in suite._tests[2:]]) + self.assertIn( + "DocTestCase", [t.__class__.__name__ for t in suite._tests[2:]] + ) def test_duplicates_ignored(self): """ Tests shouldn't be discovered twice when discovering on overlapping paths. """ - base_app = 'forms_tests' - sub_app = 'forms_tests.field_tests' + base_app = "forms_tests" + sub_app = "forms_tests.field_tests" runner = DiscoverRunner(verbosity=0) - with self.modify_settings(INSTALLED_APPS={'append': sub_app}): + with self.modify_settings(INSTALLED_APPS={"append": sub_app}): single = runner.build_suite([base_app]).countTestCases() dups = runner.build_suite([base_app, sub_app]).countTestCases() self.assertEqual(single, dups) @@ -319,32 +370,46 @@ class DiscoverRunnerTests(SimpleTestCase): """ runner = DiscoverRunner(reverse=True, verbosity=0) suite = runner.build_suite( - test_labels=('test_runner_apps.sample', 'test_runner_apps.simple')) - self.assertIn('test_runner_apps.simple', next(iter(suite)).id(), - msg="Test labels should be reversed.") - suite = runner.build_suite(test_labels=('test_runner_apps.simple',)) + test_labels=("test_runner_apps.sample", "test_runner_apps.simple") + ) + self.assertIn( + "test_runner_apps.simple", + next(iter(suite)).id(), + msg="Test labels should be reversed.", + ) + suite = runner.build_suite(test_labels=("test_runner_apps.simple",)) suite = tuple(suite) - self.assertIn('DjangoCase', suite[0].id(), - msg="Test groups should not be reversed.") - self.assertIn('SimpleCase', suite[4].id(), - msg="Test groups order should be preserved.") - self.assertIn('DjangoCase2', suite[0].id(), - msg="Django test cases should be reversed.") - self.assertIn('SimpleCase2', suite[4].id(), - msg="Simple test cases should be reversed.") - self.assertIn('UnittestCase2', suite[8].id(), - msg="Unittest test cases should be reversed.") - self.assertIn('test_2', suite[0].id(), - msg="Methods of Django cases should be reversed.") - self.assertIn('test_2', suite[4].id(), - msg="Methods of simple cases should be reversed.") - self.assertIn('test_2', suite[9].id(), - msg="Methods of unittest cases should be reversed.") + self.assertIn( + "DjangoCase", suite[0].id(), msg="Test groups should not be reversed." + ) + self.assertIn( + "SimpleCase", suite[4].id(), msg="Test groups order should be preserved." + ) + self.assertIn( + "DjangoCase2", suite[0].id(), msg="Django test cases should be reversed." + ) + self.assertIn( + "SimpleCase2", suite[4].id(), msg="Simple test cases should be reversed." + ) + self.assertIn( + "UnittestCase2", + suite[8].id(), + msg="Unittest test cases should be reversed.", + ) + self.assertIn( + "test_2", suite[0].id(), msg="Methods of Django cases should be reversed." + ) + self.assertIn( + "test_2", suite[4].id(), msg="Methods of simple cases should be reversed." + ) + self.assertIn( + "test_2", suite[9].id(), msg="Methods of unittest cases should be reversed." + ) def test_build_suite_failed_tests_first(self): # The "doesnotexist" label results in a _FailedTest instance. suite = DiscoverRunner(verbosity=0).build_suite( - test_labels=['test_runner_apps.sample', 'doesnotexist'], + test_labels=["test_runner_apps.sample", "doesnotexist"], ) tests = list(suite) self.assertIsInstance(tests[0], unittest.loader._FailedTest) @@ -353,12 +418,12 @@ class DiscoverRunnerTests(SimpleTestCase): def test_build_suite_shuffling(self): # These will result in unittest.loader._FailedTest instances rather # than TestCase objects, but they are sufficient for testing. - labels = ['label1', 'label2', 'label3', 'label4'] + labels = ["label1", "label2", "label3", "label4"] cases = [ - ({}, ['label1', 'label2', 'label3', 'label4']), - ({'reverse': True}, ['label4', 'label3', 'label2', 'label1']), - ({'shuffle': 8}, ['label4', 'label1', 'label3', 'label2']), - ({'shuffle': 8, 'reverse': True}, ['label2', 'label3', 'label1', 'label4']), + ({}, ["label1", "label2", "label3", "label4"]), + ({"reverse": True}, ["label4", "label3", "label2", "label1"]), + ({"shuffle": 8}, ["label4", "label1", "label3", "label2"]), + ({"shuffle": 8, "reverse": True}, ["label2", "label3", "label1", "label4"]), ] for kwargs, expected in cases: with self.subTest(kwargs=kwargs): @@ -366,7 +431,7 @@ class DiscoverRunnerTests(SimpleTestCase): runner = DiscoverRunner(**kwargs, verbosity=0) tests = runner.build_suite(test_labels=labels) # The ids have the form "unittest.loader._FailedTest.label1". - names = [test.id().split('.')[-1] for test in tests] + names = [test.id().split(".")[-1] for test in tests] self.assertEqual(names, expected) def test_overridable_get_test_runner_kwargs(self): @@ -382,78 +447,95 @@ class DiscoverRunnerTests(SimpleTestCase): self.assertEqual(DiscoverRunner().test_loader, defaultTestLoader) def test_tags(self): - runner = DiscoverRunner(tags=['core'], verbosity=0) - self.assertEqual(runner.build_suite(['test_runner_apps.tagged.tests']).countTestCases(), 1) - runner = DiscoverRunner(tags=['fast'], verbosity=0) - self.assertEqual(runner.build_suite(['test_runner_apps.tagged.tests']).countTestCases(), 2) - runner = DiscoverRunner(tags=['slow'], verbosity=0) - self.assertEqual(runner.build_suite(['test_runner_apps.tagged.tests']).countTestCases(), 2) + runner = DiscoverRunner(tags=["core"], verbosity=0) + self.assertEqual( + runner.build_suite(["test_runner_apps.tagged.tests"]).countTestCases(), 1 + ) + runner = DiscoverRunner(tags=["fast"], verbosity=0) + self.assertEqual( + runner.build_suite(["test_runner_apps.tagged.tests"]).countTestCases(), 2 + ) + runner = DiscoverRunner(tags=["slow"], verbosity=0) + self.assertEqual( + runner.build_suite(["test_runner_apps.tagged.tests"]).countTestCases(), 2 + ) def test_exclude_tags(self): - runner = DiscoverRunner(tags=['fast'], exclude_tags=['core'], verbosity=0) - self.assertEqual(runner.build_suite(['test_runner_apps.tagged.tests']).countTestCases(), 1) - runner = DiscoverRunner(tags=['fast'], exclude_tags=['slow'], verbosity=0) - self.assertEqual(runner.build_suite(['test_runner_apps.tagged.tests']).countTestCases(), 0) - runner = DiscoverRunner(exclude_tags=['slow'], verbosity=0) - self.assertEqual(runner.build_suite(['test_runner_apps.tagged.tests']).countTestCases(), 0) + runner = DiscoverRunner(tags=["fast"], exclude_tags=["core"], verbosity=0) + self.assertEqual( + runner.build_suite(["test_runner_apps.tagged.tests"]).countTestCases(), 1 + ) + runner = DiscoverRunner(tags=["fast"], exclude_tags=["slow"], verbosity=0) + self.assertEqual( + runner.build_suite(["test_runner_apps.tagged.tests"]).countTestCases(), 0 + ) + runner = DiscoverRunner(exclude_tags=["slow"], verbosity=0) + self.assertEqual( + runner.build_suite(["test_runner_apps.tagged.tests"]).countTestCases(), 0 + ) def test_tag_inheritance(self): def count_tests(**kwargs): - kwargs.setdefault('verbosity', 0) - suite = DiscoverRunner(**kwargs).build_suite(['test_runner_apps.tagged.tests_inheritance']) + kwargs.setdefault("verbosity", 0) + suite = DiscoverRunner(**kwargs).build_suite( + ["test_runner_apps.tagged.tests_inheritance"] + ) return suite.countTestCases() - self.assertEqual(count_tests(tags=['foo']), 4) - self.assertEqual(count_tests(tags=['bar']), 2) - self.assertEqual(count_tests(tags=['baz']), 2) - self.assertEqual(count_tests(tags=['foo'], exclude_tags=['bar']), 2) - self.assertEqual(count_tests(tags=['foo'], exclude_tags=['bar', 'baz']), 1) - self.assertEqual(count_tests(exclude_tags=['foo']), 0) + self.assertEqual(count_tests(tags=["foo"]), 4) + self.assertEqual(count_tests(tags=["bar"]), 2) + self.assertEqual(count_tests(tags=["baz"]), 2) + self.assertEqual(count_tests(tags=["foo"], exclude_tags=["bar"]), 2) + self.assertEqual(count_tests(tags=["foo"], exclude_tags=["bar", "baz"]), 1) + self.assertEqual(count_tests(exclude_tags=["foo"]), 0) def test_tag_fail_to_load(self): with self.assertRaises(SyntaxError): - import_module('test_runner_apps.tagged.tests_syntax_error') - runner = DiscoverRunner(tags=['syntax_error'], verbosity=0) + import_module("test_runner_apps.tagged.tests_syntax_error") + runner = DiscoverRunner(tags=["syntax_error"], verbosity=0) # A label that doesn't exist or cannot be loaded due to syntax errors # is always considered matching. - suite = runner.build_suite(['doesnotexist', 'test_runner_apps.tagged']) - self.assertEqual([test.id() for test in suite], [ - 'unittest.loader._FailedTest.doesnotexist', - 'unittest.loader._FailedTest.test_runner_apps.tagged.tests_syntax_error', - ]) + suite = runner.build_suite(["doesnotexist", "test_runner_apps.tagged"]) + self.assertEqual( + [test.id() for test in suite], + [ + "unittest.loader._FailedTest.doesnotexist", + "unittest.loader._FailedTest.test_runner_apps.tagged.tests_syntax_error", + ], + ) def test_included_tags_displayed(self): - runner = DiscoverRunner(tags=['foo', 'bar'], verbosity=2) + runner = DiscoverRunner(tags=["foo", "bar"], verbosity=2) with captured_stdout() as stdout: - runner.build_suite(['test_runner_apps.tagged.tests']) - self.assertIn('Including test tag(s): bar, foo.\n', stdout.getvalue()) + runner.build_suite(["test_runner_apps.tagged.tests"]) + self.assertIn("Including test tag(s): bar, foo.\n", stdout.getvalue()) def test_excluded_tags_displayed(self): - runner = DiscoverRunner(exclude_tags=['foo', 'bar'], verbosity=3) + runner = DiscoverRunner(exclude_tags=["foo", "bar"], verbosity=3) with captured_stdout() as stdout: - runner.build_suite(['test_runner_apps.tagged.tests']) - self.assertIn('Excluding test tag(s): bar, foo.\n', stdout.getvalue()) + runner.build_suite(["test_runner_apps.tagged.tests"]) + self.assertIn("Excluding test tag(s): bar, foo.\n", stdout.getvalue()) def test_number_of_tests_found_displayed(self): runner = DiscoverRunner() with captured_stdout() as stdout: - runner.build_suite([ - 'test_runner_apps.sample.tests_sample.TestDjangoTestCase', - 'test_runner_apps.simple', - ]) - self.assertIn('Found 14 test(s).\n', stdout.getvalue()) + runner.build_suite( + [ + "test_runner_apps.sample.tests_sample.TestDjangoTestCase", + "test_runner_apps.simple", + ] + ) + self.assertIn("Found 14 test(s).\n", stdout.getvalue()) def test_pdb_with_parallel(self): - msg = ( - 'You cannot use --pdb with parallel tests; pass --parallel=1 to use it.' - ) + msg = "You cannot use --pdb with parallel tests; pass --parallel=1 to use it." with self.assertRaisesMessage(ValueError, msg): DiscoverRunner(pdb=True, parallel=2) def test_number_of_parallel_workers(self): """Number of processes doesn't exceed the number of TestCases.""" runner = DiscoverRunner(parallel=5, verbosity=0) - suite = runner.build_suite(['test_runner_apps.tagged']) + suite = runner.build_suite(["test_runner_apps.tagged"]) self.assertEqual(suite.processes, len(suite.subsuites)) def test_number_of_databases_parallel_test_suite(self): @@ -462,7 +544,7 @@ class DiscoverRunnerTests(SimpleTestCase): parallel tests. """ runner = DiscoverRunner(parallel=8, verbosity=0) - suite = runner.build_suite(['test_runner_apps.tagged']) + suite = runner.build_suite(["test_runner_apps.tagged"]) self.assertEqual(suite.processes, len(suite.subsuites)) self.assertEqual(runner.parallel, suite.processes) @@ -472,29 +554,33 @@ class DiscoverRunnerTests(SimpleTestCase): non-parallel tests. """ runner = DiscoverRunner(parallel=8, verbosity=0) - suite = runner.build_suite(['test_runner_apps.simple.tests.DjangoCase1']) + suite = runner.build_suite(["test_runner_apps.simple.tests.DjangoCase1"]) self.assertEqual(runner.parallel, 1) self.assertIsInstance(suite, TestSuite) def test_buffer_mode_test_pass(self): runner = DiscoverRunner(buffer=True, verbosity=0) with captured_stdout() as stdout, captured_stderr() as stderr: - suite = runner.build_suite([ - 'test_runner_apps.buffer.tests_buffer.WriteToStdoutStderrTestCase.test_pass', - ]) + suite = runner.build_suite( + [ + "test_runner_apps.buffer.tests_buffer.WriteToStdoutStderrTestCase.test_pass", + ] + ) runner.run_suite(suite) - self.assertNotIn('Write to stderr.', stderr.getvalue()) - self.assertNotIn('Write to stdout.', stdout.getvalue()) + self.assertNotIn("Write to stderr.", stderr.getvalue()) + self.assertNotIn("Write to stdout.", stdout.getvalue()) def test_buffer_mode_test_fail(self): runner = DiscoverRunner(buffer=True, verbosity=0) with captured_stdout() as stdout, captured_stderr() as stderr: - suite = runner.build_suite([ - 'test_runner_apps.buffer.tests_buffer.WriteToStdoutStderrTestCase.test_fail', - ]) + suite = runner.build_suite( + [ + "test_runner_apps.buffer.tests_buffer.WriteToStdoutStderrTestCase.test_fail", + ] + ) runner.run_suite(suite) - self.assertIn('Write to stderr.', stderr.getvalue()) - self.assertIn('Write to stdout.', stdout.getvalue()) + self.assertIn("Write to stderr.", stderr.getvalue()) + self.assertIn("Write to stdout.", stdout.getvalue()) def run_suite_with_runner(self, runner_class, **kwargs): class MyRunner(DiscoverRunner): @@ -516,79 +602,82 @@ class DiscoverRunnerTests(SimpleTestCase): def test_run_suite_logs_seed(self): class TestRunner: def run(self, suite): - return '<fake-result>' + return "<fake-result>" - expected_prefix = 'Used shuffle seed' + expected_prefix = "Used shuffle seed" # Test with and without shuffling enabled. result, output = self.run_suite_with_runner(TestRunner) - self.assertEqual(result, '<fake-result>') + self.assertEqual(result, "<fake-result>") self.assertNotIn(expected_prefix, output) result, output = self.run_suite_with_runner(TestRunner, shuffle=2) - self.assertEqual(result, '<fake-result>') - expected_output = f'{expected_prefix}: 2 (given)\n' + self.assertEqual(result, "<fake-result>") + expected_output = f"{expected_prefix}: 2 (given)\n" self.assertEqual(output, expected_output) def test_run_suite_logs_seed_exception(self): """ run_suite() logs the seed when TestRunner.run() raises an exception. """ + class TestRunner: def run(self, suite): - raise RuntimeError('my exception') + raise RuntimeError("my exception") result, output = self.run_suite_with_runner(TestRunner, shuffle=2) - self.assertEqual(result, 'my exception') - expected_output = 'Used shuffle seed: 2 (given)\n' + self.assertEqual(result, "my exception") + expected_output = "Used shuffle seed: 2 (given)\n" self.assertEqual(output, expected_output) - @mock.patch('faulthandler.enable') + @mock.patch("faulthandler.enable") def test_faulthandler_enabled(self, mocked_enable): - with mock.patch('faulthandler.is_enabled', return_value=False): + with mock.patch("faulthandler.is_enabled", return_value=False): DiscoverRunner(enable_faulthandler=True) mocked_enable.assert_called() - @mock.patch('faulthandler.enable') + @mock.patch("faulthandler.enable") def test_faulthandler_already_enabled(self, mocked_enable): - with mock.patch('faulthandler.is_enabled', return_value=True): + with mock.patch("faulthandler.is_enabled", return_value=True): DiscoverRunner(enable_faulthandler=True) mocked_enable.assert_not_called() - @mock.patch('faulthandler.enable') + @mock.patch("faulthandler.enable") def test_faulthandler_enabled_fileno(self, mocked_enable): # sys.stderr that is not an actual file. - with mock.patch('faulthandler.is_enabled', return_value=False), captured_stderr(): + with mock.patch( + "faulthandler.is_enabled", return_value=False + ), captured_stderr(): DiscoverRunner(enable_faulthandler=True) mocked_enable.assert_called() - @mock.patch('faulthandler.enable') + @mock.patch("faulthandler.enable") def test_faulthandler_disabled(self, mocked_enable): - with mock.patch('faulthandler.is_enabled', return_value=False): + with mock.patch("faulthandler.is_enabled", return_value=False): DiscoverRunner(enable_faulthandler=False) mocked_enable.assert_not_called() def test_timings_not_captured(self): runner = DiscoverRunner(timing=False) with captured_stderr() as stderr: - with runner.time_keeper.timed('test'): + with runner.time_keeper.timed("test"): pass runner.time_keeper.print_results() self.assertIsInstance(runner.time_keeper, NullTimeKeeper) - self.assertNotIn('test', stderr.getvalue()) + self.assertNotIn("test", stderr.getvalue()) def test_timings_captured(self): runner = DiscoverRunner(timing=True) with captured_stderr() as stderr: - with runner.time_keeper.timed('test'): + with runner.time_keeper.timed("test"): pass runner.time_keeper.print_results() self.assertIsInstance(runner.time_keeper, TimeKeeper) - self.assertIn('test', stderr.getvalue()) + self.assertIn("test", stderr.getvalue()) def test_log(self): custom_low_level = 5 custom_high_level = 45 - msg = 'logging message' + msg = "logging message" cases = [ (0, None, False), (0, custom_low_level, False), @@ -620,42 +709,44 @@ class DiscoverRunnerTests(SimpleTestCase): with captured_stdout() as stdout: runner = DiscoverRunner(verbosity=verbosity) runner.log(msg, level) - self.assertEqual(stdout.getvalue(), f'{msg}\n' if output else '') + self.assertEqual(stdout.getvalue(), f"{msg}\n" if output else "") def test_log_logger(self): - logger = logging.getLogger('test.logging') + logger = logging.getLogger("test.logging") cases = [ - (None, 'INFO:test.logging:log message'), + (None, "INFO:test.logging:log message"), # Test a low custom logging level. - (5, 'Level 5:test.logging:log message'), - (logging.DEBUG, 'DEBUG:test.logging:log message'), - (logging.INFO, 'INFO:test.logging:log message'), - (logging.WARNING, 'WARNING:test.logging:log message'), + (5, "Level 5:test.logging:log message"), + (logging.DEBUG, "DEBUG:test.logging:log message"), + (logging.INFO, "INFO:test.logging:log message"), + (logging.WARNING, "WARNING:test.logging:log message"), # Test a high custom logging level. - (45, 'Level 45:test.logging:log message'), + (45, "Level 45:test.logging:log message"), ] for level, expected in cases: with self.subTest(level=level): runner = DiscoverRunner(logger=logger) # Pass a logging level smaller than the smallest level in cases # in order to capture all messages. - with self.assertLogs('test.logging', level=1) as cm: - runner.log('log message', level) + with self.assertLogs("test.logging", level=1) as cm: + runner.log("log message", level) self.assertEqual(cm.output, [expected]) def test_suite_result_with_failure(self): cases = [ - (1, 'FailureTestCase'), - (1, 'ErrorTestCase'), - (0, 'ExpectedFailureTestCase'), - (1, 'UnexpectedSuccessTestCase'), + (1, "FailureTestCase"), + (1, "ErrorTestCase"), + (0, "ExpectedFailureTestCase"), + (1, "UnexpectedSuccessTestCase"), ] runner = DiscoverRunner(verbosity=0) for expected_failures, testcase in cases: with self.subTest(testcase=testcase): - suite = runner.build_suite([ - f'test_runner_apps.failures.tests_failures.{testcase}', - ]) + suite = runner.build_suite( + [ + f"test_runner_apps.failures.tests_failures.{testcase}", + ] + ) with captured_stderr(): result = runner.run_suite(suite) failures = runner.suite_result(suite, result) @@ -664,7 +755,7 @@ class DiscoverRunnerTests(SimpleTestCase): class DiscoverRunnerGetDatabasesTests(SimpleTestCase): runner = DiscoverRunner(verbosity=2) - skip_msg = 'Skipping setup of unused database(s): ' + skip_msg = "Skipping setup of unused database(s): " def get_databases(self, test_labels): with captured_stdout() as stdout: @@ -677,43 +768,51 @@ class DiscoverRunnerGetDatabasesTests(SimpleTestCase): self.assertEqual(databases, expected_databases) skipped_databases = set(connections) - set(expected_databases) if skipped_databases: - self.assertIn(self.skip_msg + ', '.join(sorted(skipped_databases)), output) + self.assertIn(self.skip_msg + ", ".join(sorted(skipped_databases)), output) else: self.assertNotIn(self.skip_msg, output) def test_mixed(self): - databases, output = self.get_databases(['test_runner_apps.databases.tests']) - self.assertEqual(databases, {'default': True, 'other': False}) + databases, output = self.get_databases(["test_runner_apps.databases.tests"]) + self.assertEqual(databases, {"default": True, "other": False}) self.assertNotIn(self.skip_msg, output) def test_all(self): - databases, output = self.get_databases(['test_runner_apps.databases.tests.AllDatabasesTests']) + databases, output = self.get_databases( + ["test_runner_apps.databases.tests.AllDatabasesTests"] + ) self.assertEqual(databases, {alias: False for alias in connections}) self.assertNotIn(self.skip_msg, output) def test_default_and_other(self): - self.assertSkippedDatabases([ - 'test_runner_apps.databases.tests.DefaultDatabaseTests', - 'test_runner_apps.databases.tests.OtherDatabaseTests', - ], {'default': False, 'other': False}) + self.assertSkippedDatabases( + [ + "test_runner_apps.databases.tests.DefaultDatabaseTests", + "test_runner_apps.databases.tests.OtherDatabaseTests", + ], + {"default": False, "other": False}, + ) def test_default_only(self): - self.assertSkippedDatabases([ - 'test_runner_apps.databases.tests.DefaultDatabaseTests', - ], {'default': False}) + self.assertSkippedDatabases( + [ + "test_runner_apps.databases.tests.DefaultDatabaseTests", + ], + {"default": False}, + ) def test_other_only(self): - self.assertSkippedDatabases([ - 'test_runner_apps.databases.tests.OtherDatabaseTests' - ], {'other': False}) + self.assertSkippedDatabases( + ["test_runner_apps.databases.tests.OtherDatabaseTests"], {"other": False} + ) def test_no_databases_required(self): - self.assertSkippedDatabases([ - 'test_runner_apps.databases.tests.NoDatabaseTests' - ], {}) + self.assertSkippedDatabases( + ["test_runner_apps.databases.tests.NoDatabaseTests"], {} + ) def test_serialize(self): - databases, _ = self.get_databases([ - 'test_runner_apps.databases.tests.DefaultDatabaseSerializedTests' - ]) - self.assertEqual(databases, {'default': True}) + databases, _ = self.get_databases( + ["test_runner_apps.databases.tests.DefaultDatabaseSerializedTests"] + ) + self.assertEqual(databases, {"default": True}) diff --git a/tests/test_runner/test_parallel.py b/tests/test_runner/test_parallel.py index e27579831f..ca208f6a48 100644 --- a/tests/test_runner/test_parallel.py +++ b/tests/test_runner/test_parallel.py @@ -16,6 +16,7 @@ class ExceptionThatFailsUnpickling(Exception): After pickling, this class fails unpickling with an error about incorrect arguments passed to __init__(). """ + def __init__(self, arg): super().__init__() @@ -52,10 +53,9 @@ class SampleFailingSubtest(SimpleTestCase): class RemoteTestResultTest(SimpleTestCase): - def _test_error_exc_info(self): try: - raise ValueError('woops') + raise ValueError("woops") except ValueError: return sys.exc_info() @@ -75,16 +75,16 @@ class RemoteTestResultTest(SimpleTestCase): def test_was_successful_one_skip(self): result = RemoteTestResult() - result.addSkip(None, 'Skipped') + result.addSkip(None, "Skipped") self.assertIs(result.wasSuccessful(), True) - @unittest.skipUnless(tblib is not None, 'requires tblib to be installed') + @unittest.skipUnless(tblib is not None, "requires tblib to be installed") def test_was_successful_one_error(self): result = RemoteTestResult() result.addError(None, self._test_error_exc_info()) self.assertIs(result.wasSuccessful(), False) - @unittest.skipUnless(tblib is not None, 'requires tblib to be installed') + @unittest.skipUnless(tblib is not None, "requires tblib to be installed") def test_was_successful_one_failure(self): result = RemoteTestResult() result.addFailure(None, self._test_error_exc_info()) @@ -96,17 +96,17 @@ class RemoteTestResultTest(SimpleTestCase): self.assertEqual(result.events, loaded_result.events) def test_pickle_errors_detection(self): - picklable_error = RuntimeError('This is fine') - not_unpicklable_error = ExceptionThatFailsUnpickling('arg') + picklable_error = RuntimeError("This is fine") + not_unpicklable_error = ExceptionThatFailsUnpickling("arg") result = RemoteTestResult() result._confirm_picklable(picklable_error) - msg = '__init__() missing 1 required positional argument' + msg = "__init__() missing 1 required positional argument" with self.assertRaisesMessage(TypeError, msg): result._confirm_picklable(not_unpicklable_error) - @unittest.skipUnless(tblib is not None, 'requires tblib to be installed') + @unittest.skipUnless(tblib is not None, "requires tblib to be installed") def test_add_failing_subtests(self): """ Failing subtests are added correctly using addSubTest(). @@ -114,7 +114,7 @@ class RemoteTestResultTest(SimpleTestCase): # Manually run a test with failing subtests to prevent the failures # from affecting the actual test run. result = RemoteTestResult() - subtest_test = SampleFailingSubtest(methodName='dummy_test') + subtest_test = SampleFailingSubtest(methodName="dummy_test") subtest_test.run(result=result) events = result.events @@ -122,8 +122,11 @@ class RemoteTestResultTest(SimpleTestCase): self.assertIs(result.wasSuccessful(), False) event = events[1] - self.assertEqual(event[0], 'addSubTest') - self.assertEqual(str(event[2]), 'dummy_test (test_runner.test_parallel.SampleFailingSubtest) (index=0)') + self.assertEqual(event[0], "addSubTest") + self.assertEqual( + str(event[2]), + "dummy_test (test_runner.test_parallel.SampleFailingSubtest) (index=0)", + ) self.assertEqual(repr(event[3][1]), "AssertionError('0 != 1')") event = events[2] diff --git a/tests/test_runner/test_shuffler.py b/tests/test_runner/test_shuffler.py index f177249706..c6ecee5cb0 100644 --- a/tests/test_runner/test_shuffler.py +++ b/tests/test_runner/test_shuffler.py @@ -5,84 +5,83 @@ from django.test.runner import Shuffler class ShufflerTests(SimpleTestCase): - def test_hash_text(self): - actual = Shuffler._hash_text('abcd') - self.assertEqual(actual, 'e2fc714c4727ee9395f324cd2e7f331f') + actual = Shuffler._hash_text("abcd") + self.assertEqual(actual, "e2fc714c4727ee9395f324cd2e7f331f") def test_hash_text_hash_algorithm(self): class MyShuffler(Shuffler): - hash_algorithm = 'sha1' + hash_algorithm = "sha1" - actual = MyShuffler._hash_text('abcd') - self.assertEqual(actual, '81fe8bfe87576c3ecb22426f8e57847382917acf') + actual = MyShuffler._hash_text("abcd") + self.assertEqual(actual, "81fe8bfe87576c3ecb22426f8e57847382917acf") def test_init(self): shuffler = Shuffler(100) self.assertEqual(shuffler.seed, 100) - self.assertEqual(shuffler.seed_source, 'given') + self.assertEqual(shuffler.seed_source, "given") def test_init_none_seed(self): - with mock.patch('random.randint', return_value=200): + with mock.patch("random.randint", return_value=200): shuffler = Shuffler(None) self.assertEqual(shuffler.seed, 200) - self.assertEqual(shuffler.seed_source, 'generated') + self.assertEqual(shuffler.seed_source, "generated") def test_init_no_seed_argument(self): - with mock.patch('random.randint', return_value=300): + with mock.patch("random.randint", return_value=300): shuffler = Shuffler() self.assertEqual(shuffler.seed, 300) - self.assertEqual(shuffler.seed_source, 'generated') + self.assertEqual(shuffler.seed_source, "generated") def test_seed_display(self): shuffler = Shuffler(100) - shuffler.seed_source = 'test' - self.assertEqual(shuffler.seed_display, '100 (test)') + shuffler.seed_source = "test" + self.assertEqual(shuffler.seed_display, "100 (test)") def test_hash_item_seed(self): cases = [ - (1234, '64ad3fb166ddb41a2ca24f1803b8b722'), + (1234, "64ad3fb166ddb41a2ca24f1803b8b722"), # Passing a string gives the same value. - ('1234', '64ad3fb166ddb41a2ca24f1803b8b722'), - (5678, '4dde450ad339b6ce45a0a2666e35b975'), + ("1234", "64ad3fb166ddb41a2ca24f1803b8b722"), + (5678, "4dde450ad339b6ce45a0a2666e35b975"), ] for seed, expected in cases: with self.subTest(seed=seed): shuffler = Shuffler(seed=seed) - actual = shuffler._hash_item('abc', lambda x: x) + actual = shuffler._hash_item("abc", lambda x: x) self.assertEqual(actual, expected) def test_hash_item_key(self): cases = [ - (lambda x: x, '64ad3fb166ddb41a2ca24f1803b8b722'), - (lambda x: x.upper(), 'ee22e8597bff91742affe4befbf4649a'), + (lambda x: x, "64ad3fb166ddb41a2ca24f1803b8b722"), + (lambda x: x.upper(), "ee22e8597bff91742affe4befbf4649a"), ] for key, expected in cases: with self.subTest(key=key): shuffler = Shuffler(seed=1234) - actual = shuffler._hash_item('abc', key) + actual = shuffler._hash_item("abc", key) self.assertEqual(actual, expected) def test_shuffle_key(self): cases = [ - (lambda x: x, ['a', 'd', 'b', 'c']), - (lambda x: x.upper(), ['d', 'c', 'a', 'b']), + (lambda x: x, ["a", "d", "b", "c"]), + (lambda x: x.upper(), ["d", "c", "a", "b"]), ] for num, (key, expected) in enumerate(cases, start=1): with self.subTest(num=num): shuffler = Shuffler(seed=1234) - actual = shuffler.shuffle(['a', 'b', 'c', 'd'], key) + actual = shuffler.shuffle(["a", "b", "c", "d"], key) self.assertEqual(actual, expected) def test_shuffle_consistency(self): seq = [str(n) for n in range(5)] cases = [ - (None, ['3', '0', '2', '4', '1']), - (0, ['3', '2', '4', '1']), - (1, ['3', '0', '2', '4']), - (2, ['3', '0', '4', '1']), - (3, ['0', '2', '4', '1']), - (4, ['3', '0', '2', '1']), + (None, ["3", "0", "2", "4", "1"]), + (0, ["3", "2", "4", "1"]), + (1, ["3", "0", "2", "4"]), + (2, ["3", "0", "4", "1"]), + (3, ["0", "2", "4", "1"]), + (4, ["3", "0", "2", "1"]), ] shuffler = Shuffler(seed=1234) for index, expected in cases: @@ -99,4 +98,4 @@ class ShufflerTests(SimpleTestCase): shuffler = Shuffler(seed=1234) msg = "item 'A' has same hash 'a56ce89262959e151ee2266552f1819c' as item 'a'" with self.assertRaisesMessage(RuntimeError, msg): - shuffler.shuffle(['a', 'b', 'A'], lambda x: x.upper()) + shuffler.shuffle(["a", "b", "A"], lambda x: x.upper()) diff --git a/tests/test_runner/tests.py b/tests/test_runner/tests.py index 62b489abc7..665f2c5ef8 100644 --- a/tests/test_runner/tests.py +++ b/tests/test_runner/tests.py @@ -15,15 +15,19 @@ from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.core.management import call_command from django.core.management.base import SystemCheckError -from django.test import ( - SimpleTestCase, TransactionTestCase, skipUnlessDBFeature, -) +from django.test import SimpleTestCase, TransactionTestCase, skipUnlessDBFeature from django.test.runner import ( - DiscoverRunner, Shuffler, reorder_test_bin, reorder_tests, shuffle_tests, + DiscoverRunner, + Shuffler, + reorder_test_bin, + reorder_tests, + shuffle_tests, ) from django.test.testcases import connections_support_transactions from django.test.utils import ( - captured_stderr, dependency_ordered, get_unique_databases_and_mirrors, + captured_stderr, + dependency_ordered, + get_unique_databases_and_mirrors, iter_test_cases, ) from django.utils.deprecation import RemovedInDjango50Warning @@ -85,15 +89,21 @@ class TestSuiteTests(SimpleTestCase): # Each test.id() has a form like the following: # "test_runner.tests.IterTestCasesTests.test_iter_test_cases.<locals>.Tests1.test1". # It suffices to check only the last two parts. - names = ['.'.join(test.id().split('.')[-2:]) for test in tests] + names = [".".join(test.id().split(".")[-2:]) for test in tests] self.assertEqual(names, expected) def test_iter_test_cases_basic(self): suite = self.make_test_suite() tests = iter_test_cases(suite) - self.assertTestNames(tests, expected=[ - 'Tests1.test1', 'Tests1.test2', 'Tests2.test1', 'Tests2.test2', - ]) + self.assertTestNames( + tests, + expected=[ + "Tests1.test1", + "Tests1.test2", + "Tests2.test1", + "Tests2.test2", + ], + ) def test_iter_test_cases_string_input(self): msg = ( @@ -101,7 +111,7 @@ class TestSuiteTests(SimpleTestCase): "in 'abc')." ) with self.assertRaisesMessage(TypeError, msg): - list(iter_test_cases('abc')) + list(iter_test_cases("abc")) def test_iter_test_cases_iterable_of_tests(self): class Tests(unittest.TestCase): @@ -113,16 +123,26 @@ class TestSuiteTests(SimpleTestCase): tests = list(unittest.defaultTestLoader.loadTestsFromTestCase(Tests)) actual_tests = iter_test_cases(tests) - self.assertTestNames(actual_tests, expected=[ - 'Tests.test1', 'Tests.test2', - ]) + self.assertTestNames( + actual_tests, + expected=[ + "Tests.test1", + "Tests.test2", + ], + ) def test_iter_test_cases_custom_test_suite_class(self): suite = self.make_test_suite(suite_class=MySuite) tests = iter_test_cases(suite) - self.assertTestNames(tests, expected=[ - 'Tests1.test1', 'Tests1.test2', 'Tests2.test1', 'Tests2.test2', - ]) + self.assertTestNames( + tests, + expected=[ + "Tests1.test1", + "Tests1.test2", + "Tests2.test1", + "Tests2.test2", + ], + ) def test_iter_test_cases_mixed_test_suite_classes(self): suite = self.make_test_suite(suite=MySuite()) @@ -144,25 +164,43 @@ class TestSuiteTests(SimpleTestCase): shuffler = Shuffler(seed=9) shuffled_tests = shuffle_tests(tests, shuffler) self.assertIsInstance(shuffled_tests, collections.abc.Iterator) - self.assertTestNames(shuffled_tests, expected=[ - 'Tests2.test1', 'Tests2.test2', 'Tests1.test2', 'Tests1.test1', - ]) + self.assertTestNames( + shuffled_tests, + expected=[ + "Tests2.test1", + "Tests2.test2", + "Tests1.test2", + "Tests1.test1", + ], + ) def test_reorder_test_bin_no_arguments(self): tests = self.make_tests() reordered_tests = reorder_test_bin(tests) self.assertIsInstance(reordered_tests, collections.abc.Iterator) - self.assertTestNames(reordered_tests, expected=[ - 'Tests1.test1', 'Tests1.test2', 'Tests2.test1', 'Tests2.test2', - ]) + self.assertTestNames( + reordered_tests, + expected=[ + "Tests1.test1", + "Tests1.test2", + "Tests2.test1", + "Tests2.test2", + ], + ) def test_reorder_test_bin_reverse(self): tests = self.make_tests() reordered_tests = reorder_test_bin(tests, reverse=True) self.assertIsInstance(reordered_tests, collections.abc.Iterator) - self.assertTestNames(reordered_tests, expected=[ - 'Tests2.test2', 'Tests2.test1', 'Tests1.test2', 'Tests1.test1', - ]) + self.assertTestNames( + reordered_tests, + expected=[ + "Tests2.test2", + "Tests2.test1", + "Tests1.test2", + "Tests1.test1", + ], + ) def test_reorder_test_bin_random(self): tests = self.make_tests() @@ -170,9 +208,15 @@ class TestSuiteTests(SimpleTestCase): shuffler = Shuffler(seed=9) reordered_tests = reorder_test_bin(tests, shuffler=shuffler) self.assertIsInstance(reordered_tests, collections.abc.Iterator) - self.assertTestNames(reordered_tests, expected=[ - 'Tests2.test1', 'Tests2.test2', 'Tests1.test2', 'Tests1.test1', - ]) + self.assertTestNames( + reordered_tests, + expected=[ + "Tests2.test1", + "Tests2.test2", + "Tests1.test2", + "Tests1.test1", + ], + ) def test_reorder_test_bin_random_and_reverse(self): tests = self.make_tests() @@ -180,22 +224,40 @@ class TestSuiteTests(SimpleTestCase): shuffler = Shuffler(seed=9) reordered_tests = reorder_test_bin(tests, shuffler=shuffler, reverse=True) self.assertIsInstance(reordered_tests, collections.abc.Iterator) - self.assertTestNames(reordered_tests, expected=[ - 'Tests1.test1', 'Tests1.test2', 'Tests2.test2', 'Tests2.test1', - ]) + self.assertTestNames( + reordered_tests, + expected=[ + "Tests1.test1", + "Tests1.test2", + "Tests2.test2", + "Tests2.test1", + ], + ) def test_reorder_tests_same_type_consecutive(self): """Tests of the same type are made consecutive.""" tests = self.make_tests() # Move the last item to the front. tests.insert(0, tests.pop()) - self.assertTestNames(tests, expected=[ - 'Tests2.test2', 'Tests1.test1', 'Tests1.test2', 'Tests2.test1', - ]) + self.assertTestNames( + tests, + expected=[ + "Tests2.test2", + "Tests1.test1", + "Tests1.test2", + "Tests2.test1", + ], + ) reordered_tests = reorder_tests(tests, classes=[]) - self.assertTestNames(reordered_tests, expected=[ - 'Tests2.test2', 'Tests2.test1', 'Tests1.test1', 'Tests1.test2', - ]) + self.assertTestNames( + reordered_tests, + expected=[ + "Tests2.test2", + "Tests2.test1", + "Tests1.test1", + "Tests1.test2", + ], + ) def test_reorder_tests_random(self): tests = self.make_tests() @@ -203,22 +265,40 @@ class TestSuiteTests(SimpleTestCase): shuffler = Shuffler(seed=9) reordered_tests = reorder_tests(tests, classes=[], shuffler=shuffler) self.assertIsInstance(reordered_tests, collections.abc.Iterator) - self.assertTestNames(reordered_tests, expected=[ - 'Tests2.test1', 'Tests2.test2', 'Tests1.test2', 'Tests1.test1', - ]) + self.assertTestNames( + reordered_tests, + expected=[ + "Tests2.test1", + "Tests2.test2", + "Tests1.test2", + "Tests1.test1", + ], + ) def test_reorder_tests_random_mixed_classes(self): tests = self.make_tests() # Move the last item to the front. tests.insert(0, tests.pop()) shuffler = Shuffler(seed=9) - self.assertTestNames(tests, expected=[ - 'Tests2.test2', 'Tests1.test1', 'Tests1.test2', 'Tests2.test1', - ]) + self.assertTestNames( + tests, + expected=[ + "Tests2.test2", + "Tests1.test1", + "Tests1.test2", + "Tests2.test1", + ], + ) reordered_tests = reorder_tests(tests, classes=[], shuffler=shuffler) - self.assertTestNames(reordered_tests, expected=[ - 'Tests2.test1', 'Tests2.test2', 'Tests1.test2', 'Tests1.test1', - ]) + self.assertTestNames( + reordered_tests, + expected=[ + "Tests2.test1", + "Tests2.test2", + "Tests1.test2", + "Tests1.test1", + ], + ) def test_reorder_tests_reverse_with_duplicates(self): class Tests1(unittest.TestCase): @@ -236,124 +316,133 @@ class TestSuiteTests(SimpleTestCase): subsuite = list(suite)[0] suite.addTest(subsuite) tests = list(iter_test_cases(suite)) - self.assertTestNames(tests, expected=[ - 'Tests1.test1', 'Tests2.test2', 'Tests2.test3', 'Tests1.test1', - ]) + self.assertTestNames( + tests, + expected=[ + "Tests1.test1", + "Tests2.test2", + "Tests2.test3", + "Tests1.test1", + ], + ) reordered_tests = reorder_tests(tests, classes=[]) - self.assertTestNames(reordered_tests, expected=[ - 'Tests1.test1', 'Tests2.test2', 'Tests2.test3', - ]) + self.assertTestNames( + reordered_tests, + expected=[ + "Tests1.test1", + "Tests2.test2", + "Tests2.test3", + ], + ) reordered_tests = reorder_tests(tests, classes=[], reverse=True) - self.assertTestNames(reordered_tests, expected=[ - 'Tests2.test3', 'Tests2.test2', 'Tests1.test1', - ]) + self.assertTestNames( + reordered_tests, + expected=[ + "Tests2.test3", + "Tests2.test2", + "Tests1.test1", + ], + ) class DependencyOrderingTests(unittest.TestCase): - def test_simple_dependencies(self): raw = [ - ('s1', ('s1_db', ['alpha'])), - ('s2', ('s2_db', ['bravo'])), - ('s3', ('s3_db', ['charlie'])), + ("s1", ("s1_db", ["alpha"])), + ("s2", ("s2_db", ["bravo"])), + ("s3", ("s3_db", ["charlie"])), ] dependencies = { - 'alpha': ['charlie'], - 'bravo': ['charlie'], + "alpha": ["charlie"], + "bravo": ["charlie"], } ordered = dependency_ordered(raw, dependencies=dependencies) ordered_sigs = [sig for sig, value in ordered] - self.assertIn('s1', ordered_sigs) - self.assertIn('s2', ordered_sigs) - self.assertIn('s3', ordered_sigs) - self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s1')) - self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s2')) + self.assertIn("s1", ordered_sigs) + self.assertIn("s2", ordered_sigs) + self.assertIn("s3", ordered_sigs) + self.assertLess(ordered_sigs.index("s3"), ordered_sigs.index("s1")) + self.assertLess(ordered_sigs.index("s3"), ordered_sigs.index("s2")) def test_chained_dependencies(self): raw = [ - ('s1', ('s1_db', ['alpha'])), - ('s2', ('s2_db', ['bravo'])), - ('s3', ('s3_db', ['charlie'])), + ("s1", ("s1_db", ["alpha"])), + ("s2", ("s2_db", ["bravo"])), + ("s3", ("s3_db", ["charlie"])), ] dependencies = { - 'alpha': ['bravo'], - 'bravo': ['charlie'], + "alpha": ["bravo"], + "bravo": ["charlie"], } ordered = dependency_ordered(raw, dependencies=dependencies) ordered_sigs = [sig for sig, value in ordered] - self.assertIn('s1', ordered_sigs) - self.assertIn('s2', ordered_sigs) - self.assertIn('s3', ordered_sigs) + self.assertIn("s1", ordered_sigs) + self.assertIn("s2", ordered_sigs) + self.assertIn("s3", ordered_sigs) # Explicit dependencies - self.assertLess(ordered_sigs.index('s2'), ordered_sigs.index('s1')) - self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s2')) + self.assertLess(ordered_sigs.index("s2"), ordered_sigs.index("s1")) + self.assertLess(ordered_sigs.index("s3"), ordered_sigs.index("s2")) # Implied dependencies - self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s1')) + self.assertLess(ordered_sigs.index("s3"), ordered_sigs.index("s1")) def test_multiple_dependencies(self): raw = [ - ('s1', ('s1_db', ['alpha'])), - ('s2', ('s2_db', ['bravo'])), - ('s3', ('s3_db', ['charlie'])), - ('s4', ('s4_db', ['delta'])), + ("s1", ("s1_db", ["alpha"])), + ("s2", ("s2_db", ["bravo"])), + ("s3", ("s3_db", ["charlie"])), + ("s4", ("s4_db", ["delta"])), ] dependencies = { - 'alpha': ['bravo', 'delta'], - 'bravo': ['charlie'], - 'delta': ['charlie'], + "alpha": ["bravo", "delta"], + "bravo": ["charlie"], + "delta": ["charlie"], } ordered = dependency_ordered(raw, dependencies=dependencies) ordered_sigs = [sig for sig, aliases in ordered] - self.assertIn('s1', ordered_sigs) - self.assertIn('s2', ordered_sigs) - self.assertIn('s3', ordered_sigs) - self.assertIn('s4', ordered_sigs) + self.assertIn("s1", ordered_sigs) + self.assertIn("s2", ordered_sigs) + self.assertIn("s3", ordered_sigs) + self.assertIn("s4", ordered_sigs) # Explicit dependencies - self.assertLess(ordered_sigs.index('s2'), ordered_sigs.index('s1')) - self.assertLess(ordered_sigs.index('s4'), ordered_sigs.index('s1')) - self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s2')) - self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s4')) + self.assertLess(ordered_sigs.index("s2"), ordered_sigs.index("s1")) + self.assertLess(ordered_sigs.index("s4"), ordered_sigs.index("s1")) + self.assertLess(ordered_sigs.index("s3"), ordered_sigs.index("s2")) + self.assertLess(ordered_sigs.index("s3"), ordered_sigs.index("s4")) # Implicit dependencies - self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s1')) + self.assertLess(ordered_sigs.index("s3"), ordered_sigs.index("s1")) def test_circular_dependencies(self): raw = [ - ('s1', ('s1_db', ['alpha'])), - ('s2', ('s2_db', ['bravo'])), + ("s1", ("s1_db", ["alpha"])), + ("s2", ("s2_db", ["bravo"])), ] dependencies = { - 'bravo': ['alpha'], - 'alpha': ['bravo'], + "bravo": ["alpha"], + "alpha": ["bravo"], } with self.assertRaises(ImproperlyConfigured): dependency_ordered(raw, dependencies=dependencies) def test_own_alias_dependency(self): - raw = [ - ('s1', ('s1_db', ['alpha', 'bravo'])) - ] - dependencies = { - 'alpha': ['bravo'] - } + raw = [("s1", ("s1_db", ["alpha", "bravo"]))] + dependencies = {"alpha": ["bravo"]} with self.assertRaises(ImproperlyConfigured): dependency_ordered(raw, dependencies=dependencies) # reordering aliases shouldn't matter - raw = [ - ('s1', ('s1_db', ['bravo', 'alpha'])) - ] + raw = [("s1", ("s1_db", ["bravo", "alpha"]))] with self.assertRaises(ImproperlyConfigured): dependency_ordered(raw, dependencies=dependencies) @@ -361,105 +450,108 @@ class DependencyOrderingTests(unittest.TestCase): class MockTestRunner: def __init__(self, *args, **kwargs): - if parallel := kwargs.get('parallel'): - sys.stderr.write(f'parallel={parallel}') + if parallel := kwargs.get("parallel"): + sys.stderr.write(f"parallel={parallel}") MockTestRunner.run_tests = mock.Mock(return_value=[]) class ManageCommandTests(unittest.TestCase): - def test_custom_test_runner(self): - call_command('test', 'sites', - testrunner='test_runner.tests.MockTestRunner') - MockTestRunner.run_tests.assert_called_with(('sites',)) + call_command("test", "sites", testrunner="test_runner.tests.MockTestRunner") + MockTestRunner.run_tests.assert_called_with(("sites",)) def test_bad_test_runner(self): with self.assertRaises(AttributeError): - call_command('test', 'sites', testrunner='test_runner.NonexistentRunner') + call_command("test", "sites", testrunner="test_runner.NonexistentRunner") def test_time_recorded(self): with captured_stderr() as stderr: - call_command('test', '--timing', 'sites', testrunner='test_runner.tests.MockTestRunner') - self.assertIn('Total run took', stderr.getvalue()) + call_command( + "test", + "--timing", + "sites", + testrunner="test_runner.tests.MockTestRunner", + ) + self.assertIn("Total run took", stderr.getvalue()) # Isolate from the real environment. @mock.patch.dict(os.environ, {}, clear=True) -@mock.patch.object(multiprocessing, 'cpu_count', return_value=12) +@mock.patch.object(multiprocessing, "cpu_count", return_value=12) # Python 3.8 on macOS defaults to 'spawn' mode. -@mock.patch.object(multiprocessing, 'get_start_method', return_value='fork') +@mock.patch.object(multiprocessing, "get_start_method", return_value="fork") class ManageCommandParallelTests(SimpleTestCase): def test_parallel_default(self, *mocked_objects): with captured_stderr() as stderr: call_command( - 'test', - '--parallel', - testrunner='test_runner.tests.MockTestRunner', + "test", + "--parallel", + testrunner="test_runner.tests.MockTestRunner", ) - self.assertIn('parallel=12', stderr.getvalue()) + self.assertIn("parallel=12", stderr.getvalue()) def test_parallel_auto(self, *mocked_objects): with captured_stderr() as stderr: call_command( - 'test', - '--parallel=auto', - testrunner='test_runner.tests.MockTestRunner', + "test", + "--parallel=auto", + testrunner="test_runner.tests.MockTestRunner", ) - self.assertIn('parallel=12', stderr.getvalue()) + self.assertIn("parallel=12", stderr.getvalue()) def test_no_parallel(self, *mocked_objects): with captured_stderr() as stderr: - call_command('test', testrunner='test_runner.tests.MockTestRunner') + call_command("test", testrunner="test_runner.tests.MockTestRunner") # Parallel is disabled by default. - self.assertEqual(stderr.getvalue(), '') + self.assertEqual(stderr.getvalue(), "") def test_parallel_spawn(self, mocked_get_start_method, mocked_cpu_count): - mocked_get_start_method.return_value = 'spawn' + mocked_get_start_method.return_value = "spawn" with captured_stderr() as stderr: call_command( - 'test', - '--parallel=auto', - testrunner='test_runner.tests.MockTestRunner', + "test", + "--parallel=auto", + testrunner="test_runner.tests.MockTestRunner", ) - self.assertIn('parallel=1', stderr.getvalue()) + self.assertIn("parallel=1", stderr.getvalue()) def test_no_parallel_spawn(self, mocked_get_start_method, mocked_cpu_count): - mocked_get_start_method.return_value = 'spawn' + mocked_get_start_method.return_value = "spawn" with captured_stderr() as stderr: call_command( - 'test', - testrunner='test_runner.tests.MockTestRunner', + "test", + testrunner="test_runner.tests.MockTestRunner", ) - self.assertEqual(stderr.getvalue(), '') + self.assertEqual(stderr.getvalue(), "") - @mock.patch.dict(os.environ, {'DJANGO_TEST_PROCESSES': '7'}) + @mock.patch.dict(os.environ, {"DJANGO_TEST_PROCESSES": "7"}) def test_no_parallel_django_test_processes_env(self, *mocked_objects): with captured_stderr() as stderr: - call_command('test', testrunner='test_runner.tests.MockTestRunner') - self.assertEqual(stderr.getvalue(), '') + call_command("test", testrunner="test_runner.tests.MockTestRunner") + self.assertEqual(stderr.getvalue(), "") - @mock.patch.dict(os.environ, {'DJANGO_TEST_PROCESSES': 'invalid'}) + @mock.patch.dict(os.environ, {"DJANGO_TEST_PROCESSES": "invalid"}) def test_django_test_processes_env_non_int(self, *mocked_objects): with self.assertRaises(ValueError): call_command( - 'test', - '--parallel', - testrunner='test_runner.tests.MockTestRunner', + "test", + "--parallel", + testrunner="test_runner.tests.MockTestRunner", ) - @mock.patch.dict(os.environ, {'DJANGO_TEST_PROCESSES': '7'}) + @mock.patch.dict(os.environ, {"DJANGO_TEST_PROCESSES": "7"}) def test_django_test_processes_parallel_default(self, *mocked_objects): - for parallel in ['--parallel', '--parallel=auto']: + for parallel in ["--parallel", "--parallel=auto"]: with self.subTest(parallel=parallel): with captured_stderr() as stderr: call_command( - 'test', + "test", parallel, - testrunner='test_runner.tests.MockTestRunner', + testrunner="test_runner.tests.MockTestRunner", ) - self.assertIn('parallel=7', stderr.getvalue()) + self.assertIn("parallel=7", stderr.getvalue()) class CustomTestRunnerOptionsSettingsTests(AdminScriptTestCase): @@ -467,37 +559,43 @@ class CustomTestRunnerOptionsSettingsTests(AdminScriptTestCase): Custom runners can add command line arguments. The runner is specified through a settings file. """ + def setUp(self): super().setUp() settings = { - 'TEST_RUNNER': '\'test_runner.runner.CustomOptionsTestRunner\'', + "TEST_RUNNER": "'test_runner.runner.CustomOptionsTestRunner'", } - self.write_settings('settings.py', sdict=settings) + self.write_settings("settings.py", sdict=settings) def test_default_options(self): - args = ['test', '--settings=test_project.settings'] + args = ["test", "--settings=test_project.settings"] out, err = self.run_django_admin(args) self.assertNoOutput(err) - self.assertOutput(out, '1:2:3') + self.assertOutput(out, "1:2:3") def test_default_and_given_options(self): - args = ['test', '--settings=test_project.settings', '--option_b=foo'] + args = ["test", "--settings=test_project.settings", "--option_b=foo"] out, err = self.run_django_admin(args) self.assertNoOutput(err) - self.assertOutput(out, '1:foo:3') + self.assertOutput(out, "1:foo:3") def test_option_name_and_value_separated(self): - args = ['test', '--settings=test_project.settings', '--option_b', 'foo'] + args = ["test", "--settings=test_project.settings", "--option_b", "foo"] out, err = self.run_django_admin(args) self.assertNoOutput(err) - self.assertOutput(out, '1:foo:3') + self.assertOutput(out, "1:foo:3") def test_all_options_given(self): - args = ['test', '--settings=test_project.settings', '--option_a=bar', - '--option_b=foo', '--option_c=31337'] + args = [ + "test", + "--settings=test_project.settings", + "--option_a=bar", + "--option_b=foo", + "--option_c=31337", + ] out, err = self.run_django_admin(args) self.assertNoOutput(err) - self.assertOutput(out, 'bar:foo:31337') + self.assertOutput(out, "bar:foo:31337") class CustomTestRunnerOptionsCmdlineTests(AdminScriptTestCase): @@ -505,54 +603,64 @@ class CustomTestRunnerOptionsCmdlineTests(AdminScriptTestCase): Custom runners can add command line arguments when the runner is specified using --testrunner. """ + def setUp(self): super().setUp() - self.write_settings('settings.py') + self.write_settings("settings.py") def test_testrunner_option(self): args = [ - 'test', '--testrunner', 'test_runner.runner.CustomOptionsTestRunner', - '--option_a=bar', '--option_b=foo', '--option_c=31337' + "test", + "--testrunner", + "test_runner.runner.CustomOptionsTestRunner", + "--option_a=bar", + "--option_b=foo", + "--option_c=31337", ] - out, err = self.run_django_admin(args, 'test_project.settings') + out, err = self.run_django_admin(args, "test_project.settings") self.assertNoOutput(err) - self.assertOutput(out, 'bar:foo:31337') + self.assertOutput(out, "bar:foo:31337") def test_testrunner_equals(self): args = [ - 'test', '--testrunner=test_runner.runner.CustomOptionsTestRunner', - '--option_a=bar', '--option_b=foo', '--option_c=31337' + "test", + "--testrunner=test_runner.runner.CustomOptionsTestRunner", + "--option_a=bar", + "--option_b=foo", + "--option_c=31337", ] - out, err = self.run_django_admin(args, 'test_project.settings') + out, err = self.run_django_admin(args, "test_project.settings") self.assertNoOutput(err) - self.assertOutput(out, 'bar:foo:31337') + self.assertOutput(out, "bar:foo:31337") def test_no_testrunner(self): - args = ['test', '--testrunner'] - out, err = self.run_django_admin(args, 'test_project.settings') - self.assertIn('usage', err) - self.assertNotIn('Traceback', err) + args = ["test", "--testrunner"] + out, err = self.run_django_admin(args, "test_project.settings") + self.assertIn("usage", err) + self.assertNotIn("Traceback", err) self.assertNoOutput(out) class Ticket17477RegressionTests(AdminScriptTestCase): def setUp(self): super().setUp() - self.write_settings('settings.py') + self.write_settings("settings.py") def test_ticket_17477(self): """'manage.py help test' works after r16352.""" - args = ['help', 'test'] + args = ["help", "test"] out, err = self.run_manage(args) self.assertNoOutput(err) class SQLiteInMemoryTestDbs(TransactionTestCase): - available_apps = ['test_runner'] - databases = {'default', 'other'} + available_apps = ["test_runner"] + databases = {"default", "other"} - @unittest.skipUnless(all(db.connections[conn].vendor == 'sqlite' for conn in db.connections), - "This is an sqlite-specific issue") + @unittest.skipUnless( + all(db.connections[conn].vendor == "sqlite" for conn in db.connections), + "This is an sqlite-specific issue", + ) def test_transaction_support(self): # Assert connections mocking is appropriately applied by preventing # any attempts at calling create_test_db on the global connection @@ -560,29 +668,36 @@ class SQLiteInMemoryTestDbs(TransactionTestCase): for connection in db.connections.all(): create_test_db = mock.patch.object( connection.creation, - 'create_test_db', - side_effect=AssertionError("Global connection object shouldn't be manipulated.") + "create_test_db", + side_effect=AssertionError( + "Global connection object shouldn't be manipulated." + ), ) create_test_db.start() self.addCleanup(create_test_db.stop) for option_key, option_value in ( - ('NAME', ':memory:'), ('TEST', {'NAME': ':memory:'})): - tested_connections = db.ConnectionHandler({ - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - option_key: option_value, - }, - 'other': { - 'ENGINE': 'django.db.backends.sqlite3', - option_key: option_value, - }, - }) - with mock.patch('django.test.utils.connections', new=tested_connections): - other = tested_connections['other'] + ("NAME", ":memory:"), + ("TEST", {"NAME": ":memory:"}), + ): + tested_connections = db.ConnectionHandler( + { + "default": { + "ENGINE": "django.db.backends.sqlite3", + option_key: option_value, + }, + "other": { + "ENGINE": "django.db.backends.sqlite3", + option_key: option_value, + }, + } + ) + with mock.patch("django.test.utils.connections", new=tested_connections): + other = tested_connections["other"] DiscoverRunner(verbosity=0).setup_databases() msg = ( "DATABASES setting '%s' option set to sqlite3's ':memory:' value " - "shouldn't interfere with transaction support detection." % option_key + "shouldn't interfere with transaction support detection." + % option_key ) # Transaction support is properly initialized for the 'other' DB. self.assertTrue(other.features.supports_transactions, msg) @@ -596,7 +711,7 @@ class DummyBackendTest(unittest.TestCase): setup_databases() doesn't fail with dummy database backend. """ tested_connections = db.ConnectionHandler({}) - with mock.patch('django.test.utils.connections', new=tested_connections): + with mock.patch("django.test.utils.connections", new=tested_connections): runner_instance = DiscoverRunner(verbosity=0) old_config = runner_instance.setup_databases() runner_instance.teardown_databases(old_config) @@ -607,110 +722,126 @@ class AliasedDefaultTestSetupTest(unittest.TestCase): """ setup_databases() doesn't fail when 'default' is aliased """ - tested_connections = db.ConnectionHandler({ - 'default': { - 'NAME': 'dummy' - }, - 'aliased': { - 'NAME': 'dummy' - } - }) - with mock.patch('django.test.utils.connections', new=tested_connections): + tested_connections = db.ConnectionHandler( + {"default": {"NAME": "dummy"}, "aliased": {"NAME": "dummy"}} + ) + with mock.patch("django.test.utils.connections", new=tested_connections): runner_instance = DiscoverRunner(verbosity=0) old_config = runner_instance.setup_databases() runner_instance.teardown_databases(old_config) class SetupDatabasesTests(SimpleTestCase): - def setUp(self): self.runner_instance = DiscoverRunner(verbosity=0) def test_setup_aliased_databases(self): - tested_connections = db.ConnectionHandler({ - 'default': { - 'ENGINE': 'django.db.backends.dummy', - 'NAME': 'dbname', - }, - 'other': { - 'ENGINE': 'django.db.backends.dummy', - 'NAME': 'dbname', + tested_connections = db.ConnectionHandler( + { + "default": { + "ENGINE": "django.db.backends.dummy", + "NAME": "dbname", + }, + "other": { + "ENGINE": "django.db.backends.dummy", + "NAME": "dbname", + }, } - }) + ) - with mock.patch('django.db.backends.dummy.base.DatabaseWrapper.creation_class') as mocked_db_creation: - with mock.patch('django.test.utils.connections', new=tested_connections): + with mock.patch( + "django.db.backends.dummy.base.DatabaseWrapper.creation_class" + ) as mocked_db_creation: + with mock.patch("django.test.utils.connections", new=tested_connections): old_config = self.runner_instance.setup_databases() self.runner_instance.teardown_databases(old_config) - mocked_db_creation.return_value.destroy_test_db.assert_called_once_with('dbname', 0, False) + mocked_db_creation.return_value.destroy_test_db.assert_called_once_with( + "dbname", 0, False + ) def test_setup_test_database_aliases(self): """ The default database must be the first because data migrations use the default alias by default. """ - tested_connections = db.ConnectionHandler({ - 'other': { - 'ENGINE': 'django.db.backends.dummy', - 'NAME': 'dbname', - }, - 'default': { - 'ENGINE': 'django.db.backends.dummy', - 'NAME': 'dbname', + tested_connections = db.ConnectionHandler( + { + "other": { + "ENGINE": "django.db.backends.dummy", + "NAME": "dbname", + }, + "default": { + "ENGINE": "django.db.backends.dummy", + "NAME": "dbname", + }, } - }) - with mock.patch('django.test.utils.connections', new=tested_connections): + ) + with mock.patch("django.test.utils.connections", new=tested_connections): test_databases, _ = get_unique_databases_and_mirrors() self.assertEqual( test_databases, { - ('', '', 'django.db.backends.dummy', 'test_dbname'): ( - 'dbname', - ['default', 'other'], + ("", "", "django.db.backends.dummy", "test_dbname"): ( + "dbname", + ["default", "other"], ), }, ) def test_destroy_test_db_restores_db_name(self): - tested_connections = db.ConnectionHandler({ - 'default': { - 'ENGINE': settings.DATABASES[db.DEFAULT_DB_ALIAS]["ENGINE"], - 'NAME': 'xxx_test_database', - }, - }) + tested_connections = db.ConnectionHandler( + { + "default": { + "ENGINE": settings.DATABASES[db.DEFAULT_DB_ALIAS]["ENGINE"], + "NAME": "xxx_test_database", + }, + } + ) # Using the real current name as old_name to not mess with the test suite. old_name = settings.DATABASES[db.DEFAULT_DB_ALIAS]["NAME"] - with mock.patch('django.db.connections', new=tested_connections): - tested_connections['default'].creation.destroy_test_db(old_name, verbosity=0, keepdb=True) - self.assertEqual(tested_connections['default'].settings_dict["NAME"], old_name) + with mock.patch("django.db.connections", new=tested_connections): + tested_connections["default"].creation.destroy_test_db( + old_name, verbosity=0, keepdb=True + ) + self.assertEqual( + tested_connections["default"].settings_dict["NAME"], old_name + ) def test_serialization(self): - tested_connections = db.ConnectionHandler({ - 'default': { - 'ENGINE': 'django.db.backends.dummy', - }, - }) - with mock.patch('django.db.backends.dummy.base.DatabaseWrapper.creation_class') as mocked_db_creation: - with mock.patch('django.test.utils.connections', new=tested_connections): + tested_connections = db.ConnectionHandler( + { + "default": { + "ENGINE": "django.db.backends.dummy", + }, + } + ) + with mock.patch( + "django.db.backends.dummy.base.DatabaseWrapper.creation_class" + ) as mocked_db_creation: + with mock.patch("django.test.utils.connections", new=tested_connections): self.runner_instance.setup_databases() mocked_db_creation.return_value.create_test_db.assert_called_once_with( verbosity=0, autoclobber=False, serialize=True, keepdb=False ) def test_serialized_off(self): - tested_connections = db.ConnectionHandler({ - 'default': { - 'ENGINE': 'django.db.backends.dummy', - 'TEST': {'SERIALIZE': False}, - }, - }) + tested_connections = db.ConnectionHandler( + { + "default": { + "ENGINE": "django.db.backends.dummy", + "TEST": {"SERIALIZE": False}, + }, + } + ) msg = ( - 'The SERIALIZE test database setting is deprecated as it can be ' - 'inferred from the TestCase/TransactionTestCase.databases that ' - 'enable the serialized_rollback feature.' + "The SERIALIZE test database setting is deprecated as it can be " + "inferred from the TestCase/TransactionTestCase.databases that " + "enable the serialized_rollback feature." ) - with mock.patch('django.db.backends.dummy.base.DatabaseWrapper.creation_class') as mocked_db_creation: - with mock.patch('django.test.utils.connections', new=tested_connections): + with mock.patch( + "django.db.backends.dummy.base.DatabaseWrapper.creation_class" + ) as mocked_db_creation: + with mock.patch("django.test.utils.connections", new=tested_connections): with self.assertWarnsMessage(RemovedInDjango50Warning, msg): self.runner_instance.setup_databases() mocked_db_creation.return_value.create_test_db.assert_called_once_with( @@ -718,23 +849,23 @@ class SetupDatabasesTests(SimpleTestCase): ) -@skipUnlessDBFeature('supports_sequence_reset') +@skipUnlessDBFeature("supports_sequence_reset") class AutoIncrementResetTest(TransactionTestCase): """ Creating the same models in different test methods receive the same PK values since the sequences are reset before each test method. """ - available_apps = ['test_runner'] + available_apps = ["test_runner"] reset_sequences = True def _test(self): # Regular model - p = Person.objects.create(first_name='Jack', last_name='Smith') + p = Person.objects.create(first_name="Jack", last_name="Smith") self.assertEqual(p.pk, 1) # Auto-created many-to-many through model - p.friends.add(Person.objects.create(first_name='Jacky', last_name='Smith')) + p.friends.add(Person.objects.create(first_name="Jacky", last_name="Smith")) self.assertEqual(p.friends.through.objects.first().pk, 1) # Many-to-many through model b = B.objects.create() @@ -754,10 +885,12 @@ class EmptyDefaultDatabaseTest(unittest.TestCase): An empty default database in settings does not raise an ImproperlyConfigured error when running a unit test that does not use a database. """ - tested_connections = db.ConnectionHandler({'default': {}}) - with mock.patch('django.db.connections', new=tested_connections): + tested_connections = db.ConnectionHandler({"default": {}}) + with mock.patch("django.db.connections", new=tested_connections): connection = tested_connections[db.utils.DEFAULT_DB_ALIAS] - self.assertEqual(connection.settings_dict['ENGINE'], 'django.db.backends.dummy') + self.assertEqual( + connection.settings_dict["ENGINE"], "django.db.backends.dummy" + ) connections_support_transactions() @@ -766,15 +899,22 @@ class RunTestsExceptionHandlingTests(unittest.TestCase): """ Teardown functions are run when run_checks() raises SystemCheckError. """ - with mock.patch('django.test.runner.DiscoverRunner.setup_test_environment'), \ - mock.patch('django.test.runner.DiscoverRunner.setup_databases'), \ - mock.patch('django.test.runner.DiscoverRunner.build_suite'), \ - mock.patch('django.test.runner.DiscoverRunner.run_checks', side_effect=SystemCheckError), \ - mock.patch('django.test.runner.DiscoverRunner.teardown_databases') as teardown_databases, \ - mock.patch('django.test.runner.DiscoverRunner.teardown_test_environment') as teardown_test_environment: + with mock.patch( + "django.test.runner.DiscoverRunner.setup_test_environment" + ), mock.patch("django.test.runner.DiscoverRunner.setup_databases"), mock.patch( + "django.test.runner.DiscoverRunner.build_suite" + ), mock.patch( + "django.test.runner.DiscoverRunner.run_checks", side_effect=SystemCheckError + ), mock.patch( + "django.test.runner.DiscoverRunner.teardown_databases" + ) as teardown_databases, mock.patch( + "django.test.runner.DiscoverRunner.teardown_test_environment" + ) as teardown_test_environment: runner = DiscoverRunner(verbosity=0, interactive=False) with self.assertRaises(SystemCheckError): - runner.run_tests(['test_runner_apps.sample.tests_sample.TestDjangoTestCase']) + runner.run_tests( + ["test_runner_apps.sample.tests_sample.TestDjangoTestCase"] + ) self.assertTrue(teardown_databases.called) self.assertTrue(teardown_test_environment.called) @@ -783,16 +923,23 @@ class RunTestsExceptionHandlingTests(unittest.TestCase): SystemCheckError is surfaced when run_checks() raises SystemCheckError and teardown databases() raises ValueError. """ - with mock.patch('django.test.runner.DiscoverRunner.setup_test_environment'), \ - mock.patch('django.test.runner.DiscoverRunner.setup_databases'), \ - mock.patch('django.test.runner.DiscoverRunner.build_suite'), \ - mock.patch('django.test.runner.DiscoverRunner.run_checks', side_effect=SystemCheckError), \ - mock.patch('django.test.runner.DiscoverRunner.teardown_databases', side_effect=ValueError) \ - as teardown_databases, \ - mock.patch('django.test.runner.DiscoverRunner.teardown_test_environment') as teardown_test_environment: + with mock.patch( + "django.test.runner.DiscoverRunner.setup_test_environment" + ), mock.patch("django.test.runner.DiscoverRunner.setup_databases"), mock.patch( + "django.test.runner.DiscoverRunner.build_suite" + ), mock.patch( + "django.test.runner.DiscoverRunner.run_checks", side_effect=SystemCheckError + ), mock.patch( + "django.test.runner.DiscoverRunner.teardown_databases", + side_effect=ValueError, + ) as teardown_databases, mock.patch( + "django.test.runner.DiscoverRunner.teardown_test_environment" + ) as teardown_test_environment: runner = DiscoverRunner(verbosity=0, interactive=False) with self.assertRaises(SystemCheckError): - runner.run_tests(['test_runner_apps.sample.tests_sample.TestDjangoTestCase']) + runner.run_tests( + ["test_runner_apps.sample.tests_sample.TestDjangoTestCase"] + ) self.assertTrue(teardown_databases.called) self.assertFalse(teardown_test_environment.called) @@ -801,18 +948,25 @@ class RunTestsExceptionHandlingTests(unittest.TestCase): Exceptions on teardown are surfaced if no exceptions happen during run_checks(). """ - with mock.patch('django.test.runner.DiscoverRunner.setup_test_environment'), \ - mock.patch('django.test.runner.DiscoverRunner.setup_databases'), \ - mock.patch('django.test.runner.DiscoverRunner.build_suite'), \ - mock.patch('django.test.runner.DiscoverRunner.run_checks'), \ - mock.patch('django.test.runner.DiscoverRunner.teardown_databases', side_effect=ValueError) \ - as teardown_databases, \ - mock.patch('django.test.runner.DiscoverRunner.teardown_test_environment') as teardown_test_environment: + with mock.patch( + "django.test.runner.DiscoverRunner.setup_test_environment" + ), mock.patch("django.test.runner.DiscoverRunner.setup_databases"), mock.patch( + "django.test.runner.DiscoverRunner.build_suite" + ), mock.patch( + "django.test.runner.DiscoverRunner.run_checks" + ), mock.patch( + "django.test.runner.DiscoverRunner.teardown_databases", + side_effect=ValueError, + ) as teardown_databases, mock.patch( + "django.test.runner.DiscoverRunner.teardown_test_environment" + ) as teardown_test_environment: runner = DiscoverRunner(verbosity=0, interactive=False) with self.assertRaises(ValueError): # Suppress the output when running TestDjangoTestCase. - with mock.patch('sys.stderr'): - runner.run_tests(['test_runner_apps.sample.tests_sample.TestDjangoTestCase']) + with mock.patch("sys.stderr"): + runner.run_tests( + ["test_runner_apps.sample.tests_sample.TestDjangoTestCase"] + ) self.assertTrue(teardown_databases.called) self.assertFalse(teardown_test_environment.called) @@ -836,7 +990,7 @@ class NoOpTestRunner(DiscoverRunner): class DiscoverRunnerExtraTestsDeprecationTests(SimpleTestCase): - msg = 'The extra_tests argument is deprecated.' + msg = "The extra_tests argument is deprecated." def get_runner(self): return NoOpTestRunner(verbosity=0, interactive=False) @@ -851,6 +1005,6 @@ class DiscoverRunnerExtraTestsDeprecationTests(SimpleTestCase): with captured_stderr(): with self.assertWarnsMessage(RemovedInDjango50Warning, self.msg): runner.run_tests( - test_labels=['test_runner_apps.sample.tests_sample.EmptyTestCase'], + test_labels=["test_runner_apps.sample.tests_sample.EmptyTestCase"], extra_tests=[], ) |