【问题标题】:Testing python smtp email service测试 python smtp 电子邮件服务
【发布时间】:2013-10-28 18:47:46
【问题描述】:

所以我使用 smtplib 编写了一个简单的电子邮件服务,以便在用户首次登录时发送欢迎电子邮件。我想知道测试我的代码的最佳方法是什么。

def send_email(nickname, email):
    msg = MIMEMultipart('alternative')

    config = read_config_file(MAIL_CONFIG_PATH)
    sen = config.get('gmail_credentials', 'email')
    pwd = config.get('gmail_credentials', 'password')

    server = None
    try:
        server = smtplib.SMTP('smtp.gmail.com', 587) 
        server.ehlo()
        server.starttls()
        server.login(sen, pwd)
        server.sendmail(sen, [email], msg.as_string())
        return 'Sent!'

    finally:
        if server:
        server.quit()

我发现你可以使用假的 smtp 服务器:

sudo python -m smtpd -n -c DebuggingServer localhost:25

但我仍然不确定我应该如何在我的代码中实现这样的东西。如何更改我的 API 以便它在测试期间运行 SMTP 服务器并连接到 GMAIL 服务器以进行实际调用?是否有初始化脚本可以在我们的服务器上运行 SMTP 服务器(这将部署在 AWS EC2 上)。

【问题讨论】:

    标签: python email amazon-ec2 smtplib


    【解决方案1】:

    对于遇到同样问题的老票的任何人,我想用标准库编写集成测试,所以上述解决方案对我不起作用。在单元测试代码中本地设置调试服务器也有点棘手,据称不支持 starttls。最后我选择了这个;

    import smtplib
    from unittest import TestCase
    
    class TestSMTP(TestCase)
    
        ...
        setup etc.
    
        def test_smtp_connection(self):
            # connect to actual host on actual port
            smtp = smtp.SMTP(host, port)
            smtp.starttls()
    
            # check we have an open socket
            self.assertIsNotNone(smtp.sock)
    
            # run a no-operation, which is basically a server-side pass-through
            self.assertEqual(smtp.noop(), (250, '2.0.0 OK'))
    
            # assert disconnected
            self.assertEqual(smtp.quit(), (221, '2.0.0 Service closing transmission channel'))
            self.assertIsNone(smtp.sock)
    

    请注意,这些是集成测试,您需要做的就是验证您的电子邮件服务器是否正常工作。其他所有事情都可以通过模拟smtp.SMTP 并捕获传递给sendmail 的任何内容并验证那里的内容来完成。您不是在对 smtp 进行单元测试,而是在对应用程序进行单元测试。

    【讨论】:

      【解决方案2】:

      免责声明:我曾在相关产品上工作,请注意此答案可能包含偏见。

      我与人共同创建了一个名为 Mailosaur 的托管服务,它允许开发人员(包括我们在内)在真实环境中(即通过网络,使用 SMTP)测试这种过程。

      您获得了一个 SMTP 端点(也是无限的测试电子邮件地址,但您使用的是 SMTP,因此不需要它)。

      该服务然后将电子邮件转换为 JSON representation,您可以通过 HTTP API 获取。

      为了使查询更容易使用,可以使用客户端绑定(可用于Java、.NET 和 Ruby),但您可以使用常规 curl 或任何其他 HTTP 客户端(或联系我们,我们会很高兴组装一个 Python 客户端)。

      最终的测试过程是:-

      1. 通过 SMTP 向smtp.mailosaur.in 发送电子邮件(无需更改发件人/收件人地址)
      2. 查询 API:

        curl https://mailosaur.com/v2/emails?mailbox={mailbox}&key={api_key}
        
      3. 做你的常规断言(伪代码):

        assert.equal(3, email.attachments.length, 'Expected 3 attachments');
        assert.contains('https://verify-url', email.html.links, 'Expected link to verification url');
        

      【讨论】:

        【解决方案3】:

        我遇到了同样的问题:发送电子邮件的应用程序,我想检查它们是否正确向一群真实的人发送各种形式不完整的电子邮件。

        我使用 PostHoc,它使用 SMTP 接收电子邮件,但随后仅显示在网络浏览器中发送的电子邮件。

        它在 GitHub 上:https://github.com/agilepro/posthoc

        这是描述它的博客文章:https://agiletribe.purplehillsbooks.com/2017/07/24/posthoc-testing-apps-that-send-email/

        我不运行真正的 SMTP 服务器的原因是这些服务器旨在实际查找邮件并将邮件传递给收件人。我想用真实的电子邮件地址和真实的邮件列表测试应用程序。我想看看真实情况是否可以处理,并且我想验证发送的每封电子邮件看起来都像它应该的样子。我想要这一切,但我想确定实际上没有任何电子邮件被发送。

        多年来,我在将电子邮件重定向到不同地址的应用程序中进行了切换,我可以在那里看到电子邮件。但这仍然是个问题,因为应用程序运行在与生产环境不同的模式下。使用 PostHoc,应用程序完全像在生产中一样运行,我仍然可以安全地看到所有发送的电子邮件。

        PostHoc 需要 TomCat 来运行它,但没有别的。

        我喜欢它在 5 天后自动删除所有旧邮件的方式。 5 天后我再也不需要看到这些电子邮件中的任何一封,因此我不需要对其进行任何清理。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-10-28
          • 2012-07-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-17
          • 1970-01-01
          相关资源
          最近更新 更多