Des conseils pour tester l'envoi d'email? Autre que peut-être créer un compte gmail , en particulier pour recevoir ces emails?
J'aimerais peut-être stocker les emails localement, dans un dossier au fur et à mesure de leur envoi.
Vous pouvez utiliser un backend de fichier pour envoyer des emails qui est une solution très pratique pour le développement et les tests; les emails ne sont pas envoyés mais stockés dans un dossier que vous pouvez spécifier!
Le cadre de test de Django a quelques aides intégrées pour vous aider à tester service de messagerie .
Exemple de docs (version courte):
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.',
'[email protected]', ['[email protected]'],
fail_silently=False)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, 'Subject here')
Si vous êtes en phase de test unitaire, la meilleure solution consiste à utiliser le backend en mémoire fourni par Django.
EMAIL_BACKEND = 'Django.core.mail.backends.locmem.EmailBackend'
Prenons le cas de l'utiliser comme un appareil py.test
@pytest.fixture(autouse=True)
def email_backend_setup(self, settings):
settings.EMAIL_BACKEND = 'Django.core.mail.backends.locmem.EmailBackend'
À chaque test, le mail.outbox
est réinitialisé avec le serveur, il n'y a donc aucun effet secondaire entre les tests.
from Django.core import mail
def test_send(self):
mail.send_mail('subject', 'body.', '[email protected]', ['[email protected]'])
assert len(mail.outbox) == 1
def test_send_again(self):
mail.send_mail('subject', 'body.', '[email protected]', ['[email protected]'])
assert len(mail.outbox) == 1
Pour tout projet qui n'exige pas l'envoi de pièces jointes, j'utilise Django-mailer , qui présente l'avantage de mettre tous les courriels sortants dans une file d'attente jusqu'à ce que je déclenche leur envoi, et même après leur envoi, ils sont ensuite connectés - ce qui est visible dans l’administrateur, ce qui facilite la vérification rapide du code de courrier électronique que vous tentez d’envoyer aux intertubes.
Django a également un serveur de courrier électronique en mémoire. Plus de détails dans la documentation sous Backend en mémoire . Ceci est présent dans Django 1.6 pas sûr s'il est présent auparavant.
Corriger SMTPLib à des fins de test peut aider à tester l’envoi d’e-mails sans les envoyer.
Utilisez MAILHOG
Inspiré de MailCatcher, plus facile à installer.
Construit avec Go-MailHog s'exécute sans installation sur plusieurs plates-formes.
En outre, il possède un composant appelé Jim, le MailHog Chaos Monkey, qui vous permet de tester l'envoi d'e-mails avec différents problèmes:
Que peut faire Jim?
- Rejeter les connexions
- Nombre limite de connexions
- Refuser l'authentification
- Rejeter les expéditeurs
- Rejeter les destinataires
En savoir plus à ce sujet ici .
(Contrairement à mailcatcher original, qui m'a échoué lors de l'envoi d'emails avec emoji, codé en UTF-8 } et que cela ne fonctionnait pas vraiment, MailHog fonctionne.
Utiliser le backend de fichiers fonctionne bien, mais je trouve un peu fastidieux de fouiller dans le système de fichiers pour consulter des emails. Vous pouvez utiliser mailcatcher, https://github.com/sj26/mailcatcher , pour capturer des e-mails et les afficher dans une interface utilisateur Web.
Pour utiliser mailcatcher avec Django, vous devez ajouter quelque chose de similaire à votre fichier settings.py:
EMAIL_BACKEND = 'Django.core.mail.backends.smtp.EmailBackend'
EMAIL_Host = '127.0.0.1'
EMAIL_Host_USER = ''
EMAIL_Host_PASSWORD = ''
EMAIL_PORT = 1025
EMAIL_USE_TLS = False
Pourquoi ne pas démarrer votre propre serveur SMTP très simple en héritant de smtpd.SMTPServer
et de 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 est appelé chaque fois que votre serveur SMTP reçoit une demande de courrier, vous pouvez y faire ce que vous voulez.
Dans le code de test, faites quelque chose comme ceci:
smtp_server = TestingSMTPServer()
smtp_server.start()
do_thing_that_would_send_a_mail()
smtp_server.close()
self.assertIn(b'hello', smtp_server.received_data)
Rappelez-vous simplement de close()
le asyncore.dispatcher
en appelant smtp_server.close()
pour mettre fin à la boucle asynchrone (empêche le serveur d'écouter).
Ma solution est d'écrire du contenu dans un fichier html. De cette façon, vous pouvez voir à quoi ressemble un email. Je le laisse ici htmlfilebased.EmailBackend .
Autre conseil: Vous pouvez utiliser Django email template editor qui peut vous aider à modifier votre modèle de courrier électronique avec zéro css en ligne.
Si vous avez un serveur Tomcat disponible ou un autre moteur de servlet, une approche agréable consiste à utiliser le "Post Hoc", un petit serveur qui ressemble à l'application exactement comme un serveur SMTP, inspecter les messages électroniques qui ont été envoyés. Il est open source et disponible gratuitement.
Trouvez-le sur: Site Post Hoc GitHub
Voir le billet de blog: PostHoc: Test d'applications qui envoient un courrier électronique
https://websocket.email fournit un moyen simple de tester l'envoi d'email avec une configuration minimale (vous n'avez même pas besoin d'un compte).
Lier quelques-unes des pièces ici, voici une configuration simple basée sur filebased.EmailBackend
. Cela rend une vue de liste reliant les fichiers journaux individuels, qui ont des noms de fichiers horodatés. Cliquer sur un lien dans la liste affiche ce message dans le navigateur (brut):
Réglages
EMAIL_BACKEND = "Django.core.mail.backends.filebased.EmailBackend"
EMAIL_FILE_PATH = f"{MEDIA_ROOT}/email_out"
Vue
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})
Modèle
{% 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 %}
urls
path("mailcheck/", view=mailcheck, name="mailcheck"),