Skip to content

Instantly share code, notes, and snippets.

@devsli
Last active March 13, 2016 14:26
Show Gist options
  • Save devsli/acce0c8508327ae57340 to your computer and use it in GitHub Desktop.
Save devsli/acce0c8508327ae57340 to your computer and use it in GitHub Desktop.
py.test SMTPd fixture

Secure SMTPd py.test fixture

Test outgoing messages of your app.

It's possible to replace secure-smtpd with default smtpd if AUTH is not forced by your application.

import pytest
import secure_smtpd
from multiprocessing import Queue, Process
@pytest.yield_fixture(scope='module')
def SmtpServer():
"""
Return dummy SMTP server to check outgoing messages.
The ``multiprocessing.Queue`` of ``tuple`` objects is yelded
Sent queue example usage::
def test_get_msg(SmtpServer):
addr, sender, recipients, body = SmtpServer.get()
Note that execution will be freezed until something is retrieved
from ``sent`` queue. You can use ``Queue.get_nowait()`` or
``timeout`` parameter to avoid such behavior.
Read more about `multiprocessing <https://docs.python.org/2/library/multiprocessing.html>`_
"""
sent = Queue()
port = 1125
host = 'localhost'
class _TestSmtpServer(secure_smtpd.SMTPServer):
def __init__(self, sent_queue, *args, **kwargs):
secure_smtpd.SMTPServer.__init__(self, *args, **kwargs)
self.sent_queue = sent_queue
def process_message(self, *args):
self.sent_queue.put(args)
class DufferValidator(object):
def validate(self, user, password):
return True
def run(host, port, sent_queue):
s = _TestSmtpServer(sent_queue, ('0.0.0.0', port), None,
require_authentication=True,
credential_validator=DufferValidator())
s.run()
srv_proc = Process(target=run, args=(host, port, sent))
srv_proc.start()
yield sent
srv_proc.terminate()
import pytest
import smtplib
def test_send(SmtpServer):
sender = smtplib.SMTP()
sender.connect('localhost', 1125)
sender.login('john.doe44', 'correct horse battery staple')
sender_email = 'info@company.example'
recipient_email = 'customer@gmail.example'
text = 'Hello! Here your invoice.'
sender.sendmail(sender_email, recipient_email, text)
addr, sender, recipients, body = SmtpServer.get(timeout=10)
assert sender_email == sender
assert recipient_email == recipients.pop()
assert body == text
assert SmtpServer.empty() == True
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment