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

26 投票
5 回答
18680 浏览
提问于 2025-04-15 15:30

我最近开始学习测试驱动开发(TDD),正在为我的Django应用写单元测试。我知道可以使用数据快照(fixtures),这是测试执行的标准方法,但有些测试需要在整个数据库上运行,而对于一个有超过1000万行数据的数据库,使用JSON格式的数据快照我实在不想去处理。而且,这个测试是“只读”的。

所以,我想问问大家,你们是怎么设置测试套件,让它们在生产数据库上运行的?我想这可能很简单,只要在某个测试的setUp方法中添加DATABASE_NAME的设置就行了。但是,当我把settings.DATABASE_NAME设置为"prod_db"时,运行测试时却出现了"NameError: global name 'settings' is not defined"的错误。而且,Django的一个问题描述中提到过,意外删除生产数据库的风险,链接在这里:http://code.djangoproject.com/ticket/11987

那么,如何才能做到这一点?或者说,更好的是,最好的做法是什么,能让一个测试在生产数据库上运行,而不是在临时数据库上?

提前感谢大家的意见!

5 个回答

6

这个测试运行器适用于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
75

如果有人在网上搜索解决某个问题,这里有一个关于如何在Django生产数据库上进行单元测试的基本框架。你可以查看Django文档中的相关部分,了解文件和目录的结构,以及代码应该放在哪里。代码应该放在 yourapp/management/commands/newcommandname.py 这个位置,同时,management和commands文件夹里也需要有空的 __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)
15

首先,如果你是在生产数据库上运行这个,那就不算真正的“单元”测试了。

这其实是一个重要的批处理任务,需要像对待正式的生产批处理任务一样来处理。

你不能用Django的test命令来查看生产数据。这个命令总是会创建一个空的数据库,然后从测试用例中的数据填充进去。

你可以把处理生产数据库的过程做成一个合适的管理命令。这样环境就会配置好,你的命令可以直接使用Django的ORM来处理数据。

另一种方法是确保你配置好你的设置。你可以使用DJANGO_SETTINGS_MODULE这个环境变量,或者用settings.configure()函数来创建一个环境。

这样你就可以导入模型,进行你想在生产数据库上执行的处理。

你可以叫它“测试”,但因为你是在查看生产数据,所以必须像对待生产应用一样,认真对待设置文件和使用正确的ORM配置。

撰写回答