没有邮件服务器如何测试发送电子邮件

77

我有一个使用Django编写的应用程序,可以发送电子邮件。生产服务器有一个电子邮件服务器,但我的本地计算机上没有。我想测试在本地发送电子邮件的功能。是否有办法使django不通过电子邮件服务器发出邮件,而是将其打印到文件或控制台中?


你的本地计算机操作系统在这里可能是一个有用的信息... 你实际上不需要在计算机上安装邮件服务器,你只需要通过SMTP端口连接到邮件服务器的网络,并提供可能的用户名/密码即可。 - Spacedman
mailsnag.com专为此而建。它可以与任何框架一起使用,并具有一些用于故障模拟的不错功能。 - Iuri G.
6个回答

141

您可以配置您的应用使用控制台后端来发送电子邮件。它将电子邮件写入标准输出而不是发送它们。

更改您的settings.py文件以包含以下行:

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

不要忘记在生产环境中删除它。


21
最好将其放在开发设置文件中,不要添加到生产环境中。 - leech
3
甚至更好的做法是,使用环境变量进行配置(参考12要素应用宣言中的说明)。 - meshy
1
如果您正在使用mail_admins,请记得将ADMINS设置为某些内容,否则不会打印到标准输出。对于mail_managers同样如此。 - Flimm

85

Python内置了一个小型的SMTP服务器(built-in)。您可以使用以下命令在第二个控制台中启动它:

python -m smtpd -n -c DebuggingServer localhost:1025

这将在控制台中简单地打印发送到localhost:1025的所有邮件。

您必须在settings.py中配置Django以使用此服务器:

EMAIL_HOST = 'localhost'
EMAIL_PORT = 1025

请注意,如果您尝试在电子邮件服务器未启动时发送电子邮件,则您的应用程序可能会引发异常。fail_silently=Falsesend_mail 的默认设置。 - Tim Fletcher
1
虽然Daniel Hepper的回答无疑是针对所提出问题的正确答案,但我更喜欢这个答案,因为它是一个通用解决方案,不受环境限制。(当然,两个答案都有赞同。) - Teekin

42

你可以配置你的应用程序将电子邮件写入临时文件而不是发送它们(类似于Daniel Hepper的答案)。

EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = 'tmp/email-messages/'

这将每个新邮件保存为单独的文件。如果您发送了大量的电子邮件,而且不想使用滚动条,这很有用。


35
如果您的测试继承自 django.test.testcases.TestCase,则无需进行任何操作。 Django将EmailBackend替换为一个“特殊”的后端,然后您可以像这样测试将要发送的内容:
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

当运行python manage.py test时,会将outbox对象注入到邮件中。


1
这太棒了。 - Tolgahan ÜZÜN

13

这是对本杰明回答的补充。如果我没有安装像 postfix、sendmail 或 exim 这样的本地电子邮件服务器,我测试电子邮件的一种方法是运行 Python 电子邮件服务器。您可以使用sudo在端口25上运行它,或者只需使用一个大于1024(保留端口)的端口:

python -m smtpd -n -c DebuggingServer localhost:1025
#sudo python -m smtpd -n -c DebuggingServer localhost:25

为了测试您当前的Django应用程序代码,您可以将settings.py临时更改为在底部包含以下内容:

EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD = 'localhost', 1025, None, None

现在测试你的电子邮件,或者你可以在另一个终端窗口中使用 ./manage.py shell 进行测试,像这样:

python manage.py shell

将以下代码粘贴到邮件中即可发送电子邮件:

from django.core.mail import send_mail​
send_mail('Subject here', 'Here is the message.', 'messanger@localhost.com',['any@email.com'], fail_silently=False)

不需要使用任何真实的电子邮件地址,因为您可以在终端中查看所有内容。您可以将其倾倒到适当的容器中,例如 .html 进行进一步测试。


11

有一个很酷的应用程序由caktus开发 https://github.com/caktus/django-email-bandit 只需将以下内容添加到您的settings.py文件中:

EMAIL_BACKEND = 'bandit.backends.smtp.HijackSMTPBackend'
BANDIT_EMAIL = 'your_email@example.com'
在您的电子邮件设置之上...所有电子邮件将被转发到“your_email@example.com”
愉快的编码...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接