我一直在 django 中遇到大型数据集的单元测试运行速度非常慢(2 小时以上)的问题,因此编写了以下内容以实现更快的测试,通过用这个替换我们所有的夹具加载测试将时间缩短到 40 分钟我最初写它是为了用创建的静态 django 模型对象替换我们的固定装置。
from django.core.management import call_command
from django.db import transaction, DEFAULT_DB_ALIAS, connection, connections
from django import test
from django.test import TransactionTestCase
from django.test.testcases import disable_transaction_methods, \
restore_transaction_methods
class FastTestCase(TransactionTestCase):
"""
FastTestCase is a TransactionTestCase utilising a save point following the global setup
to rollback following each test. This works in the same way FastFixtures would work,
but allows rolling back to after the fixtures were loaded in order to speed up tests when
very large data sets are being created.
FastTestCase was written to assist in avoiding having to make a lot of changes to JSON fixtures
when model changes had been made in order to enable unit tests to continue passing.
NOTE: this is slower when small test data sets are being used!
"""
@classmethod
def setUpClass(cls):
if test.testcases.connections_support_transactions():
transaction.enter_transaction_management(using=DEFAULT_DB_ALIAS)
transaction.managed(True, using=DEFAULT_DB_ALIAS)
disable_transaction_methods()
cls.fixtures_loaded = False
@classmethod
def tearDownClass(cls):
if test.testcases.connections_support_transactions():
restore_transaction_methods()
transaction.rollback(using=DEFAULT_DB_ALIAS)
transaction.leave_transaction_management(using=DEFAULT_DB_ALIAS)
for connection in connections.all():
connection.close()
def globalSetUp(self):
"""
Hook method to be overridden and provide fast fixtures style of setup
"""
def _fixture_setup(self):
from django.contrib.sites.models import Site
Site.objects.clear_cache()
if not self.__class__.fixtures_loaded:
if hasattr(self, 'fixtures'):
call_command('loaddata',*self.fixtures, **{'verbosity':0,'commit':False,'database':DEFAULT_DB_ALIAS})
self.globalSetUp()
if test.testcases.connections_support_transactions():
self.__class__.fixtures_loaded = True
if test.testcases.connections_support_transactions():
self.save_point = transaction.savepoint()
def _fixture_teardown(self):
if test.testcases.connections_support_transactions():
transaction.savepoint_rollback(self.save_point)
else:
super(FastTestCase, self)._fixture_teardown()
def _post_teardown(self):
self._fixture_teardown()
self._urlconf_teardown()
我现在正在寻求进一步提高速度,有什么方法可以让我更快更有效地处理较小的数据集?