67

ユーティリティ関数によって実行されたクエリの数を調べようとしています。この関数の単体テストを作成しましたが、関数はうまく機能しています。私がやりたいのは、関数によって実行された 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機能要求があることがわかりました。ただし、チケットはまだ開いています。それまでの間、これについて別の方法はありますか?

4

8 に答える 8

73

Django 1.3 以降、まさにこの目的のために利用できるassertNumQueriesがあります。

これを使用する 1 つの方法 (Django 3.2 以降) は、コンテキスト マネージャーとして使用することです。

# measure queries of some_func and some_func2
with self.assertNumQueries(2):
    result = some_func()
    result2 = some_func2()
于 2011-10-11T15:40:20.183 に答える
47

Vinayの応答は正しいですが、マイナーな追加が1つあります。

Djangoの単体テストフレームワークは、実行時に実際にDEBUGをFalseに設定するため、デバッグモードを再度有効にしない限り、単体テストsettings.pyには何も入力されません。connection.queriesDjangoのドキュメントでは、この理由を次のように説明しています。

構成ファイルのDEBUG設定の値に関係なく、すべてのDjangoテストはDEBUG=Falseで実行されます。これは、コードの観察された出力が本番環境で見られるものと一致することを保証するためです。

デバッグを有効にしてもテストに影響がないことが確実な場合(たとえば、DBヒットを具体的にテストしている場合など)、解決策は、単体テストでデバッグを一時的に再度有効にしてから設定することです。後で戻る:

def test_myself(self):
    from django.conf import settings
    from django.db import connection

    settings.DEBUG = True
    connection.queries = []

    # Test code as normal
    self.assert_(connection.queries)

    settings.DEBUG = False
于 2009-08-10T12:34:21.290 に答える
8

最新の Django (>=1.8) では十分に文書化されています (1.7 についても文書化されています) here 、実際にエラーを発生させているconnection.queries=[]を割り当てる代わりにメソッドreset_queriesがあります。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()

また、finally 句で行うのではなく、setUp/tearDown でクエリをリセットして、テストごとにクエリを確実にリセットすることを検討することもできますが、この方法はより明示的です (より冗長ではありますが)。または、try 句でreset_queriesを何度でも使用できます。 0 から数えてクエリを評価する必要があるためです。

于 2015-08-29T13:20:10.370 に答える
4

DEBUG(おそらくテスト環境で) True に設定した場合settings.py、テストで実行されたクエリを次のようにカウントできます。

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)
于 2009-08-10T11:25:33.357 に答える