Skip to main content

Django Testcontainers Plus

A plug-and-play testcontainers integration for Django

PyPI version License: MIT

Why Django Testcontainers Plus?

Testing Django applications often requires external services like PostgreSQL, Redis, or S3. Django Testcontainers Plus makes this effortless by:

  • Zero Configuration: Automatically detects your database and service needs from Django settings
  • Plug and Play: Install, add to settings, and go - no manual container management
  • Database Agnostic: Supports PostgreSQL, MySQL, MariaDB, and more
  • Beyond Databases: Redis for caching, S3-compatible storage, and other services
  • Dual Compatibility: Works with both Django's test runner and pytest
  • Smart Defaults: Sensible defaults with full customization when needed

Installation

Basic Installation

# Using uv (recommended)
uv add django-testcontainers-plus

# Using pip
pip install django-testcontainers-plus

Optional Extras for containers

# MySQL/MariaDB support
pip install django-testcontainers-plus[mysql]

# Redis support
pip install django-testcontainers-plus[redis]

# S3 support (RustFS)
pip install django-testcontainers-plus[s3]

# Or install all
pip install django-testcontainers-plus[all]

Note Postgres works by default so doesn't need to be installed like the above

Quick Start

Option 1: Django Test Runner (Minimal Setup)

# settings.py
TEST_RUNNER = 'django_testcontainers_plus.runner.TestcontainersRunner'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'myapp',
    }
}

That's it! Run your tests:

python manage.py test

PostgreSQL will automatically start in a container, run your tests, and clean up.

Option 2: pytest-django

# conftest.py
pytest_plugins = ['django_testcontainers_plus.pytest_plugin']
# settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'test',
    }
}

Run your tests:

pytest

Supported Services

Databases

  • PostgreSQL - Auto-detected from django.db.backends.postgresql
  • MySQL/MariaDB - Auto-detected from django.db.backends.mysql
  • MongoDB - Coming soon
  • SQL Server - Coming soon

Other Services

  • Redis - Auto-detected from cache/Celery settings
  • Mailhog - Auto-detected from SMTP email backend
  • S3 (RustFS) - Auto-detected from django-storages S3 backend
  • Elasticsearch - Search (coming soon)

Configuration

Zero Configuration (Auto-Detection)

Django Testcontainers Plus automatically detects services from your settings:

# PostgreSQL auto-detected
DATABASES = {
    'default': {'ENGINE': 'django.db.backends.postgresql', 'NAME': 'test'}
}

# Redis auto-detected
CACHES = {
    'default': {'BACKEND': 'django.core.cache.backends.redis.RedisCache'}
}

# Celery Redis auto-detected
CELERY_BROKER_URL = 'redis://localhost:6379/0'

# Mailhog auto-detected
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'localhost'

Custom Configuration

Override defaults when needed:

TESTCONTAINERS = {
    'postgres': {
        'image': 'postgres:16-alpine',
        'username': 'testuser',
        'password': 'testpass',
        'dbname': 'testdb',
    },
    'redis': {
        'image': 'redis:7-alpine',
    },
    'mailhog': {
        'image': 'mailhog/mailhog:latest',
    },
}

Disable Auto-Detection

TESTCONTAINERS = {
    'postgres': {
        'auto': False,  # Disable auto-detection
        'enabled': True,  # But explicitly enable it
    },
}

Examples

PostgreSQL with Django Test Runner

# settings.py
TEST_RUNNER = 'django_testcontainers_plus.runner.TestcontainersRunner'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'myapp',
    }
}

# Optional: Customize PostgreSQL version
TESTCONTAINERS = {
    'postgres': {
        'image': 'postgres:15',
    }
}
python manage.py test

MySQL with pytest

# conftest.py
pytest_plugins = ['django_testcontainers_plus.pytest_plugin']

# settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'test',
    }
}
pytest

PostgreSQL + Redis

# settings.py
TEST_RUNNER = 'django_testcontainers_plus.runner.TestcontainersRunner'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'test',
    }
}

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.redis.RedisCache',
        'LOCATION': 'redis://localhost:6379/0',
    }
}

Both PostgreSQL and Redis containers will start automatically!

Mailhog for Email Testing

Mailhog is an email testing tool that captures emails sent by your application. When the Mailhog container starts, the following Django settings are automatically configured:

Setting Description
EMAIL_HOST Container hostname
EMAIL_PORT SMTP port (mapped from 1025)
EMAIL_USE_TLS Set to False
EMAIL_USE_SSL Set to False
MAILHOG_API_URL HTTP API base URL for retrieving sent emails (e.g., http://localhost:32769/api/v2)
# settings.py
TEST_RUNNER = 'django_testcontainers_plus.runner.TestcontainersRunner'

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'localhost'
EMAIL_PORT = 1025
# tests.py
from django.core.mail import send_mail
from django.conf import settings
import requests

def test_email_sending():
    # Mailhog container is automatically started
    send_mail(
        'Test Subject',
        'Test message body',
        'from@example.com',
        ['to@example.com'],
        fail_silently=False,
    )

    # Retrieve sent emails via Mailhog API using MAILHOG_API_URL
    response = requests.get(f'{settings.MAILHOG_API_URL}/messages')
    messages = response.json()['items']

    assert len(messages) == 1
    assert messages[0]['Content']['Headers']['Subject'][0] == 'Test Subject'

def test_clear_mailbox():
    # Delete all messages before test
    requests.delete(f'{settings.MAILHOG_API_URL}/messages')

    # ... send emails and verify

Note: The MAILHOG_API_URL setting is dynamically injected when the container starts. Use it to interact with the Mailhog API for retrieving, searching, or deleting captured emails during tests.

How It Works

  1. Detection: Scans your Django settings for database engines and service backends
  2. Configuration: Merges detected needs with any custom TESTCONTAINERS config
  3. Startup: Starts necessary containers before tests run
  4. Injection: Updates Django settings with container connection details
  5. Cleanup: Stops and removes containers after tests complete

Troubleshooting

Missing Dependency Errors

If you see an error like this:

======================================================================
MySQL Support Not Installed
======================================================================

MySQL was detected in your Django settings:
  → DATABASES['default']['ENGINE']

To enable MySQL support, install the required dependencies:
  pip install django-testcontainers-plus[mysql]

Or install all providers:
  pip install django-testcontainers-plus[all]
======================================================================

What happened? Django Testcontainers Plus detected that you're using MySQL in your settings, but the MySQL client library (mysql-connector-python) isn't installed.

Solution: Install the extra for your database:

# For MySQL/MariaDB
pip install django-testcontainers-plus[mysql]

# For Redis
pip install django-testcontainers-plus[redis]

# For S3 (RustFS)
pip install django-testcontainers-plus[s3]

# Or install everything
pip install django-testcontainers-plus[all]

Common Issues

Q: Why do I need extras for some databases but not Postgres?

A: PostgreSQL works without extras because the base testcontainers package includes PostgreSQL support. MySQL and Redis require their respective Python client libraries.

Q: Can I disable auto-detection?

A: Yes! Set auto: False in your configuration:

TESTCONTAINERS = {
    'mysql': {
        'auto': False,  # Won't auto-detect MySQL
        'enabled': False,  # Explicitly disable
    }
}

Q: The error message says a service was detected, but I don't use it

A: Check your settings for Redis/MySQL references in:

  • DATABASES - Database engines
  • CACHES - Cache backends
  • CELERY_BROKER_URL - Celery broker
  • SESSION_ENGINE - Session storage

You can disable detection for that service with auto: False.

Q: Tests work locally but fail in CI

A: Make sure your CI environment has:

  1. Docker available (most CI providers include it)
  2. The correct extras installed: pip install django-testcontainers-plus[all]
  3. Sufficient permissions to run Docker containers

Development

This project uses uv for package management.

# Clone the repository
git clone https://github.com/woodywoodster/django-testcontainers-plus
cd django-testcontainers-plus

# Install dependencies (including all optional database clients)
uv sync --all-extras --dev

# Run tests
uv run pytest

# Run linting
uv run ruff check .

# Run type checking
uv run mypy src/

Roadmap

  • PostgreSQL support
  • MySQL/MariaDB support
  • Redis support
  • Django test runner integration
  • pytest plugin
  • Mailhog support
  • MongoDB support
  • S3-compatible object storage (RustFS)
  • Elasticsearch support
  • RabbitMQ support
  • Container reuse between test runs
  • Parallel test support
  • Full documentation site

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Credits

Built with testcontainers-python.

Metadata

Release files for django-testcontainers-plus 0.1.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-testcontainers-plus 0.1.6
File Size Uploaded
django_testcontainers_plus-0.1.6.tar.gz 116.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-testcontainers-plus 0.1.6
File Interpreter ABI Platform
django_testcontainers_plus-0.1.6-py3-none-any.whl Python 3 none any Details

Total release size: 138.3 kB

Release files / django_testcontainers_plus-0.1.6.tar.gz

Download URL django_testcontainers_plus-0.1.6.tar.gz
Size 116.6 kB
Tags Source
SHA-256 checksum
How to use checksums
090d09232855d2e2392e8a9db3dc3b11a38578b918a1b666a80decafbd8febdd
BLAKE2b-256 checksum
How to use checksums
c64ce2d8340fb7d5700d2fe9958126f681ad14e36a3226e4b4ea0b6476123d6b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / django_testcontainers_plus-0.1.6-py3-none-any.whl

Download URL django_testcontainers_plus-0.1.6-py3-none-any.whl
Size 21.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
45f3535ddd92a22024ef8b51ac6271e66b8c036417f21e483176355f2adab864
BLAKE2b-256 checksum
How to use checksums
1608bee3c2fbc6e142e6590a27560c8331161167a024dd0e923b3db0d76fa703
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.1.7

2 release files

This release

0.1.6 This release

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page