如何在生产数据库上运行django单元测试?

时间:2009-10-29 20:50:17

标签: python django unit-testing

我正在开始TDD开发态度,正在为我的django应用程序编写单元测试。我知道固定装置并且知道测试应该执行的方式,但是对于给定的测试,我确实需要在整个数据库上执行它,并且用于10万行数据库的json fixture不是我想要处理的东西此外,这个测试是“只读”。

所以问题是你如何设置测试套件以在生产数据库上运行?我想这可能就像在某些测试的setUp方法中添加DATABASE_NAME设置一样简单。但是settings.DATABASE_NAME =“prod_db”在运行测试时导致“NameError:全局名称'设置'未定义”。此外,http://code.djangoproject.com/ticket/11987中描述的风险可能会意外删除生产数据库。

那么,如何在生产数据库而不是临时数据库上运行测试套件的单一测试,或者甚至更好的是什么是最佳实践呢?

提前为任何意见干杯!

5 个答案:

答案 0 :(得分:63)

如果有人谷歌在这里搜索给定问题的解决方案,这里是关于如何在django生产数据库上执行单元测试的框架。检查django docs部分here,了解文件/目录结构,以及有关放置给定代码的位置的说明。它应该放在yourapp/management/commands/newcommandname.py中,管理文件和命令文件夹都应包含空__init__.py文件,这使得python将它们视为有效模块。

测试套件可以运行:

  

$ python manage.py newcommandname

这里有你应该放在yourapp/management/commands/newcommandname.py中的代码:

from django.core.management.base import BaseCommand
import unittest

class Command(BaseCommand):
    help = """
    If you need Arguments, please check other modules in 
    django/core/management/commands.
    """

    def handle(self, **options):
        suite = unittest.TestLoader().loadTestsFromTestCase(TestChronology)
        unittest.TextTestRunner().run(suite)


class TestChronology(unittest.TestCase):
    def setUp(self):
        print "Write your pre-test prerequisites here"

    def test_equality(self):
        """
        Tests that 1 + 1 always equals 2.
        """
        from core.models import Yourmodel
        self.failUnlessEqual(1 + 1, 2)

答案 1 :(得分:12)

首先,如果你在生产数据库上运行它,它就不是一个“单元”测试了。

这是一流的批处理作业,需要像对待一流的批量作业一样对待。

您不能使用Django test命令查看生产数据。它总是创建一个空数据库,该数据库从TestCase中的fixture中填充。

您可以使生产数据库处理正确的management command。这个环境都已正确配置,因此您的命令可以简单地使用Django ORM来处理您的数据。

另一种方法是确保配置settings。或 使用DJANGO_SETTINGS_MODULE环境变量或使用settings.configure()函数创建环境。

然后,您可以导入模型并对生产数据库执行要执行的处理。

如果您愿意,可以将其称为“测试”,但是您正在查看生产数据,因此必须将其视为生产应用程序,以获取设置文件并使用正确的ORM配置。

答案 2 :(得分:4)

此TEST_RUNNER适用于Django 1.3

from django.test.simple import DjangoTestSuiteRunner as TestRunner

class DjangoTestSuiteRunner(TestRunner):
    def setup_databases(self, **kwargs):
        pass

    def teardown_databases(self, old_config, **kwargs):
        pass

答案 3 :(得分:2)

单元测试旨在测试没有任何副作用。虽然你的测试不会被称为unittest。如果你想要这样做,你可以使用一个自定义测试运行器来设置数据库(或者在你的情况下使用现有的数据库)。

您可以在settings.py文件中设置TEST_RUNNER设置。默认位于django.test.simple.run_tests。你可以在这里查看来源: http://code.djangoproject.com/browser/django/trunk/django/test/simple.py

将代码复制并粘贴到新文件中,并从代码中删除以下行:

connection.creation.create_test_db(verbosity, autoclobber=not interactive)
...
connection.creation.destroy_test_db(old_name, verbosity)

这将阻止django创建测试数据库并重置设置文件的数据库配置。

答案 4 :(得分:1)

这不是一个好主意,但是如果您知道自己在做什么(基本上会破坏生产),则可以检查以下设置:

https://docs.djangoproject.com/en/2.2/ref/settings/#test

DATABASES = {
  'default': {
     ...
     'TEST': {
        'NAME': 'your prod db'
     }
}