2

因此,我使用 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 上)。

4

3 回答 3

1

免责声明:我研究过有问题的产品,请注意此答案可能包含偏见。

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

你得到一个 SMTP 端点(也是无限的测试电子邮件地址,但你使用的是 SMTP,所以不需要这个)。

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

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

最终的测试过程是:-

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

    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');
    
于 2013-10-29T07:51:42.053 回答
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 进行单元测试,而是在对应用程序进行单元测试。

于 2021-02-16T12:21:23.270 回答
0

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

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

它位于 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 天后我再也不需要看到这些电子邮件中的任何一封,因此我不需要对其进行任何清理。

于 2018-02-26T19:50:08.143 回答