Question

Je suis en train de connaître le nombre de requêtes exécutées par une fonction d'utilité. Je l'ai écrit un test unitaire pour cette fonction et la fonction fonctionne bien. Ce que je voudrais faire est de suivre le nombre de requêtes SQL exécutées par la fonction pour que je puisse voir s'il y a une amélioration après quelques refactoring.

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: Je trouve qu'il ya un Django en attente demande de fonctionnalité pour cela. Cependant, le billet est toujours ouvert. En attendant, il est une autre façon d'aller à ce sujet?

Était-ce utile?

La solution

Depuis Django 1.3 il y a une assertNumQueries disponible exactement à cet effet.

Autres conseils

La réponse de Vinay est correcte, avec une addition mineure.

Le cadre de test unitaire de Django définit en fait DEBUG sur False quand il court, donc peu importe ce que vous avez à settings.py, vous n'aurez rien peuplé connection.queries dans votre test unitaire à moins que vous réactivez le mode de débogage. Les documents expliquent Django pour cette comme:

  

Quelle que soit la valeur du paramètre DEBUG dans votre fichier de configuration, tous les Django tests obtenus avec DEBUG = False. Est de faire en sorte que la sortie observée de votre code correspond à ce qui sera vu dans un contexte de production.

Si vous êtes certain que l'activation de débogage n'affectera pas vos tests (par exemple si vous testez spécifiquement touche DB, comme il semble que vous êtes), la solution est de debug réactiver temporairement dans votre test unitaire, il reculer après:

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

Si vous avez DEBUG défini sur True dans votre settings.py (probablement si dans votre environnement de test), vous pouvez compter les requêtes exécutées dans votre test comme suit:

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)

Dans Django moderne (> = 1.8), il est bien documenté (il est également documenté 1,7) ici , vous avez la méthode reset_queries au lieu d'attribuer connection.queries = [] qui est en effet soulevé une erreur, quelque chose comme ça fonctionne sur 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()

Vous pouvez également envisager la réinitialisation des requêtes sur setUp / tearDown pour assurer les requêtes sont remis à zéro pour chaque test au lieu de le faire sur finally, mais cette manière est plus explicite (bien plus bavard), ou vous pouvez utiliser reset_queries dans la clause essayer autant de fois que vous avez besoin d'évaluer les requêtes à compter de 0.

Si vous ne voulez pas utiliser TestCase (avec assertNumQueries ) ou modifier les réglages à DEBUG = True, vous pouvez utiliser le gestionnaire de contexte CaptureQueriesContext (comme assertNumQueries utilisant).

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

paramètres db

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top