A Django plugin for pytest that provides Django-specific testing fixtures, marks, and assertions.
—
Django test client and request factory fixtures for HTTP testing, view testing, and API testing. These fixtures provide access to Django's test client for making HTTP requests and testing views.
Standard Django test client for making HTTP requests in tests.
def client() -> django.test.Client:
"""
Django test client for HTTP requests and view testing.
Provides a test client that can make GET, POST, PUT, DELETE, and other
HTTP requests to your Django views. Automatically handles CSRF tokens,
sessions, and authentication state.
Returns:
django.test.Client: Configured test client instance
"""Usage example:
def test_view_response(client):
# GET request
response = client.get("/my-view/")
assert response.status_code == 200
assert b"Hello World" in response.content
# POST request with data
response = client.post("/submit/", {"name": "test", "email": "test@example.com"})
assert response.status_code == 302
# JSON POST request
import json
response = client.post(
"/api/data/",
json.dumps({"key": "value"}),
content_type="application/json"
)
assert response.status_code == 201Async version of Django test client for testing async views and ASGI applications.
def async_client() -> django.test.AsyncClient:
"""
Django async test client for async view testing.
Async version of Django's test client for testing async views,
ASGI applications, and async middleware. Supports all HTTP methods
with async/await syntax.
Returns:
django.test.AsyncClient: Configured async test client instance
"""Usage example:
import pytest
@pytest.mark.asyncio
async def test_async_view(async_client):
# Async GET request
response = await async_client.get("/async-view/")
assert response.status_code == 200
# Async POST request
response = await async_client.post("/async-submit/", {"data": "test"})
assert response.status_code == 302Django request factory for creating request objects for direct view testing.
def rf() -> django.test.RequestFactory:
"""
Django request factory for creating request objects.
Creates request objects that can be passed directly to view functions
for unit testing. Unlike the test client, this doesn't run middleware
or URL resolution - it creates raw HttpRequest objects.
Returns:
django.test.RequestFactory: Request factory instance
"""Usage example:
def test_view_directly(rf):
from myapp.views import my_view
# Create GET request
request = rf.get("/fake-path/")
response = my_view(request)
assert response.status_code == 200
# Create POST request with data
request = rf.post("/fake-path/", {"name": "test"})
request.user = user_instance # Manually set user if needed
response = my_view(request)
assert response.status_code == 302Async version of Django request factory for testing async views directly.
def async_rf() -> django.test.AsyncRequestFactory:
"""
Django async request factory for creating async request objects.
Creates async request objects for directly testing async view functions
without running through ASGI middleware stack. Useful for unit testing
async views in isolation.
Returns:
django.test.AsyncRequestFactory: Async request factory instance
"""Usage example:
import pytest
@pytest.mark.asyncio
async def test_async_view_directly(async_rf):
from myapp.views import my_async_view
# Create async GET request
request = async_rf.get("/fake-path/")
response = await my_async_view(request)
assert response.status_code == 200
# Create async POST request
request = async_rf.post("/fake-path/", {"data": "test"})
response = await my_async_view(request)
assert response.status_code == 201from django.test import Client, AsyncClient, RequestFactory, AsyncRequestFactory
from django.http import HttpRequest, HttpResponse
from typing import Dict, Any, Optional, Union
# HTTP method types
HttpMethodData = Dict[str, Any]
ContentType = str
StatusCode = int
# Response types from Django
from django.http import (
HttpResponse,
HttpResponseRedirect,
HttpResponsePermanentRedirect,
JsonResponse,
StreamingHttpResponse,
FileResponse
)
# Request object types
class HttpRequest:
"""Django HTTP request object."""
method: str
path: str
GET: Dict[str, str]
POST: Dict[str, str]
FILES: Dict[str, Any]
COOKIES: Dict[str, str]
META: Dict[str, str]
user: Any
session: Dict[str, Any]
# Test client method signatures
class Client:
def get(self, path: str, data: Optional[HttpMethodData] = None, **extra) -> HttpResponse: ...
def post(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpResponse: ...
def put(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpResponse: ...
def patch(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpResponse: ...
def delete(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpResponse: ...
def head(self, path: str, data: Optional[HttpMethodData] = None, **extra) -> HttpResponse: ...
def options(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpResponse: ...
def trace(self, path: str, **extra) -> HttpResponse: ...
def login(self, **credentials) -> bool: ...
def logout(self) -> None: ...
def force_login(self, user, backend: Optional[str] = None) -> None: ...
class AsyncClient:
async def get(self, path: str, data: Optional[HttpMethodData] = None, **extra) -> HttpResponse: ...
async def post(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpResponse: ...
async def put(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpResponse: ...
async def patch(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpResponse: ...
async def delete(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpResponse: ...
async def head(self, path: str, data: Optional[HttpMethodData] = None, **extra) -> HttpResponse: ...
async def options(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpResponse: ...
async def trace(self, path: str, **extra) -> HttpResponse: ...
async def login(self, **credentials) -> bool: ...
async def logout(self) -> None: ...
async def force_login(self, user, backend: Optional[str] = None) -> None: ...
class RequestFactory:
def get(self, path: str, data: Optional[HttpMethodData] = None, **extra) -> HttpRequest: ...
def post(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpRequest: ...
def put(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpRequest: ...
def patch(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpRequest: ...
def delete(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpRequest: ...
def head(self, path: str, data: Optional[HttpMethodData] = None, **extra) -> HttpRequest: ...
def options(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpRequest: ...
def trace(self, path: str, **extra) -> HttpRequest: ...
class AsyncRequestFactory:
def get(self, path: str, data: Optional[HttpMethodData] = None, **extra) -> HttpRequest: ...
def post(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpRequest: ...
def put(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpRequest: ...
def patch(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpRequest: ...
def delete(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpRequest: ...
def head(self, path: str, data: Optional[HttpMethodData] = None, **extra) -> HttpRequest: ...
def options(self, path: str, data: Optional[HttpMethodData] = None, content_type: Optional[ContentType] = None, **extra) -> HttpRequest: ...
def trace(self, path: str, **extra) -> HttpRequest: ...Install with Tessl CLI
npx tessl i tessl/pypi-pytest-django