From 8ed3ecb328f0ef1a8beaf24cc09213524f0656e7 Mon Sep 17 00:00:00 2001 From: Petr Belskiy Date: Wed, 26 Aug 2020 22:03:21 +0300 Subject: [PATCH 1/5] add async client fixture --- docs/helpers.rst | 20 ++++++++++++++++++-- pytest_django/fixtures.py | 11 +++++++++++ pytest_django/plugin.py | 1 + tests/test_fixtures.py | 9 +++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/docs/helpers.rst b/docs/helpers.rst index 1203c3a08..234aaeb38 100644 --- a/docs/helpers.rst +++ b/docs/helpers.rst @@ -168,7 +168,23 @@ To use `client` as an authenticated standard user, call its response = client.get('/private') assert response.content == 'Protected Area' -.. fixture:: admin_client +``async_client`` - ``django.test.AsyncClient`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An instance of a `django.test.AsyncClient`_ + +.. _django.test.AsyncClient: https://docs.djangoproject.com/en/stable/topics/testing/tools/#the-test-client + +Example +""""""" + +:: + + @pytest.mark.asyncio + async def test_with_async_client(async_client): + response = await async_client.get('/') + assert response.content == 'Foobar' + ``admin_client`` - ``django.test.Client`` logged in as admin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -235,7 +251,7 @@ This fixture will ensure the Django database is set up. Only required for fixtures that want to use the database themselves. A test function should normally use the :func:`pytest.mark.django_db` mark to signal it needs the database. This fixture does -not return a database connection object. When you need a Django +not return a database connection object. When you need a Django database connection or cursor, import it from Django using ``from django.db import connection``. diff --git a/pytest_django/fixtures.py b/pytest_django/fixtures.py index 1dd4d0457..2e1a4db70 100644 --- a/pytest_django/fixtures.py +++ b/pytest_django/fixtures.py @@ -20,6 +20,7 @@ "django_user_model", "django_username_field", "client", + "async_client", "admin_client", "rf", "settings", @@ -261,6 +262,16 @@ def client(): return Client() +@pytest.fixture() +def async_client(): + """A Django test async client instance.""" + skip_if_no_django() + + from django.test.client import AsyncClient + + return AsyncClient() + + @pytest.fixture() def django_user_model(db): """The class of Django's user model.""" diff --git a/pytest_django/plugin.py b/pytest_django/plugin.py index 701e317a1..72d4efcc2 100644 --- a/pytest_django/plugin.py +++ b/pytest_django/plugin.py @@ -28,6 +28,7 @@ from .fixtures import _live_server_helper # noqa from .fixtures import admin_client # noqa from .fixtures import admin_user # noqa +from .fixtures import async_client # noqa from .fixtures import client # noqa from .fixtures import db # noqa from .fixtures import django_user_model # noqa diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py index 602d90fcd..04350dfc9 100644 --- a/tests/test_fixtures.py +++ b/tests/test_fixtures.py @@ -36,6 +36,15 @@ def test_client(client): assert isinstance(client, Client) +@pytest.mark.skipif( + get_django_version() < (3, 1), reason="Django >= 3.1 required" +) +def test_async_client(async_client): + from django.test.client import AsyncClient + + assert isinstance(async_client, AsyncClient) + + @pytest.mark.django_db def test_admin_client(admin_client): assert isinstance(admin_client, Client) From fb13dbd3a89d6f79b09b9db054219305a52a85e4 Mon Sep 17 00:00:00 2001 From: Petr Belskiy Date: Sat, 17 Oct 2020 18:50:40 +0300 Subject: [PATCH 2/5] import get_django_version --- tests/test_fixtures.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py index 04350dfc9..25b440c00 100644 --- a/tests/test_fixtures.py +++ b/tests/test_fixtures.py @@ -18,6 +18,7 @@ from django.utils.encoding import force_str from pytest_django_test.app.models import Item +from pytest_django.lazy_django import get_django_version @contextmanager From f2b23e629b633954b5cf7071a107a42586be3816 Mon Sep 17 00:00:00 2001 From: Petr Belskiy Date: Sat, 17 Oct 2020 23:35:30 +0300 Subject: [PATCH 3/5] fix docs --- docs/helpers.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/helpers.rst b/docs/helpers.rst index 234aaeb38..90a927577 100644 --- a/docs/helpers.rst +++ b/docs/helpers.rst @@ -168,6 +168,8 @@ To use `client` as an authenticated standard user, call its response = client.get('/private') assert response.content == 'Protected Area' +.. fixture:: async_client + ``async_client`` - ``django.test.AsyncClient`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -185,6 +187,7 @@ Example response = await async_client.get('/') assert response.content == 'Foobar' +.. fixture:: admin_client ``admin_client`` - ``django.test.Client`` logged in as admin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 5764a12aa77fc6a64b4c4c7554a3bcfdae32a156 Mon Sep 17 00:00:00 2001 From: Petr Belskiy Date: Sat, 17 Oct 2020 23:57:15 +0300 Subject: [PATCH 4/5] add async_rf fixture --- docs/helpers.rst | 20 ++++++++++++++++++++ pytest_django/fixtures.py | 11 +++++++++++ pytest_django/plugin.py | 1 + tests/test_fixtures.py | 6 +++++- 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/docs/helpers.rst b/docs/helpers.rst index 90a927577..c4135f5c0 100644 --- a/docs/helpers.rst +++ b/docs/helpers.rst @@ -135,6 +135,26 @@ Example response = my_view(request) assert response.status_code == 200 +.. fixture:: async_rf + +``async_rf`` - ``AsyncRequestFactory`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An instance of a :class:`django.test.AsyncRequestFactory`. + +Example +""""""" + +:: + + from myapp.views import my_view + + @pytest.mark.asyncio + async def test_details(async_rf): + request = await async_rf.get('/customer/details') + response = my_view(request) + assert response.status_code == 200 + .. fixture:: client ``client`` - ``django.test.Client`` diff --git a/pytest_django/fixtures.py b/pytest_django/fixtures.py index 2e1a4db70..d9f891a14 100644 --- a/pytest_django/fixtures.py +++ b/pytest_django/fixtures.py @@ -23,6 +23,7 @@ "async_client", "admin_client", "rf", + "async_rf", "settings", "live_server", "_live_server_helper", @@ -333,6 +334,16 @@ def rf(): return RequestFactory() +@pytest.fixture() +def async_rf(): + """AsyncRequestFactory instance""" + skip_if_no_django() + + from django.test.client import AsyncRequestFactory + + return AsyncRequestFactory() + + class SettingsWrapper: _to_restore = [] diff --git a/pytest_django/plugin.py b/pytest_django/plugin.py index 72d4efcc2..41498b2c2 100644 --- a/pytest_django/plugin.py +++ b/pytest_django/plugin.py @@ -35,6 +35,7 @@ from .fixtures import django_username_field # noqa from .fixtures import live_server # noqa from .fixtures import django_db_reset_sequences # noqa +from .fixtures import async_rf # noqa from .fixtures import rf # noqa from .fixtures import settings # noqa from .fixtures import transactional_db # noqa diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py index 25b440c00..f39bda34b 100644 --- a/tests/test_fixtures.py +++ b/tests/test_fixtures.py @@ -13,7 +13,7 @@ from django.conf import settings as real_settings from django.core import mail from django.db import connection, transaction -from django.test.client import Client, RequestFactory +from django.test.client import Client, AsyncRequestFactory, RequestFactory from django.test.testcases import connections_support_transactions from django.utils.encoding import force_str @@ -83,6 +83,10 @@ def test_rf(rf): assert isinstance(rf, RequestFactory) +def test_async_rf(async_rf): + assert isinstance(async_rf, AsyncRequestFactory) + + @pytest.mark.django_db def test_django_assert_num_queries_db(request, django_assert_num_queries): with nonverbose_config(request.config): From d8e7a14a264023b21537c86ae3f20682b9b6d21c Mon Sep 17 00:00:00 2001 From: Petr Belskiy Date: Sun, 18 Oct 2020 00:24:47 +0300 Subject: [PATCH 5/5] add version checking for async_rf --- docs/helpers.rst | 8 +++++--- tests/test_fixtures.py | 9 +++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/helpers.rst b/docs/helpers.rst index c4135f5c0..42147c0af 100644 --- a/docs/helpers.rst +++ b/docs/helpers.rst @@ -138,9 +138,11 @@ Example .. fixture:: async_rf ``async_rf`` - ``AsyncRequestFactory`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An instance of a `django.test.AsyncRequestFactory` -An instance of a :class:`django.test.AsyncRequestFactory`. +.. _django.test.AsyncRequestFactory: https://docs.djangoproject.com/en/3.1/topics/testing/advanced/#asyncrequestfactory Example """"""" @@ -193,7 +195,7 @@ To use `client` as an authenticated standard user, call its ``async_client`` - ``django.test.AsyncClient`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -An instance of a `django.test.AsyncClient`_ +An instance of a `django.test.AsyncClient` .. _django.test.AsyncClient: https://docs.djangoproject.com/en/stable/topics/testing/tools/#the-test-client diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py index f39bda34b..e837b9b47 100644 --- a/tests/test_fixtures.py +++ b/tests/test_fixtures.py @@ -13,7 +13,7 @@ from django.conf import settings as real_settings from django.core import mail from django.db import connection, transaction -from django.test.client import Client, AsyncRequestFactory, RequestFactory +from django.test.client import Client, RequestFactory from django.test.testcases import connections_support_transactions from django.utils.encoding import force_str @@ -37,9 +37,7 @@ def test_client(client): assert isinstance(client, Client) -@pytest.mark.skipif( - get_django_version() < (3, 1), reason="Django >= 3.1 required" -) +@pytest.mark.skipif(get_django_version() < (3, 1), reason="Django >= 3.1 required") def test_async_client(async_client): from django.test.client import AsyncClient @@ -83,7 +81,10 @@ def test_rf(rf): assert isinstance(rf, RequestFactory) +@pytest.mark.skipif(get_django_version() < (3, 1), reason="Django >= 3.1 required") def test_async_rf(async_rf): + from django.test.client import AsyncRequestFactory + assert isinstance(async_rf, AsyncRequestFactory)