diff --git a/django/test/testcases.py b/django/test/testcases.py index cd7e7b45d6..13ceb4a8ea 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -379,14 +379,15 @@ class SimpleTestCase(unittest.TestCase): result.addError(self, sys.exc_info()) return - def _pre_setup(self): + @classmethod + def _pre_setup(cls): """ Perform pre-test setup: * Create a test client. * Clear the mail test outbox. """ - self.client = self.client_class() - self.async_client = self.async_client_class() + cls.client = cls.client_class() + cls.async_client = cls.async_client_class() mail.outbox = [] def _post_teardown(self): @@ -1106,7 +1107,8 @@ class TransactionTestCase(SimpleTestCase): # This can be slow; this flag allows enabling on a per-case basis. serialized_rollback = False - def _pre_setup(self): + @classmethod + def _pre_setup(cls): """ Perform pre-test setup: * If the class has an 'available_apps' attribute, restrict the app @@ -1115,20 +1117,20 @@ class TransactionTestCase(SimpleTestCase): * If the class has a 'fixtures' attribute, install those fixtures. """ super()._pre_setup() - if self.available_apps is not None: - apps.set_available_apps(self.available_apps) + if cls.available_apps is not None: + apps.set_available_apps(cls.available_apps) setting_changed.send( sender=settings._wrapped.__class__, setting="INSTALLED_APPS", - value=self.available_apps, + value=cls.available_apps, enter=True, ) - for db_name in self._databases_names(include_mirrors=False): + for db_name in cls._databases_names(include_mirrors=False): emit_post_migrate_signal(verbosity=0, interactive=False, db=db_name) try: - self._fixture_setup() + cls._fixture_setup() except Exception: - if self.available_apps is not None: + if cls.available_apps is not None: apps.unset_available_apps() setting_changed.send( sender=settings._wrapped.__class__, @@ -1140,7 +1142,7 @@ class TransactionTestCase(SimpleTestCase): # Clear the queries_log so that it's less likely to overflow (a single # test probably won't execute 9K queries). If queries_log overflows, # then assertNumQueries() doesn't work. - for db_name in self._databases_names(include_mirrors=False): + for db_name in cls._databases_names(include_mirrors=False): connections[db_name].queries_log.clear() @classmethod @@ -1156,7 +1158,8 @@ class TransactionTestCase(SimpleTestCase): ) ] - def _reset_sequences(self, db_name): + @staticmethod + def _reset_sequences(db_name): conn = connections[db_name] if conn.features.supports_sequence_reset: sql_list = conn.ops.sequence_reset_by_name_sql( @@ -1168,26 +1171,27 @@ class TransactionTestCase(SimpleTestCase): for sql in sql_list: cursor.execute(sql) - def _fixture_setup(self): - for db_name in self._databases_names(include_mirrors=False): + @classmethod + def _fixture_setup(cls): + for db_name in cls._databases_names(include_mirrors=False): # Reset sequences - if self.reset_sequences: - self._reset_sequences(db_name) + if cls.reset_sequences: + cls._reset_sequences(db_name) # Provide replica initial data from migrated apps, if needed. - if self.serialized_rollback and hasattr( + if cls.serialized_rollback and hasattr( connections[db_name], "_test_serialized_contents" ): - if self.available_apps is not None: + if cls.available_apps is not None: apps.unset_available_apps() connections[db_name].creation.deserialize_db_from_string( connections[db_name]._test_serialized_contents ) - if self.available_apps is not None: - apps.set_available_apps(self.available_apps) + if cls.available_apps is not None: + apps.set_available_apps(cls.available_apps) - if self.fixtures: - call_command("loaddata", *self.fixtures, verbosity=0, database=db_name) + if cls.fixtures: + call_command("loaddata", *cls.fixtures, verbosity=0, database=db_name) def _should_reload_connections(self): return True @@ -1427,25 +1431,26 @@ class TestCase(TransactionTestCase): return False return super()._should_reload_connections() - def _fixture_setup(self): - if not self._databases_support_transactions(): + @classmethod + def _fixture_setup(cls): + if not cls._databases_support_transactions(): # If the backend does not support transactions, we should reload # class data before each test - self.setUpTestData() + cls.setUpTestData() return super()._fixture_setup() - if self.reset_sequences: + if cls.reset_sequences: raise TypeError("reset_sequences cannot be used on TestCase instances") - self.atomics = self._enter_atomics() - if not self._databases_support_savepoints(): - if self.fixtures: - for db_name in self._databases_names(include_mirrors=False): + cls.atomics = cls._enter_atomics() + if not cls._databases_support_savepoints(): + if cls.fixtures: + for db_name in cls._databases_names(include_mirrors=False): call_command( "loaddata", - *self.fixtures, + *cls.fixtures, **{"verbosity": 0, "database": db_name}, ) - self.setUpTestData() + cls.setUpTestData() def _fixture_teardown(self): if not self._databases_support_transactions(): diff --git a/tests/test_utils/test_testcase.py b/tests/test_utils/test_testcase.py index efca01e29e..866e0dccc6 100644 --- a/tests/test_utils/test_testcase.py +++ b/tests/test_utils/test_testcase.py @@ -65,14 +65,12 @@ class TestTestCase(TestCase): @skipUnlessDBFeature("supports_transactions") def test_reset_sequences(self): - old_reset_sequences = self.reset_sequences - self.reset_sequences = True + old_reset_sequences = self.__class__.reset_sequences + self.__class__.reset_sequences = True + self.addCleanup(setattr, self.__class__, "reset_sequences", old_reset_sequences) msg = "reset_sequences cannot be used on TestCase instances" - try: - with self.assertRaisesMessage(TypeError, msg): - self._fixture_setup() - finally: - self.reset_sequences = old_reset_sequences + with self.assertRaisesMessage(TypeError, msg): + self._fixture_setup() def assert_no_queries(test):