Domanda

Sto cercando di scoprire il numero di query eseguite da una funzione di utilità. Ho scritto un test di unità per questa funzione e la funzione sta lavorando bene. Quello che vorrei fare è tenere traccia del numero di query SQL eseguite dalla funzione in modo che posso vedere se c'è qualche miglioramento dopo un po 'di 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: ho scoperto che c'è un Django caratteristica richiesta attesa per questo. Tuttavia, il biglietto è ancora aperta. Nel frattempo c'è un altro modo per andare su questo?

È stato utile?

Soluzione

Dal Django 1.3 c'è un assertNumQueries disponibili proprio per questo scopo.

Altri suggerimenti

La risposta di Vinay è corretta, con una piccola aggiunta.

framework di unit test di Django in realtà imposta DEBUG su False quando viene eseguito, quindi non importa quello che hai in settings.py, non avrete nulla popolata connection.queries nel vostro unit test a meno che non si ri-abilitare la modalità di debug. La documentazione Django spiegano la per questo come:

  

A prescindere dal valore dell'impostazione DEBUG nel file di configurazione, tutte Django test eseguiti con DEBUG = False. Questo per garantire che l'uscita osservata del codice corrisponde a quello che si vedrà in un ambiente di produzione.

Se si è certi che l'attivazione di debug non influenzerà i test (come ad esempio se si sta testando specificatamente DB colpisce, come suona come siete), la soluzione è temporaneamente riattivare il debug nel vostro unit test, quindi impostare nuovamente in seguito:

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

Se si utilizza pytest, pytest-django ha django_assert_num_queries apparecchio per questo scopo:

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

Se avete DEBUG impostato su True nel settings.py (presumibilmente in modo nell'ambiente di prova), allora si può contare query eseguite nel test come segue:

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 Django moderna (> = 1.8) è ben documentato (è anche documentato per 1.7) qui , avete il metodo di reset_queries invece di assegnare connection.queries = [] , che in effetti sta sollevando un errore, qualcosa di simile che funziona su 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()

Si può anche prendere in considerazione il ripristino query su Setup / tearDown per garantire le query vengono reimpostati per ogni test invece di farlo sulla clausola finally, ma in questo modo è più esplicito (anche se più verbose), oppure è possibile utilizzare reset_queries nella clausola try tutte le volte che è necessario valutare le query contando da 0.

Se non si desidera utilizzare TestCase (con assertNumQueries ) o modificare le impostazioni per DEBUG = true, è possibile utilizzare contesto responsabile CaptureQueriesContext (stesso di assertNumQueries usando).

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 impostazioni

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top