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?
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.
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
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.
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.
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...
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.
来源:https://stackoverflow.com/questions/4642011/test-sending-email-without-email-server