I haven’t written one of these supposedly weekly posts with small Django tips for a while, but at least I always post them on Fridays.
This time I gonna address how we can test emails with the tools that Django provides and more precisely how to check the attachments of those emails.
The testing behavior of emails is very well documented (Django’s documentation is one of the best I’ve seen) and can be found here.
Summing it up, if you want to test some business logic that sends an email, Django replaces the
EMAIL_BACKEND setting with a testing backend during the execution of your test suite and makes the outbox available through
But what about attachments? Since each item on the testing outbox is an instance of the
EmailMessage class, it contains an attribute named “attachments” (surprise!) that is list of tuples with all the relevant information:
("<filename>", "<contents>", "<mime type>")
Here is an example:
# utils.py from django.core.mail import EmailMessage def some_function_that_sends_emails(): msg = EmailMessage( subject="Example email", body="This is the content of the email", from_email="email@example.com", to=["firstname.lastname@example.org"], ) msg.attach("sometext.txt", "The content of the file", "text/plain") msg.send() # tests.py from django.test import TestCase from django.core import mail from .utils import some_function_that_sends_emails class ExampleEmailTest(TestCase): def test_example_function(self): some_function_that_sends_emails() self.assertEqual(len(mail.outbox), 1) email_message = mail.outbox self.assertEqual(email_message.subject, "Example email") self.assertEqual(email_message.body, "This is the content of the email") self.assertEqual(len(email_message.attachments), 1) file_name, content, mimetype = email_message.attachments self.assertEqual(file_name, "sometext.txt") self.assertEqual(content, "The content of the file") self.assertEqual(mimetype, "text/plain")
If you are using
pytest-django the same can be achieved with the
import pytest from .utils import some_function_that_sends_emails def test_example_function(mailoutbox): some_function_that_sends_emails() assert len(mailoutbox) == 1 email_message = mailoutbox assert email_message.subject == "Example email" assert email_message.body == "This is the content of the email" assert len(email_message.attachments) == 1 file_name, content, mimetype = email_message.attachments assert file_name == "sometext.txt" assert content == "The content of the file" assert mimetype == "text/plain"
And this is it for today.