Pytest-django: `mail.outbox` 没有被设置?

创建于 2018-04-10  ·  14评论  ·  资料来源: pytest-dev/pytest-django

嘿,感谢 pytest-django! 感谢所有的辛勤工作,已经使用它很多次了,没有任何问题。

我们遇到了一些问题,我们升级了一些东西,突然mail.outbox在测试期间没有保留电子邮件。 我试图弄清楚如何准确地使用mailoutbox固定装置,如此处记录的那样但我在使用它时遇到了麻烦。

现在我们正在一个班级中进行测试,我已经尝试了很多配置来传递mailoutbox固定装置。 即我更新了ini:

[pytest]
usefixtures = mailoutbox

虽然不确定如何使用该装置,但我尝试将位置参数mailoutbox到我的类方法中,但仍然无法访问它..我确定我错过了一些简单的东西。

希望朝着正确的方向推动——再次,非常感谢这个项目!

最有用的评论

我想我遇到了同样的问题,所以我决定将我的测试剥离到基本的电子邮件发送并单独运行它:

def test_reset_password(mailoutbox, db, settings):
    text_message = render_to_string('emails/password_reset/password_reset_successful.txt',
                                    context={})
    html_message = render_to_string('emails/password_reset/password_reset_successful.html',
                                    context={})
    subject = render_to_string('emails/password_reset/password_reset_successful_subject.txt',
                               context={})

    email = EmailMultiAlternatives(
        subject=subject,
        body=text_message,
        from_email="[email protected]",
        to=['[email protected]']
    )

    if html_message:
        email.attach_alternative(html_message, "text/html")
    email.send()

    print(settings.EMAIL_BACKEND)

    assert len(mailoutbox) == 1
>       assert len(mailoutbox) == 1
E       assert 0 == 1
E        +  where 0 = len([])

accounts/tests/api/test_reset_password.py:200: AssertionError
----------------------------------------------- Captured stdout call ------------------------------------------------
django.core.mail.backends.locmem.EmailBackend
--------------------------------------------- Captured stdout teardown ----------------------------------------------

现在很酷的部分是如果我删除db固定装置,测试通过。 所以我尝试删除我的django_db_setup方法,但无济于事......

我现在被困住了。

所有14条评论

请参阅https://github.com/pytest-dev/pytest-django/blob/5da0935731d71aa347c57cd1753f51e3ba9f32d5/docs/helpers.rst#clearing -of-mailoutbox (7aee367)。
(虽然不清楚我是否正确理解了这个问题)

我想我遇到了同样的问题,所以我决定将我的测试剥离到基本的电子邮件发送并单独运行它:

def test_reset_password(mailoutbox, db, settings):
    text_message = render_to_string('emails/password_reset/password_reset_successful.txt',
                                    context={})
    html_message = render_to_string('emails/password_reset/password_reset_successful.html',
                                    context={})
    subject = render_to_string('emails/password_reset/password_reset_successful_subject.txt',
                               context={})

    email = EmailMultiAlternatives(
        subject=subject,
        body=text_message,
        from_email="[email protected]",
        to=['[email protected]']
    )

    if html_message:
        email.attach_alternative(html_message, "text/html")
    email.send()

    print(settings.EMAIL_BACKEND)

    assert len(mailoutbox) == 1
>       assert len(mailoutbox) == 1
E       assert 0 == 1
E        +  where 0 = len([])

accounts/tests/api/test_reset_password.py:200: AssertionError
----------------------------------------------- Captured stdout call ------------------------------------------------
django.core.mail.backends.locmem.EmailBackend
--------------------------------------------- Captured stdout teardown ----------------------------------------------

现在很酷的部分是如果我删除db固定装置,测试通过。 所以我尝试删除我的django_db_setup方法,但无济于事......

我现在被困住了。

我忘了提到在同一个项目中有一些测试, mailoutbox夹具似乎可以工作,所以我试图找出这些测试和失败的测试之间的任何区别。
我发现的唯一区别是mailoutbox参数在测试函数中的位置。 如果它在任何依赖于db固定装置的固定装置之前它不起作用,但如果我把它放在后面它会起作用,所以我想我找到了一个解决方法。

我可以通过 pytest-django==3.3.3 确认我们也看到了这种行为

@bogdanpetrea
感谢您的调查/更新。
将有助于某人调试/修复此问题。

不确定它是否真的相关,但我发现可能存在 AttributeError 由于mail.outbox没有首先设置 - 但这与 pytest-django 启动时改变环境有关。
参考: https :

我目前遇到的问题是,mailoutbox 不是空的 :(
这是最新的测试函数参数。

编辑:我在真正的测试代码之前调用mailoutbox.clear()作为工作。

@jedie
你能提供一个可重现的测试用例吗? pytest-django 的失败测试当然是最好的。

与#708有关? (即在它触及的代码周围戳一下)

我创建了一个简单的测试用例来重现这个问题(至少是我遇到的问题): https ://github.com/pytest-dev/pytest-django/compare/master...koniiiik :589- mailoutbox-is-not-django-core-mail-outbox?expand=1

从我如何使用mailoutbox来看,能够让mailoutbox.clear()实际清除mailoutboxmail.outbox也非常有帮助。 如果mailoutbox is mail.outbox ,那么有人可以在运行代码之前清除发件箱,然后应该生成特定数量的电子邮件(即1电子邮件)。

不确定这是否与此问题有关,但mailoutbox固定装置在我的测试中与mail.outbox的行为不匹配。 它不收集已发送的电子邮件:

(Pdb) mail.outbox
[<django.core.mail.message.EmailMultiAlternatives object at 0x7f6d864cb198>]
(Pdb) mailoutbox
[]
(Pdb)

不确定这是否与此问题有关,但mailoutbox固定装置在我的测试中与mail.outbox的行为不匹配。 它不收集已发送的电子邮件:

(Pdb) mail.outbox
[<django.core.mail.message.EmailMultiAlternatives object at 0x7f6d864cb198>]
(Pdb) mailoutbox
[]
(Pdb)

相同的。
mail.outbox包含一条消息,而mailoutbox为空。
pytest-django 版本是 3.9.0。

我有同样的问题。

如果我使用这样的夹具失败:

def test_send_foo_mail(mailoutbox, user_client, foo):

像这样它的工作原理:

def test_send_foo_mail(user_client, foo, mailoutbox):

我花了很多时间才发现它。 我想帮助调试这个。 我查看了实现,但我不知道如何调试它。

相关: https :

经历与前一位评论员相同的行为。 像这样使用它不起作用:

def test_command_and_email(
    mailoutbox, argument, time_machine, mocker 
):

但是如果我把它放在最后一个地方,一切都会正常运行。

def test_command_and_email(
    argument, time_machine, mocker, mailoutbox
):

参数argument也是一个使用db固定装置的固定装置,所以我想这是这种行为的主要原因。
我正在使用pytets-django 4.3.0

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

jedie picture jedie  ·  7评论

blueyed picture blueyed  ·  7评论

clintonb picture clintonb  ·  4评论

rlskoeser picture rlskoeser  ·  7评论

mjk4 picture mjk4  ·  4评论