用大数据集加速Django测试

2024-04-30 01:56:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我在django中遇到了非常慢的单元测试运行(2小时以上)的问题,所以写了下面的内容来加快测试速度,用我最初编写的用静态django模型对象创建的fixture替换我们的fixture,从而使测试速度降到40分钟。在

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()

我现在希望进一步提高速度,有什么方法可以让它对较小的数据集更快更有效?在


Tags: todjangofromtestimportselfdefaultdb