Refs #35660 -- Updated TransactionTestCase methods into class or static methods.

This commit is contained in:
Jacob Walls 2024-09-04 09:33:31 -04:00 committed by Sarah Boyce
parent d2c97981fb
commit 8eca3e9bce
2 changed files with 42 additions and 39 deletions

View File

@ -379,14 +379,15 @@ class SimpleTestCase(unittest.TestCase):
result.addError(self, sys.exc_info()) result.addError(self, sys.exc_info())
return return
def _pre_setup(self): @classmethod
def _pre_setup(cls):
""" """
Perform pre-test setup: Perform pre-test setup:
* Create a test client. * Create a test client.
* Clear the mail test outbox. * Clear the mail test outbox.
""" """
self.client = self.client_class() cls.client = cls.client_class()
self.async_client = self.async_client_class() cls.async_client = cls.async_client_class()
mail.outbox = [] mail.outbox = []
def _post_teardown(self): def _post_teardown(self):
@ -1106,7 +1107,8 @@ class TransactionTestCase(SimpleTestCase):
# This can be slow; this flag allows enabling on a per-case basis. # This can be slow; this flag allows enabling on a per-case basis.
serialized_rollback = False serialized_rollback = False
def _pre_setup(self): @classmethod
def _pre_setup(cls):
""" """
Perform pre-test setup: Perform pre-test setup:
* If the class has an 'available_apps' attribute, restrict the app * 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. * If the class has a 'fixtures' attribute, install those fixtures.
""" """
super()._pre_setup() super()._pre_setup()
if self.available_apps is not None: if cls.available_apps is not None:
apps.set_available_apps(self.available_apps) apps.set_available_apps(cls.available_apps)
setting_changed.send( setting_changed.send(
sender=settings._wrapped.__class__, sender=settings._wrapped.__class__,
setting="INSTALLED_APPS", setting="INSTALLED_APPS",
value=self.available_apps, value=cls.available_apps,
enter=True, 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) emit_post_migrate_signal(verbosity=0, interactive=False, db=db_name)
try: try:
self._fixture_setup() cls._fixture_setup()
except Exception: except Exception:
if self.available_apps is not None: if cls.available_apps is not None:
apps.unset_available_apps() apps.unset_available_apps()
setting_changed.send( setting_changed.send(
sender=settings._wrapped.__class__, 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 # 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, # test probably won't execute 9K queries). If queries_log overflows,
# then assertNumQueries() doesn't work. # 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() connections[db_name].queries_log.clear()
@classmethod @classmethod
@ -1156,7 +1158,8 @@ class TransactionTestCase(SimpleTestCase):
) )
] ]
def _reset_sequences(self, db_name): @staticmethod
def _reset_sequences(db_name):
conn = connections[db_name] conn = connections[db_name]
if conn.features.supports_sequence_reset: if conn.features.supports_sequence_reset:
sql_list = conn.ops.sequence_reset_by_name_sql( sql_list = conn.ops.sequence_reset_by_name_sql(
@ -1168,26 +1171,27 @@ class TransactionTestCase(SimpleTestCase):
for sql in sql_list: for sql in sql_list:
cursor.execute(sql) cursor.execute(sql)
def _fixture_setup(self): @classmethod
for db_name in self._databases_names(include_mirrors=False): def _fixture_setup(cls):
for db_name in cls._databases_names(include_mirrors=False):
# Reset sequences # Reset sequences
if self.reset_sequences: if cls.reset_sequences:
self._reset_sequences(db_name) cls._reset_sequences(db_name)
# Provide replica initial data from migrated apps, if needed. # 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" connections[db_name], "_test_serialized_contents"
): ):
if self.available_apps is not None: if cls.available_apps is not None:
apps.unset_available_apps() apps.unset_available_apps()
connections[db_name].creation.deserialize_db_from_string( connections[db_name].creation.deserialize_db_from_string(
connections[db_name]._test_serialized_contents connections[db_name]._test_serialized_contents
) )
if self.available_apps is not None: if cls.available_apps is not None:
apps.set_available_apps(self.available_apps) apps.set_available_apps(cls.available_apps)
if self.fixtures: if cls.fixtures:
call_command("loaddata", *self.fixtures, verbosity=0, database=db_name) call_command("loaddata", *cls.fixtures, verbosity=0, database=db_name)
def _should_reload_connections(self): def _should_reload_connections(self):
return True return True
@ -1427,25 +1431,26 @@ class TestCase(TransactionTestCase):
return False return False
return super()._should_reload_connections() return super()._should_reload_connections()
def _fixture_setup(self): @classmethod
if not self._databases_support_transactions(): def _fixture_setup(cls):
if not cls._databases_support_transactions():
# If the backend does not support transactions, we should reload # If the backend does not support transactions, we should reload
# class data before each test # class data before each test
self.setUpTestData() cls.setUpTestData()
return super()._fixture_setup() return super()._fixture_setup()
if self.reset_sequences: if cls.reset_sequences:
raise TypeError("reset_sequences cannot be used on TestCase instances") raise TypeError("reset_sequences cannot be used on TestCase instances")
self.atomics = self._enter_atomics() cls.atomics = cls._enter_atomics()
if not self._databases_support_savepoints(): if not cls._databases_support_savepoints():
if self.fixtures: if cls.fixtures:
for db_name in self._databases_names(include_mirrors=False): for db_name in cls._databases_names(include_mirrors=False):
call_command( call_command(
"loaddata", "loaddata",
*self.fixtures, *cls.fixtures,
**{"verbosity": 0, "database": db_name}, **{"verbosity": 0, "database": db_name},
) )
self.setUpTestData() cls.setUpTestData()
def _fixture_teardown(self): def _fixture_teardown(self):
if not self._databases_support_transactions(): if not self._databases_support_transactions():

View File

@ -65,14 +65,12 @@ class TestTestCase(TestCase):
@skipUnlessDBFeature("supports_transactions") @skipUnlessDBFeature("supports_transactions")
def test_reset_sequences(self): def test_reset_sequences(self):
old_reset_sequences = self.reset_sequences old_reset_sequences = self.__class__.reset_sequences
self.reset_sequences = True self.__class__.reset_sequences = True
self.addCleanup(setattr, self.__class__, "reset_sequences", old_reset_sequences)
msg = "reset_sequences cannot be used on TestCase instances" msg = "reset_sequences cannot be used on TestCase instances"
try: with self.assertRaisesMessage(TypeError, msg):
with self.assertRaisesMessage(TypeError, msg): self._fixture_setup()
self._fixture_setup()
finally:
self.reset_sequences = old_reset_sequences
def assert_no_queries(test): def assert_no_queries(test):