为什么测试中查询未被添加到Django的db.connection.queries中?

9 投票
4 回答
3031 浏览
提问于 2025-04-16 03:50

我正在尝试通过查看 django.db.connection.queries 的内容来捕捉我的代码提交给数据库的查询。不过,不知道为什么,在所有自动生成的设置查询记录之后,我自己代码的查询没有被记录下来。下面的测试案例展示了这个情况。

from django.test import TestCase
from django.db import reset_queries, connection
from django.contrib.auth.models import User
from django.conf import settings

class Test1(TestCase):
    def setUp(self):
        settings.DEBUG = True

    def test1(self):
        self.assert_(settings.DEBUG, 'DEBUG is False')
        reset_queries() #clears out all the setup queries
        User.objects.all()
        self.assert_(connection.queries, 'No queries')

这是运行这个测试后的结果:

Traceback (most recent call last):
  File "/Users/jacob/foo/bar_project/baz_application/tests.py", line 246, in test1
    self.assert_(connection.queries)
AssertionError: No queries

有没有人能帮我解释一下这个问题?谢谢。

4 个回答

5

当你运行测试时,Django的测试框架会把 DEBUG 设置为 False,这是明确指定的。

9

你需要明确地设置 DEBUG。比如,可以看看 Django 文档中关于 这些测试 的示例用法部分:

# Set up.
# The test runner sets settings.DEBUG to False, but we want to gather queries
# so we'll set it to True here and reset it at the end of the test suite.
>>> from django.conf import settings
>>> settings.DEBUG = True

更新:我可能漏掉了什么,但在每个测试中这样做肯定能解决问题。看看 DjangoTestSuiteRunner -- 看起来 DEBUGsetup_test_environment 中被设置为 False,而这个方法是在 run_tests 中调用的,接着它会实例化一个 DjangoTestRunner 并调用它的 run method。所以你需要把这个设置改回来 -- 根据我快速浏览的 代码,在你的 setup 方法中这样做可能就足够了。

5

执行 User.objects.all() 后,你不会看到任何查询。这是很正常的现象。原因是什么呢?因为查询集是懒惰的。也就是说,除非你对这个查询集做了什么操作,否则不会触发任何查询。为了验证这个想法,你可以试试下面的代码,看看结果是否符合预期。

class Test1(TestCase):
    def setUp(self):
        settings.DEBUG = True

    def test1(self):
        self.assert_(settings.DEBUG, 'DEBUG is False')
        reset_queries() #clears out all the setup queries
        print User.objects.all() # <============= Printing the queryset.
        self.assert_(connection.queries, 'No queries')

撰写回答