Frage

Ich versuche, die Anzahl der Abfragen durch eine Nutzenfunktion ausgeführt, um herauszufinden. Ich habe einen Komponententest für diese Funktion geschrieben und die Funktion gut funktioniert. Was ich möchte, ist die Anzahl der SQL-Abfragen durch die Funktion ausgeführt, um den Überblick, so dass ich sehen kann, ob es eine Verbesserung nach einigem Refactoring ist.

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>)

EDIT: Ich fand heraus, dass es eine Django anhängig Feature-Anfrage für diese. Allerdings ist das Ticket noch offen. In der Zwischenzeit gibt es eine andere Art und Weise, um dies zu?

War es hilfreich?

Lösung

Da Django 1.3 gibt es eine assertNumQueries verfügbar genau für diesen Zweck.

Andere Tipps

Vinay Antwort richtig ist, mit einem kleinen Zusatz.

Djangos Unit-Test-Framework DEBUG auf False tatsächlich einstellt, wenn es läuft, also egal, was Sie in settings.py haben, werden Sie nichts in connection.queries in Ihrem Unit-Test bevölkert haben, wenn Sie wieder aktivieren Debug-Modus. Die Django docs erklärt die Begründung für diese als:

  

Unabhängig vom Wert der DEBUG-Einstellung in der Konfigurationsdatei, die alle Django-Tests mit DEBUG ausführen = False. Damit soll sichergestellt werden, dass die beobachtete Ausgabe des Codes übereinstimmt, was in einer Produktionsumgebung zu sehen sein wird.

Wenn Sie sicher sind, dass die Debug ermöglicht wird Ihre Tests beeinflussen (zB wenn Sie speziell zu test DB trifft, wie es klingt wie Sie sind), ist die Lösung, um vorübergehend wieder aktivieren Debug in Ihrem Gerät zu testen, legen sie es dann wieder später:

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

Wenn Sie pytest verwenden, pytest-django hat django_assert_num_queries Halterung für diesen Zweck:

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')

Wenn Sie in Ihrem DEBUG settings.py auf True gesetzt haben (vermutlich so in der Testumgebung), dann können Sie Abfragen in Ihrem Test ausgeführt zählen wie folgt:

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)

In der modernen Django (> = 1.8) es ist gut dokumentiert (es ist auch für 1.7 dokumentiert) hier , haben Sie die Methode reset_queries statt Zuweisung connection.queries = [] , die in der Tat einen Fehler erzieht, dass so etwas funktioniert auf 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()

Sie können sich auch Abfragen auf Setup / Teardown Zurücksetzen Abfragen für jeden Test zurückgesetzt, um sicherzustellen, anstatt es zu tun auf finally, aber auf diese Weise ist expliziter (obwohl ausführlicher), oder Sie können verwenden reset_queries in der try-Klausel so oft wie Sie Abfragen müssen auswerten von 0 zu zählen.

Wenn Sie nicht verwenden wollen Testcase (mit assertNumQueries ) oder Einstellungen ändern DEBUG = True, können Sie Kontextmanager CaptureQueriesContext (das gleiche wie assertNumQueries verwenden).

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

db Einstellungen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top