如何对生产数据库运行单元测试?

时间:2010-04-06 23:58:36

标签: django unit-testing

如何针对生产数据库而不是测试数据库运行单元测试?

我的生产服务器上似乎有一个错误,但在我的开发计算机上却没有。

我不在乎数据库是否被破坏。

8 个答案:

答案 0 :(得分:3)

复制数据库或导致问题的数据库的一部分是否可行?如果您保留备份服务器,则可以从那里复制数据(确保您有另一个备份,以防您混淆备份数据库)。

基本上,你不想搞乱实时数据而你不想留下没有备份以防万一你搞砸了(你会的!)。

答案 1 :(得分:1)

简短的回答:你没有。

答案很长:你没有,你制作生产数据库的副本并在那里运行

答案 2 :(得分:1)

使用manage.py dumpdata > mydata.json从数据库中获取数据的副本。

转到您的本地计算机,将mydata.json复制到名为fixtures的应用的子目录,例如myapp/fixtures/mydata.json并且执行:

manage.py syncdb # Set up an empty database
manage.py loaddata mydata.json

您的本地数据库将填充数据,您可以进行测试。

答案 3 :(得分:0)

复制数据库......这真是一个很好的做法!!

只需执行测试,而不是调用commit,在末尾调用rollback。

答案 4 :(得分:0)

首先要尝试的是在生产服务器上的shell上手动执行测试代码。

python manage.py shell

如果这不起作用,您可能需要转储生产数据,在本地复制并将其用作您正在使用的测试用例的夹具。

如果有办法让django使用标准数据库而不创建新数据库,我认为不是创建一个fixture,你可以做一个sqldump,它通常是一个小得多的文件。

答案 5 :(得分:0)

如果你真的不关心垃圾数据库,那么Marco回复交易的答案也是我的首选。您也可以尝试NdbUnit但我个人认为它带来的额外行李并不值得获得。

您现在如何测试测试数据库?通过测试db你的意思是SQLite吗?

HTH,
Berryl

答案 6 :(得分:0)

我有一个完全慢的django-test-db套件和一个疯狂的快速运行的生产测试套件,它是从一个通用的测试模块构建的。我使用生产套件在开发过程中检查我的更改,并在我的开发机器上作为提交验证步骤。 django套件模块如下所示:

import django.test
import my_test_module
...
class MyTests(django.test.TestCase):
    def test_XXX(self):
        my_test_module.XXX(self)

生产测试套件模块使用裸单元测试,如下所示:

import unittest
import my_test_module
class MyTests(unittest.TestCase):
    def test_XXX(self):
        my_test_module.XXX(self)
suite = unittest.TestLoader().loadTestsFromTestCase(MyTests)
unittest.TextTestRunner(verbosity=2).run(suite)

测试模块如下所示:

def XXX(testcase):
    testcase.assertEquals('foo', 'bar')

我运行像这样的裸测试版本,所以我的测试在任何一种情况下都可以使用django ORM:

% python manage.py shell < run_unit_tests

其中run_unit_tests包含:

import path.to.production_module

生产模块需要与django版本略有不同的setUp()和tearDown(),您可以在其中放置任何必需的表清理。我还通过模仿测试客户端类在公共测试模块中使用django测试客户端:

class FakeDict(dict):
    """
    class that wraps dict and provides a getlist member
    used by the django view request unpacking code, used when
    passing in a FakeRequest (see below), only needed for those
    api entrypoints that have list parameters
    """
    def getlist(self, name):
        return [x for x in self.get(name)]

class FakeRequest(object):
    """
    an object mimicing the django request object passed in to views
    so we can test the api entrypoints from the developer unit test
    framework
    """
    user = get_test_user()
    GET={}
    POST={}

以下是通过客户端测试的测试模块功能的示例:

def XXX(testcase):
    if getattr(testcase, 'client', None) is None:
        req_dict = FakeDict()
    else:
        req_dict = {}
    req_dict['param'] = 'value'
    if getattr(testcase, 'client', None) is None:
        fake_req = FakeRequest()
        fake_req.POST = req_dict
        resp = view_function_to_test(fake_req)
    else:
        resp = testcase.client.post('/path/to/function_to_test/', req_dict)
    ...

我发现这个结构非常好用,套件的超高速生产版本可以节省大量时间。

答案 7 :(得分:0)

如果数据库支持模板数据库,请将生产数据库用作模板数据库。确保您的Django数据库用户具有足够的权限。

如果您使用的是PostgreSQL,您可以轻松地将生产数据库的名称指定为POSTGIS_TEMPLATE(并使用PostGIS后端)。