django how to see sql query when running tests?
If you want to print/log all SQL queries from the tests, try subclassing TestCase
like this:
from django.conf import settings
from django.template import Template, Context
import sys
from django.db import connection
from django.test import TestCase
class LoggingTestCase(TestCase):
@staticmethod
def setUpClass():
# The test runner sets DEBUG to False. Set to True to enable SQL logging.
settings.DEBUG = True
super(LoggingTestCase, LoggingTestCase).setUpClass()
@staticmethod
def tearDownClass():
super(LoggingTestCase, LoggingTestCase).tearDownClass()
time = sum([float(q['time']) for q in connection.queries])
t = Template("{{count}} quer{{count|pluralize:\"y,ies\"}} in {{time}} seconds:\n\n{% for sql in sqllog %}[{{forloop.counter}}] {{sql.time}}s: {{sql.sql|safe}}{% if not forloop.last %}\n\n{% endif %}{% endfor %}")
print >> sys.stderr, t.render(Context({'sqllog': connection.queries, 'count': len(connection.queries), 'time': time}))
# Empty the query list between TestCases.
connection.queries = []
Then use LoggingTestCase
instead of TestCase
as the base class in your tests. Just remember to call this tearDownClass
if you override it.
Another option is to use CaptureQueriesContext
(tested with pytest
).
from django.db import connection
from django.test.utils import CaptureQueriesContext
def test_foo():
with CaptureQueriesContext(connection) as ctx:
# code that runs SQL queries
print(ctx.captured_queries)
Sources:
- https://blog.ploetzli.ch/2019/showing-sql-queries-with-pytest-and-django/
- How to force django to print each executed sql query
You can also do the following to get the queries (and then for instance print it or evaluate it in your test).
Actually you shouldn't alter django.conf.settings
nowadays, therefore I use override_settings
.
from django.db import connection, reset_queries
from django.test import override_settings, TransactionTestCase
class TransactionTests(TransactionTestCase):
@override_settings(DEBUG=True)
def test_sql(self):
reset_queries()
try:
# Code that uses the ORM goes here
except Exception as e:
pass
self.assertEqual(connection.queries, [])
TestCase
might also be suitable, see the differences in this answer.
See the Django documentation for details for SQL output.