简介
上一篇, 我们虽然已经将生成的最新的测试报告发出去了, 但是 MIMEText 只能发送正文, 无法带附件, 因此我还需要继续改造我们的代码, 实现可以发送带有附件的邮件. 发送带附件的需要导入另外一个模块 MIMEMultipart. 还有就是测
试负责人不止一个人, 需要将测试报告发给多个人, 也就是多个收件人. 这篇主要是围绕这两个主题进行讲解的.
大致思路
(一) 带有附件发送邮件
1, 导入模块 MIMEMultipart
from email.mime.multipart import MIMEMultipart
2, 先读取要发送文件的内容, file_new 是测试报告路径的参数名
3, 下图红色框框 file_name 参数是发送的附件重新命名
4,file_new 是测试报告路径的参数名, 发送邮件是将其传入
5, 运行结果
6, 查看收件箱
(二) 发送给多个收件人
上面都是发给一个收件人, 那么如何一次发给多个收件人呢? 其实是非常简单的, 只需改两个小地方, 即可, 从这里就可以看出 python 的强大之处.
1, 源码
2, 仿造修改
3, 运行结果
4, 收件箱查看
公司邮箱
QQ 邮箱
参考代码
- # coding=utf-8
- #1. 先设置编码, utf-8 可支持中英文, 如上, 一般放在第一行
- #2. 注释: 包括记录创建时间, 创建人, 项目名称.
- '''
- Created on 2019-5-7
- @author: 北京 - 宏哥
- Project: 学习和使用将测试报告通过邮件发出去且邮件带有附件
- '''
- #3. 导入 unittest 模块
- import unittest
- import os
- from email.mime.text import MIMEText
- from email.mime.multipart import MIMEMultipart
- from email.header import Header
- import smtplib
- #4. 编写测试用例和断言
- def all_case():
- # 待执行用例的目录
- #case_dir = "C:\\Users\\DELL\\PycharmProjects\\honggetest\\case"
- case_dir = os.path.join(os.getcwd(), "case")
- testcase = unittest.TestSuite()
- discover = unittest.defaultTestLoader.discover(case_dir,
- pattern="test*.py",
- top_level_dir=None)
- # #discover 方法筛选出用例, 循环添加到测试套件中
- # for test_suit in discover:
- # for test_case in test_suit:
- # #添加用力到 testcase
- # testcase.addTests(test_case)
- # print(testcase)
- testcase.addTests(discover) # 直接加载 discover 可以兼容 python2 和 3
- print(testcase)
- return testcase
- # ============== 定义发送邮件 ==========
- def send_mail(file_new):
- #-----------1. 跟发件相关的参数 ------
- smtpserver = 'smtp.mxhichina.com' #发件服务器
- port = 0 #端口
- username = 'nXXX@ceXx.cn' #发件箱用户名
- password = 'ceXXx@@123' #发件箱密码
- sender = 'XXly@cedex.cn' #发件人邮箱
- receiver = ['hongge@com.cn','1918991791@qq.com'] #收件人邮箱
- # ----------2. 编辑邮件的内容 ------
- #读文件
- f = open(file_new, 'rb')
- mail_body = f.read()
- f.close()
- # 邮件正文是 MIMEText
- body = MIMEText(mail_body, 'html', 'utf-8')
- # 邮件对象
- msg = MIMEMultipart()
- msg['Subject'] = Header("自动化测试报告", 'utf-8').encode()# 主题
- msg['From'] = Header(u'测试机 <%s>'%sender) #发件人
- msg['To'] = Header(u'测试负责人 <%s>'%receiver) #收件人
- msg['To'] = ';'.join(receiver)
- msg['date'] = time.strftime("%a,%d %b %Y %H:%M:%S %z")
- msg.attach(body)
- # 附件
- att = MIMEText(mail_body, "base64", "utf-8")
- att["Content-Type"] = "application/octet-stream"
- att["Content-Disposition"] = 'attachment; filename="test_report.html"'
- msg.attach(att)
- # ----------3. 发送邮件 ------
- try:
- smtp = smtplib.SMTP()
- smtp.connect(smtpserver) # 连服务器
- smtp.login(sender, password)
- except:
- smtp = smtplib.SMTP_SSL(smtpserver, port)
- smtp.login(sender, password) # 登录
- smtp.sendmail(sender, receiver, msg.as_string()) # 发送
- smtp.quit()
- # #发送邮件
- # smtp = smtplib.SMTP()
- # smtp.connect('smtp.mxhichina.com') # 邮箱服务器
- # smtp.login(username, password) # 登录邮箱
- # smtp.sendmail(sender, receiver, msg.as_string()) # 发送者和接收者
- # smtp.quit()
- print("邮件已发出! 注意查收.")
- # ====== 查找测试目录, 找到最新生成的测试报告文件 ======
- def new_report(test_report):
- lists = os.listdir(test_report) # 列出目录的下所有文件和文件夹保存到 lists
- lists.sort(key=lambda fn: os.path.getmtime(test_report + "\\" + fn)) # 按时间排序
- file_new = os.path.join(test_report, lists[-1]) # 获取最新的文件保存到 file_new
- print(file_new)
- return file_new
- if __name__ == "__main__":
- # 返回实例
- runner = unittest.TextTestRunner()
- #导入第三方模块 HTMLTestRunner
- import HTMLTestReportCN
- import time
- # 获取当前时间, 这样便于下面的使用.
- now = time.strftime("%Y-%m-%M-%H_%M_%S", time.localtime(time.time()))
- #保存生成报告的路径
- report_path = "C:\\Users\\DELL\\PycharmProjects\\honggetest\\report\\"+now+"_result.HTML"
- fp = open(report_path,'wb')
- runner = HTMLTestReportCN.HTMLTestRunner(stream=fp,
- title=u"这是我的自动化测试用例",
- description=u"用例执行情况",
- verbosity = 2
- )
- # run 所有用例
- runner.run(all_case())
- #关闭文件, 记住用 open() 打开文件后一定要记得关闭它, 否则会占用系统的可打开文件句柄数.
- fp.close()
- #测试报告文件夹
- test_path = "C:\\Users\\DELL\\PycharmProjects\\honggetest\\report\\"
- new_report = new_report(test_path)
- send_mail(new_report) # 发送测试报告
小结
1, 第二处我注释掉也可以发出去, 两个收件人可以收到邮件, 但是如果这样的话, 公司邮箱收件人只显示一个收件人, QQ 邮箱显示两个收件人.
公司邮箱 PS: 如果将红色框上边的注释掉, 下边的不注释, 就可以看到两个收件人的邮箱
以下是个人愚见, 如果不对请指出
- from email.mime.text import MIMEText
- from email.mime.multipart import MIMEMultipart
- import smtplib
以上是导入的包, 通过 email 和 smtplib 实现发邮件.
折腾好久, 发现是这样: email 中收件人和 sendmail 中的收件人是没啥联系的.
- mail_to = ['test1@exp.com','test2@exp.com']
- server = smtplib.SMTP()
- server.connect()
- server.sendmail(mail_from, mail_to, msg.as_string())
- server.quit()
- mail_to = 'test1@exp.com,test2@exp.com'
- msg = MIMEMultipart('related') ## 采用 related 定义内嵌资源的邮件体
- msgtext = MIMEText(content,_subtype='html',_charset='utf-8') ##_subtype 有 plain,HTML 等格式, 避免使用错误
- msg['Subject'] = subject
- msg['From'] = mail_from
- msg['To'] =mail_to
sendmail 中收件人, 它的格式应该为 list. 这个为实际的收件人地址.
而 msg['To'] 格式是字符串 (str). 这个只是为了邮件中打印出来而已.
sendmail 查源码, python/lib/smtplib.py 大概 690 行左右, 或者搜索 tolist.
2, 在使用 python 添加附件发送时报错: Cannot attach additional subparts to non-multipart/*
查询得知, 错误的原因在于缺少这行代码:
msg = MIMEMultipart()
将这行加上: msg = MIMEMultipart() 即可
邮件收不到的几种原因
1,Subject 和正文内容不要用 hello,hehe,test 等单词
2,from(发件人) 和 to(收件人) 不要为空,(要不然会被认为是垃圾邮件)
3, 找不到的话, 先看下垃圾信箱, 是不是跑到垃圾箱了
4, 如果前几次可以收到, 后来收不到了, 需改下 subject 内容 (因为每次都是一个 subject, 系统也会拒收的, 把 subject 内容设置为动态的是最好的)
5, 部分邮箱是 ssl 加密了的, 所以无法发送, 如: qq 邮箱 (用授权码去登录)
6, 要是按照上面的步骤来报错了, 说明代码抄错了, 多检查几次.
来源: https://www.cnblogs.com/du-hong/p/10819199.html