I have a Django application that sends an email. The production server has an email server but my local box does not. I would like to be able to test sending of email locally. Is there any way that I can have django not send it through the email server and just print out to a file or console?
-
The operating system of your local box might be a useful thing to know here... You don't actually need an email server on the box anyway, all you need is a network connection to an email server via the SMTP port... and possible user/password. – Spacedman Jan 09 '11 at 22:21
-
possible duplicate of [Dummy SMTP Server for testing apps that send email](http://stackoverflow.com/questions/1006650/dummy-smtp-server-for-testing-apps-that-send-email) – Patrick McElhaney Apr 07 '11 at 18:23
-
mailsnag.com is built for that. It works with any framework and has some nice features for fault simulations – Iuri G. Oct 16 '22 at 20:57
6 Answers
You can configure your application to use the Console Backend for sending e-mail. It writes e-mails to standard out instead of sending them.
Change your settings.py to include this line:
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
Don't forget to remove it for production.

- 28,981
- 10
- 72
- 75
-
21Better yet, put it in a development settings file and don't add it to production. – leech Mar 11 '14 at 06:41
-
3Or even better yet, [do it with environment variables](http://12factor.net/config). – meshy Apr 23 '15 at 20:47
-
1If you're using [`mail_admins`](https://docs.djangoproject.com/en/stable/topics/email/#mail-admins), remember to set [`ADMINS`](https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-ADMINS) to something, otherwise nothing will get print to stdout. Similarly for `mail_managers`. – Flimm Mar 28 '16 at 17:34
Python has a little SMTP server built-in. You can start it in a second console with this command:
python -m smtpd -n -c DebuggingServer localhost:1025
This will simply print all the mails sent to localhost:1025
in the console.
You have to configure Django to use this server in your settings.py
:
EMAIL_HOST = 'localhost'
EMAIL_PORT = 1025

- 30,958
- 11
- 90
- 100
-
Note that your app may throw an exception if it tries to send an email when the email server isn't started. `fail_silently=False` is the default for `send_mail`. – Tim Fletcher Mar 26 '13 at 04:16
-
1While Daniel Hepper's answer is undoubtedly the correct one with respect to the question posed, I like this answer better because it's a general solution that works regardless of environment. (Upvotes on both though, of course.) – Teekin May 09 '17 at 10:20
You can configure your application to write emails out to temporary files instead of sending them (similar to Daniel Hepper's answer).
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = 'tmp/email-messages/'
This saves each new message as a separate file. Useful if you are sending heaps of emails, and don't want to have to use the scrollback.

- 35,041
- 6
- 86
- 121
If your tests extends from django.test.testcases.TestCase then nothing has to be done. Django will replace the EmailBackend to a "special" one. Then you can test what would had been sent like this :
def testMethodThatSendAEmail(self):
...
from django.core import mail
object.method_that_send_email(to='me@example.com')
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].to, ['me@example.com'])
...#etc
The outbox object is a special object that get injected into mail when python manage.py test is run.

- 3,364
- 2
- 30
- 43
This elaborates on the answer from Benjamin. One way that I test emails if I don't have a local email server like postfix, sendmail or exim installed is to run the python email server. You can run it on port 25 with sudo, or just use a port > 1024 (reserved ports):
python -m smtpd -n -c DebuggingServer localhost:1025
#sudo python -m smtpd -n -c DebuggingServer localhost:25
For testing with your current django app code, you can change settings.py temporarily to include this at the botom:
EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD = 'localhost', 1025, None, None
Now test out your emails, or you can do this in ./manage.py shell in another terminal window like so:
python manage.py shell
And paste in this code to send an email:
from django.core.mail import send_mail
send_mail('Subject here', 'Here is the message.', 'messanger@localhost.com',['any@email.com'], fail_silently=False)
No need to use any real emails since you will see everything in your terminal. You can dump it to the appropriate container like .html for further testing.

- 34,210
- 11
- 144
- 111
There is a cool app for this by caktus https://github.com/caktus/django-email-bandit Just add this to your settings.py file:
EMAIL_BACKEND = 'bandit.backends.smtp.HijackSMTPBackend'
BANDIT_EMAIL = 'your_email@example.com'
On top of your email setttings..All emails will be diverted to 'your_email@example.com'
Happy coding...

- 446
- 1
- 7
- 14