Skip to content

Commit bf9c965

Browse files
Expose available_apps in django_db marker (#1071)
1 parent f68f888 commit bf9c965

File tree

4 files changed

+62
-8
lines changed

4 files changed

+62
-8
lines changed

docs/helpers.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,22 @@ dynamically in a hook or fixture.
8484

8585
Note that this will slow down that test suite by approximately 3x.
8686

87+
:type available_apps: Union[List[str], None]
88+
:param available_apps:
89+
.. caution::
90+
91+
This argument is **experimental** and is subject to change without
92+
deprecation.
93+
94+
The ``available_apps`` argument defines a subset of apps that are enabled
95+
for a specific set of tests. Setting ``available_apps`` configures models
96+
for which types/permissions will be created before each test, and which
97+
model tables will be emptied after each test (this truncation may cascade
98+
to unavailable apps models).
99+
100+
For details see :py:attr:`django.test.TransactionTestCase.available_apps`
101+
102+
87103
.. note::
88104

89105
If you want access to the Django database inside a *fixture*, this marker may

pytest_django/fixtures.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@
1818
import django
1919

2020
_DjangoDbDatabases = Optional[Union["Literal['__all__']", Iterable[str]]]
21-
# transaction, reset_sequences, databases, serialized_rollback
22-
_DjangoDb = Tuple[bool, bool, _DjangoDbDatabases, bool]
21+
_DjangoDbAvailableApps = Optional[List[str]]
22+
# transaction, reset_sequences, databases, serialized_rollback, available_apps
23+
_DjangoDb = Tuple[bool, bool, _DjangoDbDatabases, bool, _DjangoDbAvailableApps]
2324

2425

2526
__all__ = [
@@ -156,14 +157,16 @@ def _django_db_helper(
156157
reset_sequences,
157158
databases,
158159
serialized_rollback,
160+
available_apps,
159161
) = validate_django_db(marker)
160162
else:
161163
(
162164
transactional,
163165
reset_sequences,
164166
databases,
165167
serialized_rollback,
166-
) = False, False, None, False
168+
available_apps,
169+
) = False, False, None, False, None
167170

168171
transactional = transactional or reset_sequences or (
169172
"transactional_db" in request.fixturenames
@@ -190,12 +193,15 @@ def _django_db_helper(
190193
_reset_sequences = reset_sequences
191194
_serialized_rollback = serialized_rollback
192195
_databases = databases
196+
_available_apps = available_apps
193197

194198
class PytestDjangoTestCase(test_case_class): # type: ignore[misc,valid-type]
195199
reset_sequences = _reset_sequences
196200
serialized_rollback = _serialized_rollback
197201
if _databases is not None:
198202
databases = _databases
203+
if _available_apps is not None:
204+
available_apps = _available_apps
199205

200206
# For non-transactional tests, skip executing `django.test.TestCase`'s
201207
# `setUpClass`/`tearDownClass`, only execute the super class ones.
@@ -237,20 +243,22 @@ def validate_django_db(marker) -> "_DjangoDb":
237243
"""Validate the django_db marker.
238244
239245
It checks the signature and creates the ``transaction``,
240-
``reset_sequences``, ``databases`` and ``serialized_rollback`` attributes on
241-
the marker which will have the correct values.
246+
``reset_sequences``, ``databases``, ``serialized_rollback`` and
247+
``available_apps`` attributes on the marker which will have the correct
248+
values.
242249
243-
Sequence reset and serialized_rollback are only allowed when combined with
244-
transaction.
250+
Sequence reset, serialized_rollback, and available_apps are only allowed
251+
when combined with transaction.
245252
"""
246253

247254
def apifun(
248255
transaction: bool = False,
249256
reset_sequences: bool = False,
250257
databases: "_DjangoDbDatabases" = None,
251258
serialized_rollback: bool = False,
259+
available_apps: "_DjangoDbAvailableApps" = None,
252260
) -> "_DjangoDb":
253-
return transaction, reset_sequences, databases, serialized_rollback
261+
return transaction, reset_sequences, databases, serialized_rollback, available_apps
254262

255263
return apifun(*marker.args, **marker.kwargs)
256264

pytest_django/plugin.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ def get_order_number(test: pytest.Item) -> int:
389389
reset_sequences,
390390
databases,
391391
serialized_rollback,
392+
available_apps,
392393
) = validate_django_db(marker_db)
393394
uses_db = True
394395
transactional = transaction or reset_sequences

tests/test_database.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,35 @@ def test_serialized_rollback_enabled(self, request):
348348
marker = request.node.get_closest_marker("django_db")
349349
assert marker.kwargs["serialized_rollback"]
350350

351+
@pytest.mark.django_db
352+
def test_available_apps_disabled(self, request) -> None:
353+
marker = request.node.get_closest_marker("django_db")
354+
assert not marker.kwargs
355+
356+
@pytest.mark.django_db(available_apps=['pytest_django_test.app'])
357+
def test_available_apps_enabled(self, request) -> None:
358+
marker = request.node.get_closest_marker("django_db")
359+
assert marker.kwargs["available_apps"] == ['pytest_django_test.app']
360+
361+
@pytest.mark.django_db
362+
def test_available_apps_default(self, request) -> None:
363+
from django.apps import apps
364+
from django.conf import settings
365+
366+
for app in settings.INSTALLED_APPS:
367+
assert apps.is_installed(app)
368+
369+
@pytest.mark.django_db(available_apps=['pytest_django_test.app'])
370+
def test_available_apps_limited(self, request) -> None:
371+
from django.apps import apps
372+
from django.conf import settings
373+
374+
assert apps.is_installed("pytest_django_test.app")
375+
376+
for app in settings.INSTALLED_APPS:
377+
if app != "pytest_django_test.app":
378+
assert not apps.is_installed(app)
379+
351380

352381
def test_unittest_interaction(django_testdir) -> None:
353382
"Test that (non-Django) unittests cannot access the DB."

0 commit comments

Comments
 (0)