Je dois tester que mon application Django envoie des e-mails avec un contenu correct. Je ne veux pas compter sur des systèmes externes (comme un compte Gmail ad hoc ), car je ne teste pas le service de messagerie réel ...
J'aimerais, peut-être, stocker les e-mails localement, dans un dossier au fur et à mesure de leur envoi. Une astuce pour y parvenir?
Réponses:
Vous pouvez utiliser un serveur de fichiers pour envoyer des e-mails, ce qui est une solution très pratique pour le développement et les tests; les e-mails ne sont pas envoyés mais stockés dans un dossier que vous pouvez spécifier!
la source
Le framework de test Django a des helpers intégrés pour vous aider à tester le service de messagerie .
Exemple tiré de la documentation (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')
la source
send_mail
ils ne peuvent pas être utilisés.mail
?mail.outbox
quandsend_mail
est appelé dans une autre fonction.mail.outbox[0].body
vous montrera l'e-mail envoyé même si lesend_mail
est effectué ailleurs.Si vous êtes dans les tests unitaires, la meilleure solution est d'utiliser le backend en mémoire fourni par django.
EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
Prenez le cas de l'utiliser comme appareil py.test
@pytest.fixture(autouse=True) def email_backend_setup(self, settings): settings.EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
Dans 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
la source
Utiliser MailHog
En outre, il dispose d'un composant appelé Jim , le MailHog Chaos Monkey , qui vous permet de tester l'envoi d'e-mails avec divers problèmes:
En savoir plus ici .
(Contrairement au mailcatcher original, qui a échoué lors de l'envoi d'e-mails avec des emoji, encodés en UTF-8 et qui n'a PAS vraiment été corrigé dans la version actuelle, MailHog fonctionne simplement.)
la source
Pour tout projet qui ne nécessite pas l'envoi de pièces jointes, j'utilise django-mailer , qui a l'avantage que tous les e-mails sortants se retrouvent dans une file d'attente jusqu'à ce que je déclenche leur envoi, et même après qu'ils ont été envoyés, ils sont ensuite enregistrés - tout cela est visible dans l'administrateur, ce qui permet de vérifier rapidement ce que le code d'envoi par e-mail tente de déclencher dans les intertubes.
la source
Django dispose également d'un backend de messagerie en mémoire. Plus de détails dans la documentation sous Backend en mémoire . Ceci est présent dans Django 1.6, je ne sais pas s'il est présent dans quelque chose plus tôt.
la source
Corriger SMTPLib à des fins de test peut aider à tester l'envoi de mails sans les envoyer.
la source
Lier quelques-unes des pièces ici ensemble, 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. Cliquez sur un lien dans la liste pour afficher 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 %}
URL
path("mailcheck/", view=mailcheck, name="mailcheck"),
la source
Pourquoi ne pas démarrer votre propre serveur SMTP très simple en héritant de
smtpd.SMTPServer
etthreading.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 électronique, 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
close()
leasyncore.dispatcher
en appelantsmtp_server.close()
pour terminer la boucle asyncore (arrêter le serveur d'écouter).la source
Si vous avez un serveur TomCat disponible, ou un autre moteur de servlet, alors une approche intéressante est "Post Hoc" qui est un petit serveur qui ressemble à l'application exactement comme un serveur SMTP, mais il comprend une interface utilisateur qui vous permet de visualiser et inspectez les e-mails envoyés. Il est open source et disponible gratuitement.
Trouvez-le sur: Site Post Hoc GitHub
Voir l'article de blog: PostHoc: Test des applications qui envoient des e-mails
la source