首页 文章

为什么Django的send_mail在测试期间不起作用?

提问于
浏览
1

我有一个应用程序,可导入许多用户电子邮件地址并为其创建帐户 . 为了让他们设置自己的密码,我尝试使用django的PasswordResetForm(在django.contrib.auth.forms中) . 创建用户帐户后立即调用密码重置:

def reset_password(person):
    form = PasswordResetForm({'email': person.email})
    if form.is_valid():
        form.save(from_email='myname@myserver.com')

我没有进行任何进一步的测试,而不是包括执行此操作的单元测试:

import password_reset_module
class TestPasswordReset(TestCase):
     def setUp(self):
         p = Person(email='test@test.com')
     def test_send(self):
         password_reset_module.reset_password(p)

没有断言,现在我只想通过监视我运行的控制台来查看是否有邮件发送:

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

保存表单调用django的send_mail . 运行测试用例时,send_mail方法返回1.但是,控制台中不会显示任何邮件 . 奇怪的是从django的交互式shell调用send_mail:

python manage.py shell

工作良好 . 邮件显示在控制台中 . 在浏览器中单击忘记密码链接也会导致发送邮件 .

我也尝试过基于文件的电子邮件后端无济于事 . 当前settings.py电子邮件设置:

EMAIL_USE_TLS = False
EMAIL_HOST = 'localhost'
DEFAULT_FROM_EMAIL = 'myname@myserver.com'
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_PORT = 1025

现在想知道我在调用密码重置时是否遗漏了什么,或者手头有邮件服务器配置问题吗?

3 回答

  • 2

    尝试将其转换为适当的单元测试可能是值得的,当然您可以将其作为自动测试套件的一部分运行 . 对于单元测试,可能最简单的方法来检查邮件是否已发送(并在需要时验证邮件内容)是使用内置电子邮件后端内置的Django - 您只需使用此框中的outbox属性即可获得已发送邮件列表:

    https://docs.djangoproject.com/en/dev/topics/email/#in-memory-backend

    这样做的好处是不需要任何基础设施设置来支持测试电子邮件发送,这使得断言电子邮件内容非常简单,这也应该使测试更快(与实际将电子邮件发送到SMTP服务器相比) .

    希望这可以帮助 .

  • 4

    您的配置被否决了

    在"Email Services"部分,Django testing documentation说:

    Django的测试运行器自动将所有Django发送的电子邮件重定向到虚拟发件箱 . [...]在测试运行期间,每封外发电子邮件都保存在django.core.mail.outbox中 . 这是已发送的所有EmailMessage实例的简单列表 .

    咦?

    The Django test runner will actually configure a different email backend for you (称为locmem) . 如果您只想进行单元测试(不与实际的电子邮件服务器集成),这非常方便,但如果您不了解它,则会非常令人惊讶 .

    (我没有使用Django测试运行器 manage.py test ,但无论如何它都会发生,大概是因为我安装了 pytest-django ,它神奇地修改了我的 py.test . )

    如果要覆盖覆盖并使用 settings 模块中给出的电子邮件配置,则需要重新设置的只是电子邮件后端的设置,例如:像这样:

    @django.test.utils.override_settings(
        EMAIL_BACKEND='django.core.mail.backends.smtp.EmailBackend')
    def test_send_email_with_real_SMTP(self):
       ...
    
  • 3

    根据我的理解,您在测试设备时运行以下命令 .

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

    此命令启动一个“哑”的SMTP服务器,它接收您的电子邮件并在终端上显示它们 . 尝试在没有设置此DebuggingServer的情况下运行您的站点,并查看邮件是否已发送 .

    这是对docs page的引用

相关问题