Đang thử nghiệm gửi email trong Django [đã đóng]


90

Tôi cần kiểm tra xem ứng dụng Django của mình có gửi e-mail với nội dung chính xác hay không. Tôi không muốn dựa vào các hệ thống bên ngoài (như tài khoản gmail đặc biệt ), vì tôi không thử nghiệm dịch vụ e-mail thực tế ...

Tôi muốn, có thể, lưu trữ cục bộ các email, trong một thư mục khi chúng được gửi đi. Bất kỳ lời khuyên về cách đạt được nó?


Người điều hành: vui lòng khóa câu hỏi này. Rất nhiều thư rác được thêm vào trong các câu trả lời, đề xuất các giải pháp phức tạp đến mức nực cười chỉ để quảng bá các dịch vụ bên ngoài.
nemesisdesign

Câu trả lời:


43

Bạn có thể sử dụng phần phụ trợ tệp để gửi email , đây là một giải pháp rất tiện dụng để phát triển và thử nghiệm; email không được gửi đi nhưng được lưu trữ trong một thư mục mà bạn có thể chỉ định!


1
Thông tin thêm về phụ trợ email: docs.djangoproject.com/en/dev/topics/email/#email-backends . Đôi khi ngay cả phần phụ trợ bảng điều khiển đơn giản cũng đủ ..
Jeewes

1
Nhưng có cách nào để truy cập email được tạo trong quá trình thử nghiệm (tự động) không?
Overdrivr

182

Khung kiểm tra Django có một số trình trợ giúp được tích hợp sẵn để hỗ trợ bạn kiểm tra dịch vụ e-mail .

Ví dụ từ tài liệu (phiên bản ngắn):

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')

3
+1 Câu trả lời hay. Nhưng nó không hữu ích cho những trường hợp phức tạp, khi send_mailkhông thể sử dụng được.
santiagobasulto


2
Bạn sẽ thực hiện điều này như thế nào nếu đang thử nghiệm một hàm gọi send_mail và do đó bạn không thể truy cập mail?
Matt D

3
@MatthewDrill bạn vẫn có thể truy cập mail.outboxkhi send_mailđược gọi trong một hàm khác.
pymarco

2
@pymarco Nếu bạn nhập thư từ lõi, mail.outbox[0].bodysẽ hiển thị cho bạn email được gửi ngay cả khi email send_mailđược thực hiện ở nơi khác.
Rob

17

Nếu bạn muốn kiểm tra đơn vị, giải pháp tốt nhất là sử dụng chương trình phụ trợ Trong bộ nhớ do django cung cấp.

EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'

Lấy trường hợp sử dụng nó như một vật cố định py.test

@pytest.fixture(autouse=True)
def email_backend_setup(self, settings):
    settings.EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'  

Trong mỗi thử nghiệm, mail.outboxthiết bị được thiết lập lại với máy chủ, do đó không có tác dụng phụ giữa các thử nghiệm.

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

8

Sử dụng MailHog

Lấy cảm hứng từ MailCatcher, dễ cài đặt hơn.

Được xây dựng với Go - MailHog chạy mà không cần cài đặt trên nhiều nền tảng.


Ngoài ra, nó có một thành phần được gọi là Jim , MailHog Chaos Monkey , cho phép bạn kiểm tra việc gửi email với các sự cố khác nhau đang xảy ra:

Jim có thể làm gì?

  • Từ chối kết nối
  • Tỷ lệ kết nối giới hạn
  • Từ chối xác thực
  • Từ chối người gửi
  • Từ chối người nhận

Đọc thêm về nó ở đây .


(Không giống như mailcatcher ban đầu, lỗi với tôi khi gửi email có biểu tượng cảm xúc, được mã hóa bằng UTF-8 và nó KHÔNG thực sự được sửa trong bản phát hành hiện tại, MailHog chỉ hoạt động.)


5

Đối với bất kỳ dự án nào không yêu cầu gửi tệp đính kèm, tôi sử dụng django-mailer , có lợi ích là tất cả các email gửi đi kết thúc trong một hàng đợi cho đến khi tôi kích hoạt gửi chúng và ngay cả sau khi chúng đã được gửi đi, chúng sẽ được ghi lại - tất cả đều hiển thị trong Quản trị viên, giúp bạn dễ dàng nhanh chóng kiểm tra xem mã gửi email của bạn đang cố gắng truyền tải nội dung gì vào các kênh.


Hơn nữa, các đối tượng Thư được tạo bởi django-mailer có nghĩa là bạn cũng có thể thúc đẩy chúng (và kiểm tra nội dung của chúng) trong các bài kiểm tra đơn vị (Tôi biết rằng có hỗ trợ hộp thư đi trong bộ thử nghiệm cho một hộp thư giả, nhưng sử dụng django-mailer thì không 't gửi mail trừ khi lệnh quản lý gửi nó, có nghĩa là bạn không thể sử dụng đối tượng mailbox)
Steve Jalim

Cập nhật, có tuổi từ câu trả lời ban đầu của tôi: github.com/SmileyChris/django-mailer-2 cũng không hỗ trợ tệp đính kèm
Steve Jalim

4

Django cũng có chương trình phụ trợ email trong bộ nhớ. Thông tin chi tiết khác trong tài liệu trong Phần phụ trợ trong bộ nhớ . Điều này hiện diện trong Django 1.6 không chắc chắn nếu nó có trong bất kỳ thứ gì trước đó.



1

Gắn một vài mảnh ở đây lại với nhau, đây là một thiết lập đơn giản dựa trên filebased.EmailBackend. Điều này hiển thị chế độ xem danh sách liên kết đến các tệp nhật ký riêng lẻ, các tệp này có tên tệp được đánh dấu thời gian thuận tiện. Nhấp vào một liên kết trong danh sách sẽ hiển thị thông báo đó trong trình duyệt (thô):

Cài đặt

EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
EMAIL_FILE_PATH = f"{MEDIA_ROOT}/email_out"

Lượt xem

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})

Bản mẫu

{% 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"),

0

Tại sao không bắt đầu Máy chủ SMTP thực sự đơn giản của riêng bạn bằng cách kế thừa từ smtpd.SMTPServerthreading.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 được gọi bất cứ khi nào Máy chủ SMTP của bạn nhận được yêu cầu thư, bạn có thể làm bất cứ điều gì bạn muốn ở đó.

Trong mã thử nghiệm, hãy làm như sau:

smtp_server = TestingSMTPServer()
smtp_server.start()
do_thing_that_would_send_a_mail()
smtp_server.close()
self.assertIn(b'hello', smtp_server.received_data)

Chỉ cần nhớ tới close()những asyncore.dispatcherbằng cách gọi smtp_server.close()để kết thúc vòng lặp asyncore (ngăn chặn các máy chủ từ nghe).


0

Nếu bạn có sẵn máy chủ TomCat hoặc công cụ servlet khác, thì một cách tiếp cận hay là "Post Hoc", đây là một máy chủ nhỏ trông ứng dụng giống hệt như máy chủ SMTP, nhưng nó bao gồm giao diện người dùng cho phép bạn xem và kiểm tra các thư email đã được gửi đi. Nó là mã nguồn mở và có sẵn miễn phí.

Tìm nó tại: Đăng Hoc GitHub Site

Xem bài đăng trên blog: PostHoc: Thử nghiệm các ứng dụng gửi Email

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.