# pytest-django

A Django plugin for pytest that enables seamless testing of Django applications using the pytest testing framework. It provides Django-specific fixtures for database testing, settings management, client testing, and Django application lifecycle management while maintaining full compatibility with existing unittest-style TestCase classes.

## Package Information

- **Package Name**: pytest-django
- **Package Type**: pypi
- **Language**: Python
- **Installation**: `pip install pytest-django`

## Core Imports

```python
import pytest
from pytest_django import DjangoDbBlocker, DjangoAssertNumQueries, DjangoCaptureOnCommitCallbacks
```

Most functionality is automatically available through pytest plugin system:

```python
# Fixtures are automatically available in tests
def test_example(db, client, settings):
    # db fixture enables database access
    # client fixture provides Django test client
    # settings fixture allows settings modification
    pass
```

## Basic Usage

```python
import pytest

# Enable database access for test
@pytest.mark.django_db
def test_database_operations(db):
    from myapp.models import MyModel
    
    # Create and test model
    obj = MyModel.objects.create(name="test")
    assert obj.name == "test"
    assert MyModel.objects.count() == 1

# Use Django test client
def test_view_response(client):
    response = client.get("/my-view/")
    assert response.status_code == 200

# Modify Django settings temporarily
def test_with_custom_settings(settings):
    settings.DEBUG = True
    settings.SECRET_KEY = "test-key"
    # Settings automatically restored after test

# Test with admin user
def test_admin_functionality(admin_client, admin_user):
    response = admin_client.get("/admin/")
    assert response.status_code == 200
    assert admin_user.is_superuser
```

## Architecture

pytest-django operates as a pytest plugin that bridges Django's testing ecosystem with pytest's fixture system:

- **Plugin Registration**: Automatically registers via entry_points.pytest11
- **Fixture System**: Provides 40+ fixtures for database, client, settings, and user management
- **Mark System**: Custom pytest marks (@pytest.mark.django_db, @pytest.mark.urls, etc.)
- **Database Management**: Handles test database creation, transactions, and cleanup
- **Django Integration**: Manages Django settings, app configuration, and lifecycle

The plugin ensures proper Django setup and teardown while leveraging pytest's powerful features like parametrization, fixtures, and parallel execution.

## Capabilities

### Database Testing Fixtures

Database access control, transaction management, and database setup fixtures for Django testing with pytest.

```python { .api }
def db() -> None: ...
def transactional_db() -> None: ...
def django_db_setup() -> None: ...
def django_db_reset_sequences() -> None: ...
def django_db_serialized_rollback() -> None: ...
```

[Database Testing](./database-testing.md)

### Django Test Client Fixtures

Django test client and request factory fixtures for HTTP testing and view testing.

```python { .api }
def client() -> django.test.Client: ...
def async_client() -> django.test.AsyncClient: ...
def rf() -> django.test.RequestFactory: ...
def async_rf() -> django.test.AsyncRequestFactory: ...
```

[Client Testing](./client-testing.md)

### User Management Fixtures

User creation and authentication fixtures for testing Django user functionality.

```python { .api }
def admin_user(db: None, django_user_model, django_username_field): ...
def admin_client(admin_user) -> django.test.Client: ...
def django_user_model(db: None): ...
def django_username_field(django_user_model) -> str: ...
```

[User Management](./user-management.md)

### Settings Management

Django settings configuration and temporary modification fixtures.

```python { .api }
class SettingsWrapper:
    def __setattr__(self, name: str, value: Any) -> None: ...
    def __getattr__(self, name: str) -> Any: ...
    def __enter__(self) -> SettingsWrapper: ...
    def __exit__(self, exc_type, exc_value, traceback) -> None: ...

def settings() -> SettingsWrapper: ...
```

[Settings Management](./settings-management.md)

### Email Testing

Email testing fixtures for capturing and testing Django email functionality.

```python { .api }
def mailoutbox() -> List[django.core.mail.EmailMessage]: ...
def django_mail_patch_dns() -> None: ...
def django_mail_dnsname() -> str: ...
```

[Email Testing](./email-testing.md)

### Database Query Testing

Fixtures for asserting and controlling database query counts during testing.

```python { .api }
class DjangoAssertNumQueries:
    def __call__(self, num: int) -> ContextManager[None]: ...

def django_assert_num_queries(pytestconfig: pytest.Config) -> DjangoAssertNumQueries: ...
def django_assert_max_num_queries(pytestconfig: pytest.Config) -> DjangoAssertNumQueries: ...
```

[Query Testing](./query-testing.md)

### Live Server Testing

Live server fixtures for integration testing with running Django server.

```python { .api }
def live_server(request: pytest.FixtureRequest): ...
```

[Live Server Testing](./live-server-testing.md)

### Django Assertions

All Django TestCase assertion methods for comprehensive testing capabilities.

```python { .api }
def assertRedirects(response, expected_url, status_code=302, target_status_code=200, **kwargs): ...
def assertContains(response, text, count=None, status_code=200, **kwargs): ...
def assertTemplateUsed(response=None, template_name=None, **kwargs): ...
def assertFormError(form, field, errors, **kwargs): ...
def assertHTMLEqual(html1: str, html2: str, msg=None): ...
def assertJSONEqual(raw: str, expected_data, msg=None): ...
def assertNumQueries(num: int, func=None, *args, using="default", **kwargs): ...
```

[Django Assertions](./django-assertions.md)

### Pytest Marks

Django-specific pytest marks for test configuration and behavior control.

```python { .api }
@pytest.mark.django_db(
    transaction: bool = False,
    reset_sequences: bool = False,
    databases: list[str] | str | None = None,
    serialized_rollback: bool = False,
    available_apps: list[str] | None = None
): ...

@pytest.mark.urls(module: str): ...
@pytest.mark.ignore_template_errors(): ...
```

[Pytest Marks](./pytest-marks.md)

### Transaction Callback Testing

Fixtures for testing Django's on_commit callbacks and transaction behavior.

```python { .api }
class DjangoCaptureOnCommitCallbacks:
    def __call__(self) -> ContextManager[list]: ...

def django_capture_on_commit_callbacks() -> DjangoCaptureOnCommitCallbacks: ...
```

[Transaction Callbacks](./transaction-callbacks.md)

### Django Test Runner

Django test runner integration for using pytest with Django's manage.py test command.

```python { .api }
class TestRunner:
    def __init__(
        self,
        *,
        verbosity: int = 1,
        failfast: bool = False,
        keepdb: bool = False,
        **kwargs
    ) -> None: ...

    @classmethod
    def add_arguments(cls, parser: ArgumentParser) -> None: ...

    def run_tests(self, test_labels: Iterable[str], **kwargs) -> int: ...
```

[Django Utilities](./django-utilities.md)

## Common Types

```python { .api }
from typing import ContextManager, Any, Optional, Union, List, Literal

# Database configuration types
DatabasesType = Optional[Union[Literal["__all__"], List[str]]]
AvailableAppsType = Optional[List[str]]

# Django test client types
from django.test import Client, AsyncClient, RequestFactory, AsyncRequestFactory
from django.http import HttpResponse
from django.contrib.auth.models import AbstractUser

# Settings wrapper type
class SettingsWrapper:
    """Wrapper for Django settings with context manager support."""
    pass

# Query assertion types
class DjangoAssertNumQueries:
    """Context manager for asserting database query counts."""
    pass

class DjangoCaptureOnCommitCallbacks:
    """Context manager for capturing on_commit callbacks."""
    pass

class DjangoDbBlocker:
    """Database access control context manager."""
    def __init__(self, *, _ispytest: bool = False) -> None: ...
    def block(self) -> ContextManager[None]: ...
    def unblock(self) -> ContextManager[None]: ...
    def restore(self) -> None: ...
    
    @property
    def is_active(self) -> bool: ...
```