【问题标题】:Django multi db test fails post teardownDjango 多数据库测试在拆解后失败
【发布时间】:2019-01-09 04:38:47
【问题描述】:

我的多数据库测试问题如下:

# (django 2.0.7, python 3.6)
# settings.py:

DATABASES = {
    'default':{}, 
    'one': { # connection1 settings here }
    'two': { # connection2 settings here }
}
DATABASE_ROUTERS = []

# test.py
class MyTestCase(TestCase):

    def test_my_function(self):
         pass # this IS literally the code

我运行python manage.py test -v 2 并看到测试运行器构建了两个模拟数据库并运行绿色测试

test_my_function (mymodule.test.MyTestCase) ... ok

然后ERROR 然后ERROR: test_get_pronunciation (languages.test_hr.HRTestCase)

有以下解释:

File "/Users/Barnabas/PycharmProjects/rhymedict-multisite/venv/lib/python3.6/site-packages/django/db/backends/dummy/base.py", line 20, in complain
    raise ImproperlyConfigured("settings.DATABASES is improperly configured. "
django.core.exceptions.ImproperlyConfigured: settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.

这应该意味着程序试图访问'default' 数据库。

(如果我将multi_db = True 添加到我的MyTestCase,也会发生同样的事情)

然而奇怪的是,如果我写了

class MyTestCase(TestCase):
    pass

数据库是建立起来的,拆掉就好了。

我做错了什么?

更新:

self._post_teardown() 引发错误,我可以看到两个虚拟数据库之前都已成功拆除。

【问题讨论】:

  • 你为什么要定义default,而不仅仅是onetwo
  • 否则我会得到django.db.utils.ConnectionDoesNotExist: The connection default doesn't existrunserver
  • 是的,但是你为什么不简单地定义one作为默认值,那么你有两个数据库,所以没有一个空的。
  • 我不想这样做,因为这是两个使用几乎相同代码运行的独立站点。 https://docs.djangoproject.com/en/2.0/topics/db/multi-db/ 也允许我的设置。

标签: django django-models django-testing


【解决方案1】:

解决方案:我需要使用SimpleTestCase 而不是TestCase,瞧,问题解决了。

问题发生在 _post_teardown() 中,它应该是一个空函数(因为它在 TestCase 中是空的),但由于某种原因,TransactionTestCase_post_teardown() 被执行了。

【讨论】:

    【解决方案2】:

    这就是我如何让测试与两个数据库一起工作,就像一个魅力:

    import sys
    
    if 'test' in sys.argv or 'test_coverage' in sys.argv: 
        DATABASES = {
            'default':{
                'ENGINE':'django.db.backends.sqlite3' # <---- you can add other db connections..
            }
        }
    else:
        DATABASES = {
            'default': {},
                'one': { # connection1 settings here }
                'two': { # connection2 settings here }
        }
    
        # DB routers specification path - case sensitive:
        # ** needs to be within the same scope of DATABASES.
        DATABASE_ROUTERS = ['myapp.routers.db_router.MyRouter']
    

    关于测试文件:

    class TestModel(TestCase):
    
        databases = '__all__'
    
        . . .
    

    【讨论】:

    • 您的解决方案很好,请注意,它仅在您仅使用“一”和“二”作为镜像或备份并且您不需要明确需要数据库一和二进行测试时才有效。 (我最终只使用了一个数据库并为表添加前缀(one_table1、two_table1 等),因为 postgres 更喜欢使用更少的数据库。前缀方法为我避免了很多痛苦。)
    • 当然,对我来说它是一种魅力,因为对我们来说,需要多个数据库才能与 AWS 合作。
    猜你喜欢
    • 2012-04-20
    • 1970-01-01
    • 2020-07-14
    • 2020-09-13
    • 2018-08-20
    • 2016-03-21
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    相关资源
    最近更新 更多