Модульное тестирование Amazon SES в Django: электронные письма не отправляются

Создание модульных тестов для Amazon Simple Email Service (SES) для приложения Django с использованием пакета django-ses

test_mail.py

from django.core import mail
...
def test_send_direct_email(send_ct):
    from_email = settings.SERVER_EMAIL
    to_email = [nt[2] for nt in settings.NOTIFICATIONS_TESTERS]

    starttime = datetime.now()
    connection = mail.get_connection()
    pre_data = get_ses_emails_data()
    _mail_signal_assertion_handler.call_count = 0
    signals.message_sent.connect(_mail_signal_assertion_handler)
    emails = []
    for i in range(send_ct):
        emails.append(
            mail.EmailMessage(
                SUBJECT_EMAIL,
                BODY_EMAIL.format(send_ct=i, server=settings.EMAIL_BACKEND),
                from_email,
                to_email,
                # connection=connection,
            )
        )
    connection.send_messages(emails)

    post_data = get_ses_emails_data()
    assert int(post_data["24hour_sent"]) == int(pre_data["24hour_sent"]) + send_ct
    assert check_aws_ses_sent(assertions={"Sent": send_ct, "StartTime": starttime})
    assert _mail_signal_assertion_handler.call_count == send_ct

settings.py

AWS_DEFAULT_REGION = "ca-central-1"
    try:
        # IAM programmatic user
        AWS_ACCESS_KEY_ID = env("AWS_ACCESS_KEY_ID")
        AWS_SECRET_ACCESS_KEY = env("AWS_SECRET_ACCESS_KEY")
    except KeyError:
        raise ImproperlyConfigured("Missing AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY")

    # =========== EMAIL ==============

    EMAIL_BACKEND = "django_ses.SESBackend"
    DEFAULT_FROM_EMAIL = env("DEFAULT_FROM_EMAIL")  # verified aws ses identity
    SERVER_EMAIL = DEFAULT_FROM_EMAIL

но электронные письма так и не были отправлены (AssertionFrror: False (0 == 1). Служба работает должным образом при запуске в реальном времени на сервере.

Утверждения, которые я использую, являются связью с сигналом message_sent (новым в версии 4.4.0)

from django_ses import signals

def _mail_signal_assertion_handler(sender, message, **kwargs):
    _mail_signal_assertion_handler.call_count += 1
    assert message.subject == SUBJECT_EMAIL
    assert message.body == BODY_EMAIL.format(
        send_ct=_mail_signal_assertion_handler.call_count, server=settings.EMAIL_BACKEND
    )

signals.message_sent.connect(_mail_signal_assertion_handler)

и проверка данных SES с помощью клиентского сеанса boto3:

Я перепробовал все рекомендуемые способы открытия соединения, создания объекта EmailMessage и его отправки.

Я не пробовал создавать экземпляр SESBackend напрямую, а использовал mail.get_connection(), но я не думаю, что мне это нужно.

У меня хорошее соединение с почтовым сервером AWS, согласно https://docs.aws.amazon.com/ses/latest/dg/send-email-smtp-client-command-line.html

Мы будем признательны за любые советы.

Вы уверены, что используете правильные учетные данные SES? Они не совпадают с обычным ключом доступа AWS, а secret - theSES - это дополнительный набор учетных данных.

Например, у меня есть приложение, которому для обработки файлов требуется доступ к S3, и это же приложение также отправляет электронные письма через SES.

Я должен загрузить КЛЮЧ ДОСТУПА и СЕКРЕТНЫЙ КЛЮЧ, чтобы получить разрешения IAM на чтение и запись с S3, но я также должен загрузить другой набор учетных данных (специфичных для SES), которые будут использоваться в качестве имени пользователя и пароля для отправки электронных писем через SES с использованием SMTP.

Я бы зашел в консоль SES, получил учетные данные, специфичные для SES, жестко запрограммировал их в вашем скрипте, описанном выше, и посмотрел, решит ли это проблему (и если да, то выясните, как загрузить их из конфигурационного файла, т.е. не нужно постоянно жестко их кодировать).

< < < 0>>>для < > https://docs.djangoproject.com/en/5.1/topics/testing/tools/#email-services

Если какое-либо из ваших представлений Django отправляет электронную почту, используя функции электронной почты Django, вы, вероятно, не захотите отправлять электронное письмо каждый раз при запуске теста с использованием этого представления. По этой причине программа тестирования Django автоматически перенаправляет все электронные письма, отправленные с помощью Django, в фиктивный почтовый ящик для исходящих сообщений. Это позволяет протестировать все аспекты отправки электронной почты – от количества отправленных сообщений до содержания каждого сообщения – без фактической отправки сообщений.

Программа тестирования выполняет это, прозрачно заменяя обычный сервер электронной почты на сервер тестирования. (Не волнуйтесь – это имеет это не повлияет на других отправителей электронной почты за пределами Django, таких как почтовый сервер вашего компьютера, если он у вас запущен.)

Другими словами, я думаю, что это ожидаемое поведение; вам следует заглянуть в django.core.mail.outbox и просмотреть свои электронные письма.

Я не тестировал это, но, похоже, вы можете сделать что-то вроде:


    @override_settings(EMAIL_BACKEND="django_ses.SESBackend")
    def test_send_direct_email(send_ct):
        ...

чтобы переопределить поведение теста Django по умолчанию и фактически использовать SESBackend в тестах (я не уверен, возможно, вам также потребуется переопределить некоторые другие настройки, но я думаю, что это основная настройка для данного варианта использования)

Вернуться на верх