A Django plugin for pytest that provides Django-specific testing fixtures, marks, and assertions.
—
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.
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")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.
"""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
passFor 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 emailsfrom 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.outboxInstall with Tessl CLI
npx tessl i tessl/pypi-pytest-django