diff --git a/django/test/utils.py b/django/test/utils.py index 6a38412f01..bf849ae0d1 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -601,6 +601,9 @@ class CaptureQueriesContext: def __enter__(self): self.force_debug_cursor = self.connection.force_debug_cursor self.connection.force_debug_cursor = True + # Run any initialization queries if needed so that they won't be + # included as part of the count. + self.connection.ensure_connection() self.initial_queries = len(self.connection.queries_log) self.final_queries = None request_started.disconnect(reset_queries) diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index f029153708..e891cb4614 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -334,6 +334,11 @@ Miscellaneous * The ``FIRST_DAY_OF_WEEK`` and ``NUMBER_GROUPING`` format settings are now kept as integers in JavaScript and JSON i18n view outputs. +* :meth:`~django.test.TransactionTestCase.assertNumQueries` now ignores + connection configuration queries. Previously, if a test opened a new database + connection, those queries could be included as part of the + ``assertNumQueries()`` count. + .. _deprecated-features-2.0: Features deprecated in 2.0 diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py index 6d6e1e5328..69a6a72196 100644 --- a/tests/test_utils/tests.py +++ b/tests/test_utils/tests.py @@ -14,7 +14,8 @@ from django.forms import EmailField, IntegerField from django.http import HttpResponse from django.template.loader import render_to_string from django.test import ( - SimpleTestCase, TestCase, skipIfDBFeature, skipUnlessDBFeature, + SimpleTestCase, TestCase, TransactionTestCase, skipIfDBFeature, + skipUnlessDBFeature, ) from django.test.html import HTMLParseError, parse_html from django.test.utils import ( @@ -157,6 +158,32 @@ class AssertNumQueriesTests(TestCase): self.assertNumQueries(2, test_func) +@unittest.skipUnless( + connection.vendor != 'sqlite' or not connection.is_in_memory_db(), + 'For SQLite in-memory tests, closing the connection destroys the database.' +) +class AssertNumQueriesUponConnectionTests(TransactionTestCase): + available_apps = [] + + def test_ignores_connection_configuration_queries(self): + real_ensure_connection = connection.ensure_connection + connection.close() + + def make_configuration_query(): + is_opening_connection = connection.connection is None + real_ensure_connection() + + if is_opening_connection: + # Avoid infinite recursion. Creating a cursor calls + # ensure_connection() which is currently mocked by this method. + connection.cursor().execute('SELECT 1' + connection.features.bare_select_suffix) + + ensure_connection = 'django.db.backends.base.base.BaseDatabaseWrapper.ensure_connection' + with mock.patch(ensure_connection, side_effect=make_configuration_query): + with self.assertNumQueries(1): + list(Car.objects.all()) + + class AssertQuerysetEqualTests(TestCase): def setUp(self): self.p1 = Person.objects.create(name='p1')