Тестирование отправки электронной почты - PullRequest
71 голосов
/ 16 сентября 2010

Какие-нибудь советы по тестированию отправки электронной почты? Помимо создания учетной записи gmail , особенно для получения этих писем?

Я хотел бы, может быть, сохранять электронные письма локально, в папке по мере их отправки.

Ответы [ 14 ]

163 голосов
/ 16 сентября 2010

В тестовой среде 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')
35 голосов
/ 16 сентября 2010

Вы можете использовать файловый бэкэнд для отправки электронных писем , который является очень удобным решением для разработки и тестирования;электронные письма не отправляются, но хранятся в папке, которую вы можете указать!

12 голосов
/ 25 апреля 2016

Если вы занимаетесь модульным тестированием, лучшее решение - использовать Внутренний бэкэнд , предоставленный 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
5 голосов
/ 16 сентября 2010

Для любого проекта, который не требует отправки вложений, я использую django-mailer , что дает преимущество всех исходящих электронных писем, заканчивающихся в очереди, пока я не инициирую их отправку, и даже после того, как они 'После того как вы были отправлены, они затем регистрируются - все это видно в Admin, что позволяет легко проверить, какой код электронной почты вы пытаетесь запустить в промежутках.

4 голосов
/ 26 августа 2016

Использование MailHog

Вдохновленный MailCatcher, проще в установке.

Построен с Go - MailHog работает без установки на несколькихплатформы.

Кроме того, он имеет компонент под названием Jim , MailHog Chaos Monkey , который позволяет тестировать отправку писем с различными проблемами:

Что может сделать Джим?

  • Отклонить соединения
  • Ограничить скорость соединения
  • Отклонить аутентификацию
  • Отклонить отправителей
  • Отклонить получателей

Подробнее об этом здесь .

(В отличие от оригинального mailcatcher, который мне не удался при отправке электронных писем с эмодзи, закодированным в UTF-8 , и в текущем выпуске это НЕ БЫЛО действительно исправлено, MailHog просто работает.)

4 голосов
/ 26 июня 2014

Django также имеет почтовый сервер в памяти. Более подробную информацию можно найти в документации по Бэкэнд в памяти . Это присутствует в Django 1.6, но я не уверен, присутствует ли оно ранее.

3 голосов
/ 16 сентября 2010

Исправление SMTPLib для целей тестирования может помочь проверить отправку писем без их отправки.

1 голос
/ 18 сентября 2016

Почему бы не запустить свой собственный действительно простой SMTP-сервер путем наследования от smtpd.SMTPServer и 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)

Просто запомните close() asyncore.dispatcher путем вызова smtp_server.close(), чтобы завершить цикл асинхронности (остановить сервер от прослушивания).

1 голос
/ 14 мая 2014

Использование файлового бэкэнда работает хорошо, но я нахожу немного громоздким копаться в файловой системе для просмотра электронных писем. Вы можете использовать mailcatcher, https://github.com/sj26/mailcatcher, для захвата писем и отображения их в веб-интерфейсе.

Чтобы использовать mailcatcher с Django, вам нужно добавить что-то вроде следующего в ваши настройки.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
0 голосов
/ 18 мая 2019

Связывая несколько частей здесь, вот простая установка, основанная на 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 %}

urls

path("mailcheck/", view=mailcheck, name="mailcheck"),
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...