Django - 由测试中的代码创建的对象不会出现在测试数据库中

时间:2013-02-26 02:21:02

标签: python django

不要浪费你的时间阅读这个问题。它已经得到了回答。

我的settings.py包含:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'foo.db',
        'TEST_NAME': 'thetest.db'
    }
}

在测试代码中是这一行:

allShoes = models.Shoe.objects.filter()

allShoes应包含对象,因为该表由views.py填充,但在代码中为空。我还在测试代码中放了一个set_trace()来暂停它,并使用sqlite3程序验证foo.db包含的是对象,而不是test.db。

我已经尝试从django.test.TestCase和django.test.TransactionTestCase派生我的模型类Shoe。两者都没有。

我正在使用:

>>> django.VERSION
(1, 4, 3, 'final', 0)

(venv)bmac:ol b$ python
Python 2.7.2 (default, Jun 20 2012, 16:23:33) 
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin

对我做错了什么有任何想法?

编辑: 只是为了澄清,在运行测试并且test.db不存在之前,foo.db是空的,之前是由syncdb创建的。我的测试是Selenium测试,它会调用视图(测试中的部分代码),然后在页面上进行两次单击。每次单击都有一个调用另一个视图的AJAX处理程序;该视图(更多正在测试的代码)在数据库中创建一个条目。因此,最后,在DB被测试运行器销毁之前,DB中应该有两次单击。

编辑: 我从DATABASES中删除了TEST_NAME以使问题更简单,尽管我发现行为没有区别。在运行测试时,从我的视图代码中我可以运行:

models.Shoe.objects.using('default').all()

并查看对象。但是,从我的测试例程中,同一语句会生成一个空列表。

2 个答案:

答案 0 :(得分:1)

当Django测试运行器执行时,不会触及生产数据库。在我们的问题中,foo.db是您的生产数据库,Django确保在您运行单元测试时不会触及它。相反,它只会为了运行测试而创建一个 new 数据库。通常这将是sqlite的内存数据库,但由于您在TEST_NAME中指定了settings.py,因此测试数据库将是名为thetest.db的磁盘数据库。

除非您在测试期间调用视图代码以在测试期间填充记录,否则thetest.db中将没有任何内容。

测试用例可能看起来像这样。

from django.test import TestCase

class MyTest(TestCase):

    def test_something(self):
        # Simulate a browser POST which would populate an object in Shoes.
        # When the test starts, the db is empty.
        response = self.client.post('/shoe/add/', {
            # Post data here.
        })

        self.assertEqual(
            1,
            models.Shoe.objects.count())

答案 1 :(得分:0)

我还没有确认这个解决方案,但不希望人们花时间阅读这个问题。我相信问题出现了,因为我从我的测试代码运行Django开发服务器,以便我可以模拟连接flakiness。这导致使用生产数据库,并解释了测试数据库为空的原因。 D'哦。