在Django中使用多个数据库打破了测试隔离。怎么解决?

问题描述 投票:1回答:1

Django的TestCase类将每个测试包装在一个事务中,并在每次测试后回滚该事务,以便提供测试隔离。

但是,显然,只有default数据库中的操作才属于交易范围。我有一个带有路由器的多数据库设置,它将某些模型上的ORM调用指向第二个数据库。这意味着在以下示例中,test2失败:

class MyTestCase(TestCase):

    def test1(self):
        # Let's say Foo model ORM calls are routed to a different DB
        foo = Foo.objects.create(...)
        assert foo.is_ok()

    def test2(self):
        assert not Foo.objects.exists()

这个问题的最直接的解决方案是覆盖tearDown中的MyTestCase方法并手动确保删除所有Foo对象。但这有点令人讨厌,因为它只是一种破解,数据库序列(例如自动增量列)不会被重置,例如,只有在测试套件完成并且数据库被销毁之后。

有没有办法正确解决这个问题,确保默认情况下在事务中进行所有数据库操作并在每次测试结束时回滚?

[UPDATE]

这是我的路由器:

class FooRouter(object):

    def db_for_read(self, model, **hints):

        if model._meta.app_label == 'foo':
            return 'foo_db'

        return None

    def db_for_write(self, model, **hints):

        if model._meta.app_label == 'foo':
            return 'foo_db'

        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):

        if app_label == 'foo':
            return db == 'foo_db'

        return None
python django testing transactions
1个回答
1
投票

如果您不使用数据库路由器,您可以尝试将multi_db = True添加到TestCase以调用所有数据库的刷新

class YourTestCase(TestCase):
   multi_db = True

   def test_something(self):
       pass

Django docs

© www.soinside.com 2019 - 2024. All rights reserved.