Testing email sending

2019-03-08 06:41发布

Any tips on testing email sending? Other than maybe creating a gmail account, especially for receiving those emails?

I would like to, maybe, store the emails locally, within a folder as they are sent.

13条回答
淡お忘
2楼-- · 2019-03-08 07:11

Use MailHog

Inspired by MailCatcher, easier to install.

Built with Go - MailHog runs without installation on multiple platforms.


Also, it has a component called Jim, the MailHog Chaos Monkey, which enables you to test sending emails with various problems happening:

What can Jim do?

  • Reject connections
  • Rate limit connections
  • Reject authentication
  • Reject senders
  • Reject recipients

Read more about it here.


(Unlike original mailcatcher, which failed on me when sending emails with emoji, encoded in UTF-8 and it WASN'T really fixed in the current release, MailHog just works.)

查看更多
We Are One
3楼-- · 2019-03-08 07:14

For any project that doesn't require sending attachments, I use django-mailer, which has the benefit of all outbound emails ending up in a queue until I trigger their sending, and even after they've been sent, they are then logged - all of which is visible in the Admin, making it easy to quickly check what you emailing code is trying to fire off into the intertubes.

查看更多
兄弟一词,经得起流年.
4楼-- · 2019-03-08 07:16

My solution is write content to a html file. This way can help you see how email look like. I leave it here htmlfilebased.EmailBackend.

Other tip: You can use django email template editor which can help you edit your email template with zero inline css.

查看更多
神经病院院长
5楼-- · 2019-03-08 07:23

Why not start your own really simple SMTP Server by inherit from smtpd.SMTPServer and threading.Thread:

class TestingSMTPServer(smtpd.SMTPServer, threading.Thread):
    def __init__(self, port=25):
        smtpd.SMTPServer.__init__(
            self,
            ('localhost', port),
            ('localhost', port),
            decode_data=False
        )
        threading.Thread.__init__(self)

    def process_message(self, peer, mailfrom, rcpttos, data, **kwargs):
        self.received_peer = peer
        self.received_mailfrom = mailfrom
        self.received_rcpttos = rcpttos
        self.received_data = data

    def run(self):
        asyncore.loop()

process_message is called whenever your SMTP Server receive a mail request, you can do whatever you want there.

In the testing code, do something like this:

smtp_server = TestingSMTPServer()
smtp_server.start()
do_thing_that_would_send_a_mail()
smtp_server.close()
self.assertIn(b'hello', smtp_server.received_data)

Just remember to close() the asyncore.dispatcher by calling smtp_server.close() to end the asyncore loop(stop the server from listening).

查看更多
做个烂人
6楼-- · 2019-03-08 07:24

Django test framework has some built in helpers to aid you with testing e-mail service.

Example from docs (short version):

from django.core import mail
from django.test import TestCase

class EmailTest(TestCase):
    def test_send_email(self):
        mail.send_mail('Subject here', 'Here is the message.',
            'from@example.com', ['to@example.com'],
            fail_silently=False)
        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].subject, 'Subject here')
查看更多
我欲成王,谁敢阻挡
7楼-- · 2019-03-08 07:24

Using the file backend works well, but I find it a little a cumbersome to poke around the filesystem to look at emails. You could use mailcatcher, https://github.com/sj26/mailcatcher, to capture emails and display them in a web UI.

To use mailcatcher with Django you'll need to add something like the following to your settings.py:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = '127.0.0.1'
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_PORT = 1025
EMAIL_USE_TLS = False
查看更多
登录 后发表回答