Pytest-django: `mail.outbox`が設定されていませんか?

作成日 2018年04月10日  ·  14コメント  ·  ソース: pytest-dev/pytest-django

ねえ、pytest-djangoに感謝します! すべてのハードワークに感謝し、問題なく何度も使用しました。

いくつかのものをアップグレードしたところ、突然mail.outboxがテスト中にメールを保持しなくなって、ちょっとした問題が発生しました。 私が使用する方法を正確に把握することを試みたmailoutbox記載されているように、固定具を、ここで私はこれを使用して問題を抱えています。

現在、クラスでテストしており、 mailoutboxフィクスチャを渡すためにかなりの数の構成を試しました。 つまり、iniを更新しました:

[pytest]
usefixtures = mailoutbox

ただし、そのフィクスチャの使用方法が正確にはわかりませんが、位置引数mailoutboxをクラスメソッドに追加しようとしましたが、それでもアクセスできません。単純なものが不足していると確信しています。

正しい方向への推進に感謝します-そしてまた、このプロジェクトに感謝​​します!

bug

最も参考になるコメント

同じ問題が発生していると思うので、テストを基本的な電子メール送信に分解して、個別に実行することにしました。

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
調査/更新をありがとう。
誰かがこれをデバッグ/修正するのに役立ちます。

それが本当に関連しているかどうかはわかりませんが、 mail.outboxが最初に設定されていないために、AttributeErrorが発生する可能性があることがわかりました。ただし、これはpytest-djangoの起動中に環境を変更することに関連しています。
参照: https

私は現在問題を抱えています、そのmailoutboxは空ではありません:(
これは最新のテスト関数の引数です。

編集:回避策として、実際のテストコードの前にmailoutbox.clear()を呼び出します。

@ジェダイ
再現可能なテストケースを提供できますか? もちろん、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
):

引数argumentdbフィクスチャを使用するフィクスチャであるため、これがこの動作の主な理由だと思います。
pytets-django 4.3.0

このページは役に立ちましたか?
0 / 5 - 0 評価