Djangoアプリケーションが正しい内容の電子メールを送信することをテストする必要があります。実際の電子メールサービスをテストしていないので、外部システム(アドホックGmailアカウントなど)に依存したくありません...
たぶん、メールを送信時にフォルダ内にローカルに保存したいと思います。それを達成する方法についてのヒントはありますか?
Djangoアプリケーションが正しい内容の電子メールを送信することをテストする必要があります。実際の電子メールサービスをテストしていないので、外部システム(アドホックGmailアカウントなど)に依存したくありません...
たぶん、メールを送信時にフォルダ内にローカルに保存したいと思います。それを達成する方法についてのヒントはありますか?
回答:
電子メールの送信にファイルバックエンドを使用できます。これは、開発とテストに非常に便利なソリューションです。メールは送信されませんが、指定したフォルダに保存されます!
Djangoテストフレームワークには、電子メールサービスのテストを支援するヘルパーが組み込まれています。
ドキュメントからの例(短いバージョン):
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')
send_mail
が使用できない複雑なケースには役に立ちません。
mail
か?
mail.outbox
ときに引き続きアクセスできsend_mail
ます。
mail.outbox[0].body
すると、send_mail
他の場所で実行された場合でも送信されたメールが表示されます。
ユニットテストに興味がある場合は、djangoが提供するインメモリバックエンドを使用するのが最善の解決策です。
EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
py.testフィクスチャとして使用する場合を考えてみましょう
@pytest.fixture(autouse=True)
def email_backend_setup(self, settings):
settings.EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
各テストで、mail.outbox
はサーバーでリセットされるため、テスト間に副作用はありません。
from django.core import mail
def test_send(self):
mail.send_mail('subject', 'body.', 'from@example.com', ['to@example.com'])
assert len(mail.outbox) == 1
def test_send_again(self):
mail.send_mail('subject', 'body.', 'from@example.com', ['to@example.com'])
assert len(mail.outbox) == 1
MailHogを使用する
MailCatcherに触発され、インストールが簡単です。
Goで構築-MailHogは複数のプラットフォームにインストールせずに実行されます。
また、ジムと呼ばれるコンポーネントがありますであるMailHog Chaos Monkeyがあり、さまざまな問題が発生した状態で電子メールの送信をテストできます。
ジムは何ができますか?
- 接続を拒否する
- レート制限接続
- 認証を拒否する
- 送信者を拒否する
- 受信者を拒否する
詳しくはこちらをご覧ください。
(絵文字を使用してメールを送信するときに失敗し、UTF-8でエンコードされた元のメールキャッチャーとは異なり、現在のリリースでは実際には修正されていませんでしたが、MailHogは正常に機能します。)
添付ファイルの送信を必要としないプロジェクトでは、django-mailerを使用します。これには、送信をトリガーするまですべての送信メールがキューに入れられ、送信された後でもログに記録されるという利点があります。これらはすべて管理者に表示されるため、メールで送信するコードがインターチューブに送信しようとしているものを簡単に確認できます。
Djangoにはメモリ内のメールバックエンドもあります。詳細については、メモリ内バックエンドのドキュメントをご覧ください。これはDjango1.6に存在し、それ以前の何かに存在するかどうかはわかりません。
テスト目的でSMTPLibにパッチを適用すると、メールを送信せずに送信をテストするのに役立ちます。
ここでいくつかの要素を結び付けて、に基づいた簡単なセットアップを次に示しますfilebased.EmailBackend
。これにより、ファイル名にタイムスタンプが付けられた個々のログファイルにリンクするリストビューが表示されます。リスト内のリンクをクリックすると、そのメッセージがブラウザに表示されます(生)。
設定
EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
EMAIL_FILE_PATH = f"{MEDIA_ROOT}/email_out"
見る
import os
from django.conf import settings
from django.shortcuts import render
def mailcheck(request):
path = f"{settings.MEDIA_ROOT}/email_out"
mail_list = os.listdir(path)
return render(request, "mailcheck.html", context={"mail_list": mail_list})
テンプレート
{% if mail_list %}
<ul>
{% for msg in mail_list %}
<li>
<a href="{{ MEDIA_URL }}email_out/{{msg}}">{{ msg }}</a>
</li>
{% endfor %}
</ul>
{% else %}
No messages found.
{% endif %}
URL
path("mailcheck/", view=mailcheck, name="mailcheck"),
から継承してsmtpd.SMTPServer
、独自の非常に単純なSMTPサーバーを起動してみませんか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は、SMTPサーバーがメール要求を受信するたびに呼び出され、そこで何でも実行できます。
テストコードで、次のようにします。
smtp_server = TestingSMTPServer()
smtp_server.start()
do_thing_that_would_send_a_mail()
smtp_server.close()
self.assertIn(b'hello', smtp_server.received_data)
ただに覚えて呼び出すことで(リスニングからサーバーを停止する)asyncoreループを終了します。close()
asyncore.dispatcher
smtp_server.close()
利用可能なTomCatサーバーまたは他のサーブレットエンジンがある場合、優れたアプローチは「Post Hoc」です。これは、SMTPサーバーとまったく同じようにアプリケーションに見える小さなサーバーですが、表示および表示できるユーザーインターフェイスが含まれています。送信された電子メールメッセージを調べます。オープンソースであり、無料で入手できます。
それを見つける:ポストホックGitHubサイト
ブログ投稿を参照してください: PostHoc:メールを送信するアプリのテスト