2010-04-06 74 views
4

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

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

我不在乎数据库是否被删除。

+2

第一个明显的问题是:你能得到一个数据库的副本吗? – 2010-04-07 00:06:13

+0

我会尝试首先复制所有数据库环境,即相同的数据库软件,相同的版本,相同的设置,相同的数据。使您的开发数据库与生产数据库真正相同。 – 2010-04-07 08:21:16

+0

你没有。单元测试不会与数据库交谈。 – 2010-04-09 19:40:40

回答

3

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

基本上,你不想混淆实时数据,并且你不想留下没有备份的情况,以免你把事情搞砸(你会的!)。

+1

Django有一种方法可以告诉测试运行者复制生产数据库而不是创建一个空的数据库吗? – 2011-07-07 12:42:35

0

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

只需执行测试,而不是调用commit,在最后调用回滚。

0

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

python manage.py shell 

如果不工作,你可能需要倾倒生产数据,本地复制它,并把它作为你正在使用的测试用例的常客。

如果有一种方法可以让django使用标准数据库而不需要创建一个新的标准数据库,我认为不是创建一个夹具,而是创建一个sqldump,它通常是一个更小的文件。

1

简答:你没有。

龙答:你没有,你使生产数据库的副本,并运行它有

0

如果你真的不关心捣毁分贝,然后滚动的马可的答案回交易是我的也是首选。你也可以尝试NdbUnit,但我个人认为它带来的额外负担是值得的。

你现在如何测试测试数据库?通过测试分贝你的意思是SQLite?

HTH,
Berryl

1

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

转到您的本地机器,将mydata.json复制到您应用的子目录fixturesmyapp/fixtures/mydata.json做:

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

本地数据库将数据填充,你可以测试了。

0

我有一个完整的缓慢的django测试数据库套件和一个疯狂的快速运行反生产测试套件从一个共同的测试模块构建。我使用生产套件在开发过程中检查我的更改,并将其作为我开发计算机上的提交验证步骤。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 

生产模块需要一个稍微不同的设置()和tearDown()从Django的版本,你可以把任何所需的表清理在那里。我还通过模拟测试客户端类使用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) 
    ... 

我已经发现这种结构运行得非常好,该套件的超快速生产版本是一个重要的节省时间。

0

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

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

相关问题