diff --git a/docs/helpers.rst b/docs/helpers.rst index 1203c3a08..42147c0af 100644 --- a/docs/helpers.rst +++ b/docs/helpers.rst @@ -135,6 +135,28 @@ Example response = my_view(request) assert response.status_code == 200 +.. fixture:: async_rf + +``async_rf`` - ``AsyncRequestFactory`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An instance of a `django.test.AsyncRequestFactory` + +.. _django.test.AsyncRequestFactory: https://docs.djangoproject.com/en/3.1/topics/testing/advanced/#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`` @@ -168,6 +190,25 @@ 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`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +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' + .. fixture:: admin_client ``admin_client`` - ``django.test.Client`` logged in as admin @@ -235,7 +276,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..d9f891a14 100644 --- a/pytest_django/fixtures.py +++ b/pytest_django/fixtures.py @@ -20,8 +20,10 @@ "django_user_model", "django_username_field", "client", + "async_client", "admin_client", "rf", + "async_rf", "settings", "live_server", "_live_server_helper", @@ -261,6 +263,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.""" @@ -322,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 701e317a1..41498b2c2 100644 --- a/pytest_django/plugin.py +++ b/pytest_django/plugin.py @@ -28,12 +28,14 @@ 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 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 602d90fcd..e837b9b47 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 @@ -36,6 +37,13 @@ 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) @@ -73,6 +81,13 @@ 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) + + @pytest.mark.django_db def test_django_assert_num_queries_db(request, django_assert_num_queries): with nonverbose_config(request.config):