Я новичок в Python и движке приложений.
У меня есть этот код, который отправляет электронное письмо на основе параметров запроса после некоторой логики аутентификации. в моих модульных тестах (я использую GAEUnit), как я могу подтвердить, что электронное письмо с определенным содержанием было отправлено? - т.е. как мне издеваться над электронной почтой с помощью фальшивой электронной почты, чтобы убедиться, что отправка была вызвана?
class EmailHandler(webapp.RequestHandler):
def bad_input(self):
self.response.set_status(400)
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write("<html><body>bad input </body></html>")
def get(self):
to_addr = self.request.get("to")
subj = self.request.get("subject")
msg = self.request.get("body")
if not mail.is_email_valid(to_addr):
# Return an error message...
# self.bad_input()
pass
# authenticate here
message = mail.EmailMessage()
message.sender = "[email protected]"
message.to = to_addr
message.subject = subj
message.body = msg
message.send()
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write("<html><body>success!</body></html>")
И юнит-тесты,
import unittest
from webtest import TestApp
from google.appengine.ext import webapp
from email import EmailHandler
class SendingEmails(unittest.TestCase):
def setUp(self):
self.application = webapp.WSGIApplication([('/', EmailHandler)], debug=True)
def test_success(self):
app = TestApp(self.application)
response = app.get('http://localhost:8080/[email protected]&body=blah_blah_blah&subject=mySubject')
self.assertEqual('200 OK', response.status)
self.assertTrue('success' in response)
# somehow, assert email was sent






Очень короткое введение содержит PyPI: MiniMock 1.0. Это очень маленькая библиотека для создания макетов.
Удачи!
Вы также можете переопределить метод _GenerateLog в mail_stub внутри AppEngine.
Вот родительский класс TestCase, который я использую в качестве миксина при тестировании отправки электронных писем:
from google.appengine.api import apiproxy_stub_map, mail_stub
__all__ = ['MailTestCase']
class MailTestCase(object):
def setUp(self):
super(MailTestCase, self).setUp()
self.set_mail_stub()
self.clear_sent_messages()
def set_mail_stub(self):
test_case = self
class MailStub(mail_stub.MailServiceStub):
def _GenerateLog(self, method, message, log, *args, **kwargs):
test_case._sent_messages.append(message)
return super(MailStub, self)._GenerateLog(method, message, log, *args, **kwargs)
if 'mail' in apiproxy_stub_map.apiproxy._APIProxyStubMap__stub_map:
del apiproxy_stub_map.apiproxy._APIProxyStubMap__stub_map['mail']
apiproxy_stub_map.apiproxy.RegisterStub('mail', MailStub())
def clear_sent_messages(self):
self._sent_messages = []
def get_sent_messages(self):
return self._sent_messages
def assertEmailSent(self, to=None, sender=None, subject=None, body=None):
for message in self.get_sent_messages():
if to and to not in message.to_list(): continue
if sender and sender != message.sender(): continue
if subject and subject != message.subject(): continue
if body and body not in message.textbody(): continue
return
failure_message = "Expected e-mail message sent."
args = []
if to: args.append('To: %s' % to)
if sender: args.append('From: %s' % sender)
if subject: args.append('Subject: %s' % subject)
if body: args.append('Body (contains): %s' % body)
if args:
failure_message += ' Arguments expected: ' + ', '.join(args)
self.fail(failure_message)
После этого примерный тестовый пример может выглядеть так:
import unittest, MailTestCase
class MyTestCase(unittest.TestCase, MailTestCase):
def test_email_sent(self):
send_email_to('[email protected]') # Some method that would send an e-mail.
self.assertEmailSent(to='[email protected]')
self.assertEqual(len(self.get_sent_messages()), 1)
Посмотрите gae-testbed.googlecode.com, который предоставляет базовые классы, которые делают именно это.
Этот проект выглядит многообещающим. Я надеюсь, что вы уже можете предоставить учебники, особенно те, которые предназначены для тестирования Mail API.
Я использовал тестовый стенд GAE от jgeewax с GAEUnit. Мне было проще использовать GAEUnit вместо NoseGAE, поскольку у меня уже был GAEUnit. Вот шаги:
Добавьте GAEUnit в свое приложение
gaeunit.py в корневую папку вашего приложения.app.yaml непосредственно под строкой с надписью handlers::Код:
- url: /test.*
script: gaeunit.py
(Необязательно) В папке, извлеченной из архива, есть папка с именем sample_app, внутри которой находится измененная версия модуля webtest. Скопируйте модуль webtest (всю папку, содержащую debugapp.py и __init__.py) в корень вашего приложения.
Добавьте стенд GAE в GAEUnit:
gaetestbed (это папка с именем «gaetestbed»). Скопируйте модуль в корень вашего приложения.test_mailer.py.test_mailer.py следующие строки:Код:
import unittest
from gaetestbed import MailTestCase
class MyTestCase(MailTestCase, unittest.TestCase):
def test_email_sent(self):
send_email_to('[email protected]') # Some method that sends e-mail...
self.assertEmailSent(to='[email protected]')
self.assertEqual(len(self.get_sent_messages()), 1)
Запустите свой сервер и перейдите к http://localhost:8080/test. Вы должны заметить, что (дополнительный) тест 1/1 был запущен с http://localhost:8080/test.
Источник: Использование тестовой системы GAE с GAEUnit: проверка того, что письмо было отправлено
Просто используйте следующее, чтобы получать все сообщения, отправленные после активации почтовой корешки.
from google.appengine.api import apiproxy_stub_map
sent_messages = apiproxy_stub_map.apiproxy._APIProxyStubMap__stub_map['mail'].get_sent_messages()
У Google есть действительно простой способ сделать это в документация.
Вы создаете тестовую станцию и почтовую заглушку в своей настройке следующим образом:
self.testbed = testbed.Testbed()
self.testbed.activate()
self.testbed.init_mail_stub()
self.mail_stub = self.testbed.get_stub(testbed.MAIL_SERVICE_NAME)
Запустите свой метод, а затем проверьте его так:
messages = self.mail_stub.get_sent_messages(to='[email protected]')
self.assertEqual(1, len(messages))
self.assertEqual('[email protected]', messages[0].to)
Спасибо за ссылку на GAEUnit. Я искал что-то подобное.