测试开发【提测平台】分享11-Python实现邮件发送的两种方法实践

2021-09-26

微信搜索【大奇测试开】,关注这个坚持分享测试开发干货的家伙。

按照开发安排,本篇本应该是关于提测页面的搜索和显示实现,怕相似内容疲劳,这期改下内容顺序,将邮件服务的相关的提前,在之前的产品需求和原型中有一个功能点,就是需要在提测人进行提测,以及测试完成的操作的时候要按照一定的模版发送邮件通知,那我们就研究一下Python flask 后台服务如何实现发送邮件的知识点,最后形成一个邮件工具类,以便在实现提测功能流程中使用。

本篇内容思维导读

内置邮件模块 smtplib

从某度搜索关于python如何发送邮件,给到结果最多的就是 smtplib,资料参差不齐,抑或内容太陈旧,这里通过实践整理总结如下:

首先 了解基本使用

官方 [注解1] 的语法以及教程参考 [注解2]:

# 导入包,python环境默认自有,无需而外安装
import smtplib
from smtplib import SMTP

# 通过给定参数链接服务对象
smtplib.SMTP(host='', port=0, local_hostname=None, [timeout, ]source_address=None)
# 或需要SSL连接
smtplib.SMTP_SSL(host='', port=0, local_hostname=None, keyfile=None, certfile=None, [timeout, ]context=None, source_address=None)

# 支持with方式,否则一般上边的操作需要手动关闭
with smtplib.SMTP("domain.org") as smtp:
     # 配置发送地址和内容等

建立服务对象重要参数说明:

  • host: SMTP 服务器主机。你可以指定主机的ip地址或者域名;

  • port: 需要指定 SMTP 服务使用的端口号,一般情况下 SMTP 端口号为25;

 

Python SMTP 对象使用 sendmail 方法发送邮件,语法如下:

SMTP.sendmail(from_addr, to_addrs, msg, mail_options=(), rcpt_options=())
其中重要参数说明:
  • from_addr: 邮件发送者地址。

  • to_addrs: 字符串列表,邮件发送地址。

  • msg: 发送消息

其次 准备一个可用的邮件发送服务

可以本地,公司邮箱服务,或者是第三方服务,我这里准备的一个测试邮件服务是“企业微信邮箱”,如果你在编码测试过程中没有可用的,可以私信我发我信息,给你添加个我注册测试用的企业微信邮箱,也可以直接使用自己的如网易和QQ邮箱,只不过需要提前在设置开启对应的权限设置,具体配置可以在网上搜索下。用账号密码登录企业邮箱后在设置中找到如图信息,在测试代码中会使用到。

最后 一个完整的例子

直接通过给定HTML样式,实现模版发送,内容文字+链接,这里需要特别注意的是测试“微信企业邮箱”链接需要SSL,所以需要使用 SMTP_SSL 创建链接,而非往上很多例子使用SMTP进行创建,对应代码(源代码在github上)和执行测试内容如下:

查看我自己的邮箱是否真的收到了邮件,可以看到功能正常,上边代码中有一处需要主要是发件人和服务登录人应为为同一个否则会报SMTP 501错误。

但这里有个问题,在邮箱列表里的发件人信息和详细内容里的邮件人信息展示异常,如图:列表显示空白,邮件详细没能正确显示邮箱等。

 

 经过资料查询,需要依赖包的一个工具类进行格式化,分别是email.utils 中的 parseaddr, formataddr,经过优化后代码如图红色标注: 

增加优化逻辑后再发送一个测试邮件,看看结果,列表和详细都正常显示了。

 

本来调研的例子还准备写如何添加附件和图片等,看了麻烦,另外从上边的体验来看smtplib坑不少,然后在解决的问题的过程中发现有文章推荐 yagmail 这个python邮件服务包,感觉眼前一亮,有更好的方法就要学会使用,因为我们处在了一个好的信息共享时代~

简单易用邮件模块 yagmail

yagmail 使用

yagmail 是个外部包,使用前需要安装

# 可能需要外网访问
pip3 install yagmail
# 或从github安装
pip3 install -e git+https://github.com/kootenpv/yagmail#egg=yagmail

从实践的例子来看,发送邮件变得如此简单,不需要多说,直接上代码:

def demo_yagmail():
    # 设置收件人(不需要再设置发件人)
    receivers = ['zyueqi@qq.com', 'daqigroup@mrzcode.com']
    # 邮件主题
    subject = 'Yagmail测试主题'
    # 内容,可以单独定义,然后组成一个内容体
    body = 'Body描述'
    html = '<a href="https://github.com/mrzcode/TestProjectManagement">项目代码点我!</a>'

    # 附件文件绝对路径, 或者 通过open打开直接给io流文件
    path_file = os.path.dirname(os.path.abspath(__file__))+'/source/result.txt'
    attachments =[path_file]

    # 初始化服务对象直接根据参数给定,更多参考SMTP()内部
    server = yagmail.SMTP(host='smtp.exmail.qq.com', port=465, user='daqi@mrzcode.com', password='Test@2021')
    # 发送内容,设置接受人等信息,更多参考SMTP.send()内部
    server.send(to=receivers,
                subject=subject,
                contents=[body, html],
                attachments=attachments)

    server.close()
    print("邮件发送的如此简单!")

if __name__ == "__main__":
    demo_yagmail()

看看发送结果,正常收到,各项均没有异常,完美~ 更多参数说明参考官方 [注释3] 或者在idea 开发工具点跳到源码。

是不是Pyhon 发送邮件变得如此轻松愉快了~,上述的调研实践代码均提交到git项目代码库了,可以前去查看位置:/demoCode/emailDemo.py

邮件工具类编写

调研和实践完了上述“Python 如何实现邮件发送服务” 内容,最终目的是编写个工具类和一些方法来供后续的提测流程使用

1. configs/config.py 添加邮件服务的常量

# config.py
MAIL_HOST = "发送服务的地址"
MAIL_PORT = 25
MAIL_USER = "发送服务邮箱账号"
MAIL_PASSWORD = "发送服务邮箱密码"

2. 创建/utils/emialUtils.py 实现的参数化方法,这里对于模版因为是否也定义在其中,后边实际开发后再优化

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import yagmail
import traceback
from configs import config
'''
receivers 收件人,字符数组['邮件地址']
subject 邮件主题, 字符串
contents 邮件内容,自定义 字符数组
attachments 附件默认为空
'''
def sendEmail(receivers, subject,contents, attachments=[]):

    try:
        # 初始化服务对象直接根据参数给定,更多参考SMTP()内部
        server = yagmail.SMTP(host=config.MAIL_HOST, port=config.MAIL_PORT,
                              user=config.MAIL_USER, password=config.MAIL_PASSWORD)
        # 发送内容,设置接受人等信息,更多参考SMTP.send()内部
        server.send(to=receivers,
                    subject=subject,
                    contents=contents,
                    attachments=attachments)
        server.close()    except Exception:
        print('traceback.format_exc(): {}'.format(traceback.format_exc()))
        return False

    # 无任何异常表示发送成功
    return True

3. 调用测试,工具类直接编写变量调用方法进行测试,查看邮件发送是否OK

if __name__ == "__main__":
    # 测试发送服务
    receivers = ['zyueqi@qq.com', 'daqigroup@mrzcode.com']
    subject = 'DaQi工具类测试'
    body = '简单的问题内容体'
    sendEmail(receivers,subject,[body])

以上本篇内容所有知识点,后边文章会继续进行提测平台功能开发,另外马上也到国庆了,不知道依然不敢太放肆走的你,有什么安排,如果宅家里,学学习,动动手也是不错的选择,也提前透漏下,后边文章更新会上一些新方向,比如性能测试,比如接口自动化测试等等,敬请期待下吧,祝大家2021国庆快乐!

问题集锦

1. smtplib腾讯邮箱链接和收发邮件人显示问题

使用SMTP_SSL()创建链接而非SMTP(),显示问题通过工具类方法parseaddr, formataddr优化发送和接收邮件地址格式 

2. 邮箱服务常见的两个错误提示

  • 账号或密码错误 535, b'Error: authentication failed, system busy')

  • 发送人和登录不一致 501, b'mail from address must be same as authorization user)

【代码更新】

  • 地址:https://github.com/mrzcode/TestProjectManagement

  • TAG:TPMShare11

【注解&参考】

  • [注解1]:https://docs.python.org/zh-cn/3.8/library/smtplib.html#

  • [注解2]:https://www.runoob.com/python/python-email.html

  • [注解3]:https://github.com/kootenpv/yagmail

坚持原创,坚持实践,坚持干货,如果你觉得有用,请点击推荐,也欢迎关注我博客园和微信公众号。