我试图找出实用函数执行的查询数量。我已经为此函数编写了单元测试,并且该函数运行良好。我想要做的是跟踪该函数执行的 SQL 查询的数量,以便我可以查看一些重构后是否有任何改进。

def do_something_in_the_database():
    # Does something in the database
    # return result

class DoSomethingTests(django.test.TestCase):
    def test_function_returns_correct_values(self):
        self.assertEqual(n, <number of SQL queries executed>)

编辑:我发现有一个待处理的Django 功能要求 为了这。然而,门票仍然开放。与此同时,还有其他方法可以解决这个问题吗?

有帮助吗?

解决方案

由于Django的1.3存在 assertNumQueries使用正好用于该目的。

其他提示

如果使用的是pytestpytest-django具有 django_assert_num_queries 夹具用于该目的:

def test_queries(django_assert_num_queries):
    with django_assert_num_queries(3):
        Item.objects.create('foo')
        Item.objects.create('bar')
        Item.objects.create('baz')

如果您已经DEBUGsettings.py设置为True(大概所以在测试环境中),那么你可以指望在测试执行的查询如下:

from django.db import connection

class DoSomethingTests(django.test.TestCase):
    def test_something_or_other(self):
        num_queries_old = len(connection.queries)
        do_something_in_the_database()
        num_queries_new = len(connection.queries)
        self.assertEqual(n, num_queries_new - num_queries_old)

在现代 Django (>=1.8) 中,它有很好的文档记录(1.7 也有文档记录) 这里, ,你有方法 重置查询 而不是分配 连接.查询=[] 这确实引发了一个错误,类似的东西适用于 django>=1.8:

class QueriesTests(django.test.TestCase):
    def test_queries(self):
        from django.conf import settings
        from django.db import connection, reset_queries

        try:
            settings.DEBUG = True
            # [... your ORM code ...]
            self.assertEquals(len(connection.queries), num_of_expected_queries)
        finally:
            settings.DEBUG = False
            reset_queries()

您还可以考虑在 setUp/tearDown 上重置查询,以确保为每个测试重置查询,而不是在 finally 子句上重置查询,但这种方式更明确(尽管更冗长),或者您可以使用 重置查询 在 try 子句中添加任意次数,以评估从 0 开始计数的查询。

如果你不想使用 TestCase (带有 断言查询数量)或将设置更改为 DEBUG=True,您可以使用上下文管理器 CaptureQueriesContext (与 断言查询数量 使用)。

from django.db import ConnectionHandler
from django.test.utils import CaptureQueriesContext

DB_NAME = "default"  # name of db configured in settings you want to use - "default" is standard
connection = ConnectionHandler()[DB_NAME]
with CaptureQueriesContext(connection) as context:
    ... # do your thing
num_queries = context.initial_queries - context.final_queries
assert num_queries == expected_num_queries

数据库设置

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top