Skip to content

Commit 2bf9f3b

Browse files
committed
Add fixture for asserting maximum number of database queries
1 parent 94cccb9 commit 2bf9f3b

File tree

4 files changed

+48
-33
lines changed

4 files changed

+48
-33
lines changed

docs/helpers.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ Example
220220
assert settings.USE_TZ
221221

222222

223-
``django_assert_num_queries``
223+
``django_assert_exact_num_queries``
224224
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
225225

226226
This fixture allows to check for an expected number of DB queries.
@@ -232,8 +232,8 @@ Example
232232

233233
::
234234

235-
def test_queries(django_assert_num_queries):
236-
with django_assert_num_queries(3):
235+
def test_queries(django_assert_exact_num_queries):
236+
with django_assert_exact_num_queries(3):
237237
Item.objects.create('foo')
238238
Item.objects.create('bar')
239239
Item.objects.create('baz')

pytest_django/fixtures.py

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from __future__ import with_statement
44

55
import os
6+
from functools import partial
67

78
import pytest
89

@@ -18,7 +19,8 @@
1819
__all__ = ['django_db_setup', 'db', 'transactional_db', 'admin_user',
1920
'django_user_model', 'django_username_field',
2021
'client', 'admin_client', 'rf', 'settings', 'live_server',
21-
'_live_server_helper', 'django_assert_num_queries']
22+
'_live_server_helper', 'django_assert_exact_num_queries',
23+
'django_assert_max_num_queries']
2224

2325

2426
@pytest.fixture(scope='session')
@@ -336,22 +338,33 @@ def _live_server_helper(request):
336338
getfixturevalue(request, 'transactional_db')
337339

338340

339-
@pytest.fixture(scope='function')
340-
def django_assert_num_queries(pytestconfig):
341+
@contextmanager
342+
def _assert_num_queries(config, num, exact=True):
341343
from django.db import connection
342344
from django.test.utils import CaptureQueriesContext
345+
verbose = config.getoption('verbose') > 0
346+
with CaptureQueriesContext(connection) as context:
347+
yield
348+
failed = num != len(context) if exact else num < len(context)
349+
if failed:
350+
msg = "Expected to perform {} queries {}{}".format(
351+
num,
352+
'' if exact else 'or less ',
353+
'but {} were done'.format(len(context))
354+
)
355+
if verbose:
356+
sqls = (q['sql'] for q in context.captured_queries)
357+
msg += '\n\nQueries:\n========\n\n%s' % '\n\n'.join(sqls)
358+
else:
359+
msg += " (add -v option to show queries)"
360+
pytest.fail(msg)
361+
343362

344-
@contextmanager
345-
def _assert_num_queries(num):
346-
with CaptureQueriesContext(connection) as context:
347-
yield
348-
if num != len(context):
349-
msg = "Expected to perform %s queries but %s were done" % (num, len(context))
350-
if pytestconfig.getoption('verbose') > 0:
351-
sqls = (q['sql'] for q in context.captured_queries)
352-
msg += '\n\nQueries:\n========\n\n%s' % '\n\n'.join(sqls)
353-
else:
354-
msg += " (add -v option to show queries)"
355-
pytest.fail(msg)
356-
357-
return _assert_num_queries
363+
@pytest.fixture(scope='function')
364+
def django_assert_exact_num_queries(pytestconfig):
365+
return partial(_assert_num_queries, pytestconfig)
366+
367+
368+
@pytest.fixture(scope='function')
369+
def django_assert_max_num_queries(pytestconfig):
370+
return partial(_assert_num_queries, pytestconfig, exact=False)

pytest_django/plugin.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
import pytest
1616

1717
from .django_compat import is_django_unittest # noqa
18-
from .fixtures import django_assert_num_queries # noqa
18+
from .fixtures import django_assert_exact_num_queries # noqa
19+
from .fixtures import django_assert_max_num_queries # noqa
1920
from .fixtures import django_db_setup # noqa
2021
from .fixtures import django_db_use_migrations # noqa
2122
from .fixtures import django_db_keepdb # noqa

tests/test_fixtures.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,39 +51,40 @@ def test_rf(rf):
5151

5252

5353
@pytest.mark.django_db
54-
def test_django_assert_num_queries_db(django_assert_num_queries):
55-
with django_assert_num_queries(3):
54+
def test_django_assert_exact_num_queries_db(django_assert_exact_num_queries):
55+
with django_assert_exact_num_queries(3):
5656
Item.objects.create(name='foo')
5757
Item.objects.create(name='bar')
5858
Item.objects.create(name='baz')
5959

6060
with pytest.raises(pytest.fail.Exception):
61-
with django_assert_num_queries(2):
61+
with django_assert_exact_num_queries(2):
6262
Item.objects.create(name='quux')
6363

6464

6565
@pytest.mark.django_db(transaction=True)
66-
def test_django_assert_num_queries_transactional_db(transactional_db, django_assert_num_queries):
66+
def test_django_assert_exact_num_queries_transactional_db(
67+
transactional_db, django_assert_exact_num_queries):
6768
with transaction.atomic():
6869

69-
with django_assert_num_queries(3):
70+
with django_assert_exact_num_queries(3):
7071
Item.objects.create(name='foo')
7172
Item.objects.create(name='bar')
7273
Item.objects.create(name='baz')
7374

7475
with pytest.raises(pytest.fail.Exception):
75-
with django_assert_num_queries(2):
76+
with django_assert_exact_num_queries(2):
7677
Item.objects.create(name='quux')
7778

7879

79-
def test_django_assert_num_queries_output(django_testdir):
80+
def test_django_assert_exact_num_queries_output(django_testdir):
8081
django_testdir.create_test_module("""
8182
from django.contrib.contenttypes.models import ContentType
8283
import pytest
8384
8485
@pytest.mark.django_db
85-
def test_queries(django_assert_num_queries):
86-
with django_assert_num_queries(1):
86+
def test_queries(django_assert_exact_num_queries):
87+
with django_assert_exact_num_queries(1):
8788
list(ContentType.objects.all())
8889
ContentType.objects.count()
8990
""")
@@ -92,14 +93,14 @@ def test_queries(django_assert_num_queries):
9293
assert result.ret == 1
9394

9495

95-
def test_django_assert_num_queries_output_verbose(django_testdir):
96+
def test_django_assert_exact_num_queries_output_verbose(django_testdir):
9697
django_testdir.create_test_module("""
9798
from django.contrib.contenttypes.models import ContentType
9899
import pytest
99100
100101
@pytest.mark.django_db
101-
def test_queries(django_assert_num_queries):
102-
with django_assert_num_queries(11):
102+
def test_queries(django_assert_exact_num_queries):
103+
with django_assert_exact_num_queries(11):
103104
list(ContentType.objects.all())
104105
ContentType.objects.count()
105106
""")

0 commit comments

Comments
 (0)