CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pytest-django

A Django plugin for pytest that provides Django-specific testing fixtures, marks, and assertions.

Pending
Overview
Eval results
Files

email-testing.mddocs/

Email Testing

Email testing fixtures for capturing and testing Django email functionality. These fixtures provide access to Django's email outbox and DNS configuration for comprehensive email testing.

Capabilities

Email Outbox

Fixture providing access to Django's email outbox for testing sent emails.

def mailoutbox() -> List[django.core.mail.EmailMessage]:
    """
    Access Django's email outbox for testing sent emails.
    
    Returns a list of EmailMessage objects that have been sent during
    the test. The outbox is automatically cleared between tests.
    Requires Django's locmem email backend or test email backend.
    
    Returns:
        List[EmailMessage]: List of email messages sent during test
    """

Usage example:

from django.core import mail

def test_email_sending(mailoutbox):
    from django.core.mail import send_mail
    
    # Send an email
    send_mail(
        subject="Test Subject",
        message="Test message body",
        from_email="from@example.com",
        recipient_list=["to@example.com"],
    )
    
    # Check that email was sent
    assert len(mailoutbox) == 1
    email = mailoutbox[0]
    assert email.subject == "Test Subject"
    assert email.body == "Test message body"
    assert email.from_email == "from@example.com"
    assert email.to == ["to@example.com"]

def test_multiple_emails(mailoutbox):
    from django.core.mail import send_mail
    
    # Send multiple emails
    send_mail("Subject 1", "Body 1", "from@example.com", ["to1@example.com"])
    send_mail("Subject 2", "Body 2", "from@example.com", ["to2@example.com"])
    
    # Check all emails
    assert len(mailoutbox) == 2
    assert mailoutbox[0].subject == "Subject 1"
    assert mailoutbox[1].subject == "Subject 2"

def test_email_with_attachments(mailoutbox):
    from django.core.mail import EmailMessage
    
    email = EmailMessage(
        subject="Test with attachment",
        body="Message with attachment",
        from_email="from@example.com",
        to=["to@example.com"],
    )
    email.attach("test.txt", "File content", "text/plain")
    email.send()
    
    assert len(mailoutbox) == 1
    sent_email = mailoutbox[0]
    assert len(sent_email.attachments) == 1
    assert sent_email.attachments[0] == ("test.txt", "File content", "text/plain")

Email DNS Patching

Fixture that patches DNS name used in email message headers.

def django_mail_patch_dns() -> None:
    """
    Patch DNS name used in Django email message headers.
    
    Patches the DNS_NAME used by Django's email system to use
    a test-friendly DNS name instead of the system's actual DNS name.
    Automatically uses the value from django_mail_dnsname fixture.
    """

Email DNS Name

Fixture providing the DNS name used for email testing.

def django_mail_dnsname() -> str:
    """
    Provide DNS name for email testing.
    
    Returns the DNS name used in email message headers during testing.
    Default value is "fake-tests.example.com" but can be overridden
    by parametrizing this fixture.
    
    Returns:
        str: DNS name for email testing (default: "fake-tests.example.com")
    """

Usage example:

def test_email_dns_name(mailoutbox, django_mail_dnsname):
    from django.core.mail import send_mail
    
    send_mail(
        subject="Test DNS",
        message="Test message",
        from_email="from@example.com",
        recipient_list=["to@example.com"],
    )
    
    # Check that custom DNS name is used
    assert django_mail_dnsname == "fake-tests.example.com"
    # Email will use this DNS name in headers

# Override DNS name for specific test
@pytest.fixture
def django_mail_dnsname():
    return "custom-test.example.com"

def test_custom_dns_name(mailoutbox, django_mail_dnsname):
    # This test will use "custom-test.example.com" as DNS name
    pass

Email Configuration

For email testing to work properly, configure Django settings:

# In Django settings for testing
EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'

# Or in test
def test_with_locmem_backend(settings, mailoutbox):
    settings.EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
    # Now mailoutbox will capture emails

Email Testing Types

from django.core.mail import EmailMessage, EmailMultiAlternatives
from typing import List, Tuple, Optional, Any

# Email message types
EmailMessageType = EmailMessage
EmailList = List[EmailMessage]

# Email content types
EmailSubject = str
EmailBody = str
EmailAddress = str
EmailAddressList = List[str]

# Attachment types
AttachmentTuple = Tuple[str, str, str]  # (filename, content, mimetype)
AttachmentList = List[AttachmentTuple]

# DNS configuration
DnsName = str

# Email message structure
class EmailMessage:
    subject: str
    body: str
    from_email: str
    to: List[str]
    cc: List[str]
    bcc: List[str]
    reply_to: List[str]
    attachments: List[AttachmentTuple]
    extra_headers: dict[str, str]
    
    def send(self, fail_silently: bool = False) -> bool: ...
    def attach(self, filename: str, content: str, mimetype: str) -> None: ...
    def attach_file(self, path: str, mimetype: Optional[str] = None) -> None: ...

class EmailMultiAlternatives(EmailMessage):
    alternatives: List[Tuple[str, str]]  # (content, mimetype)
    
    def attach_alternative(self, content: str, mimetype: str) -> None: ...

# Mail outbox access
from django.core import mail
MailOutbox = mail.outbox

Install with Tessl CLI

npx tessl i tessl/pypi-pytest-django

docs

client-testing.md

database-testing.md

django-assertions.md

django-utilities.md

email-testing.md

index.md

live-server-testing.md

pytest-marks.md

query-testing.md

settings-management.md

transaction-callbacks.md

user-management.md

tile.json