From 92c0caa3fa81db56905c39e752a786c3b7e6eda4 Mon Sep 17 00:00:00 2001 From: Manolis Stamatogiannakis Date: Fri, 8 Nov 2024 15:28:03 +0100 Subject: [PATCH] fixtures: provide per-scope fixtures for unblocking database access Allow the convenience of `db` fixture for all fixture scopes. --- pytest_django/fixtures.py | 71 +++++++++++++++++++++++++++++++-------- pytest_django/plugin.py | 8 +++++ 2 files changed, 65 insertions(+), 14 deletions(-) diff --git a/pytest_django/fixtures.py b/pytest_django/fixtures.py index 8c4cad94..13a7c7c4 100644 --- a/pytest_django/fixtures.py +++ b/pytest_django/fixtures.py @@ -43,6 +43,10 @@ __all__ = [ "django_db_setup", "db", + "db_class", + "db_module", + "db_package", + "db_session", "transactional_db", "django_db_reset_sequences", "django_db_serialized_rollback", @@ -159,8 +163,7 @@ def django_db_setup( ) -@pytest.fixture() -def _django_db_helper( +def _base_django_db_helper( request: pytest.FixtureRequest, django_db_setup: None, django_db_blocker: DjangoDbBlocker, @@ -256,6 +259,14 @@ def tearDownClass(cls) -> None: PytestDjangoTestCase.doClassCleanups() +# Per-scope db helpers. +_django_db_helper = pytest.fixture(_base_django_db_helper, scope="function") +_django_db_helper_class = pytest.fixture(_base_django_db_helper, scope="class") +_django_db_helper_module = pytest.fixture(_base_django_db_helper, scope="module") +_django_db_helper_package = pytest.fixture(_base_django_db_helper, scope="package") +_django_db_helper_session = pytest.fixture(_base_django_db_helper, scope="session") + + def validate_django_db(marker: pytest.Mark) -> _DjangoDb: """Validate the django_db marker. @@ -320,23 +331,55 @@ def _set_suffix_to_test_databases(suffix: str) -> None: # ############### User visible fixtures ################ - - @pytest.fixture() def db(_django_db_helper: None) -> None: - """Require a django test database. + # The `_django_db_helper` fixture checks if `db` is requested. + pass # pragma: no cover - This database will be setup with the default fixtures and will have - the transaction management disabled. At the end of the test the outer - transaction that wraps the test itself will be rolled back to undo any - changes to the database (in case the backend supports transactions). - This is more limited than the ``transactional_db`` fixture but - faster. - If both ``db`` and ``transactional_db`` are requested, - ``transactional_db`` takes precedence. - """ +@pytest.fixture(scope="class") +def db_class(_django_db_helper_class: None) -> None: + # The `_django_db_helper` fixture checks if `db` is requested. + pass # pragma: no cover + + +@pytest.fixture(scope="module") +def db_module(_django_db_helper_module: None) -> None: + # The `_django_db_helper` fixture checks if `db` is requested. + pass # pragma: no cover + + +@pytest.fixture(scope="package") +def db_package(_django_db_helper_package: None) -> None: + # The `_django_db_helper` fixture checks if `db` is requested. + pass # pragma: no cover + + +@pytest.fixture(scope="session") +def db_session(_django_db_helper_session: None) -> None: # The `_django_db_helper` fixture checks if `db` is requested. + pass # pragma: no cover + + +# Dynamically add help text to scoped db fixtures. +_db_fixture_help = """Require a django test database for use by tests +and {}-scoped fixtures. + +This database will be setup with the default fixtures and will have +the transaction management disabled. At the end of the test the outer +transaction that wraps the test itself will be rolled back to undo any +changes to the database (in case the backend supports transactions). +This is more limited than the ``transactional_db`` fixture but +faster. + +If both ``db`` and ``transactional_db`` are requested, +``transactional_db`` takes precedence. +""" +db.__doc__ = _db_fixture_help.format("function") +db_class.__doc__ = _db_fixture_help.format("class") +db_module.__doc__ = _db_fixture_help.format("module") +db_package.__doc__ = _db_fixture_help.format("package") +db_session.__doc__ = _db_fixture_help.format("session") @pytest.fixture() diff --git a/pytest_django/plugin.py b/pytest_django/plugin.py index 285f1733..d52327aa 100644 --- a/pytest_django/plugin.py +++ b/pytest_django/plugin.py @@ -20,6 +20,10 @@ from .django_compat import is_django_unittest from .fixtures import ( _django_db_helper, # noqa: F401 + _django_db_helper_class, # noqa: F401 + _django_db_helper_module, # noqa: F401 + _django_db_helper_package, # noqa: F401 + _django_db_helper_session, # noqa: F401 _live_server_helper, # noqa: F401 admin_client, # noqa: F401 admin_user, # noqa: F401 @@ -27,6 +31,10 @@ async_rf, # noqa: F401 client, # noqa: F401 db, # noqa: F401 + db_class, # noqa: F401 + db_module, # noqa: F401 + db_package, # noqa: F401 + db_session, # noqa: F401 django_assert_max_num_queries, # noqa: F401 django_assert_num_queries, # noqa: F401 django_capture_on_commit_callbacks, # noqa: F401