(9)前面我们已经完成大半部分了。现在呢,还差发送邮件和生成报告。一般测试接口自动化运行结束就要发送邮件给相应的人员
,废话不多说。看代码,邮件发送的代码。中文乱码处理方式还有点问题,附件打开正文内容乱码。之后在修改,欢迎大家指正
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/11/8 16:25
# @Author :xxx
# @Site :
# @File : test11.py
# @Software: PyCharm
##这个文件主要是配置发送邮件的主题、正文等,将测试报告发送并抄送到相关人邮箱的逻辑。
import datetime #格式化时间必须datetime.datetime.now()
import os
import smtplib
import base64
#from email.mime.image import MIMEImage
#from email.header import Header
#from email.header import make_header
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from common.Log import MyLog
from testFile import readConfig, getpathInfo
#from email.mime.application import MIMEApplication
# from testFile.readConfig import ReadConfig
# import configparser
# from testFile.getpathInfo import get_path
A=readConfig.ReadConfig() #实例化对象,用来读取配置文件里的邮箱有关的内容
class SendEmail(object):
def __init__(self,username,passwd,recv,title,content,email_host,port,ssl_port,file=None,ssl=False):
self.username = username # 用户名
self.passwd=passwd # 密码
self.recv=recv # 收件人,多个要传list ['a@qq.com','b@qq.com]
self.title=title # 邮件标题
self.content=content # 邮件正文
self.file=file # 附件路径,如果不在当前目录下,要写绝对路径
self.ssl=ssl # 是否安全链接
self.email_host = email_host
self.port=port
self.ssl_port=ssl_port
self.log = MyLog.get_log()#log实例化
self.logger = self.log.get_logger()
def send_email(self):
msg = MIMEMultipart()
att=[]
if self.file: #处理附件,发送多个附件的处理方式
# 通过循环统计附件个数,便于添加添加附件,这里的file传值传的是list列表
for j in range(len(self.file)):
att.append(j) #把file列表中的附件加入到att列表中
# 通过for循环添加附件
for i in range(len(self.file)):#多个附件发送,len计数从1开始
# print(self.file[i-1].split('/')[-1])
path_file=self.file[i-1] #获取列表中的单个文件路径,list计数从0开始,所以-1,否则超出长度报错
# print(path_file)
file=self.file[i-1].split("/")[-1]#获取附件名称,用/切割后,-1就代表倒着取第一个
# print(file)
try:
f=open(path_file,'rb').read()
except Exception as e:
raise Exception('附件打不开!!!')
else:
att[i]=MIMEText(open(path_file,'rb').read(),'base64','utf-8')
att[i]["Content-Type"] = 'application/octet-stream'
#解决附件中文名乱码问题
new_file_name = '=?utf-8?b?' + base64.b64encode(file.encode()).decode() + '?='
att[i]["Content-Disposition"] = 'attachment; filename="%s"' % (new_file_name)
# att[i]["Content-Type"] = 'application/octet-stream;name="%s"' % make_header([(file,'utf-8')]).encode('utf-8') # 解决附件中文名乱码问题
# att[i]["Content-Disposition"] = 'attachment;filename="%s"'% make_header([(file,'utf-8')]).encode('utf-8')
msg.attach(att[i])
msg.attach(MIMEText(self.content)) # 邮件正文的内容
msg['Subject']=self.title #邮件主题
msg["From"] = self.username ## 发送者账号
msg['To'] = ''.join(self.recv) # 接收者账号列表,这里必须要把多个邮箱拼接为字符串
if self.ssl:
self.smtp=smtplib.SMTP_SSL(self.email_host,port=self.ssl_port)
else:
self.smtp=smtplib.SMTP(self.email_host,port=self.port)
# # 发送邮件服务器的对象
self.smtp.login(self.username,self.passwd)
try:
# self.smtp.sendmail(self.username,self.recv,msg.as_string())
self.smtp.sendmail(self.username, self.recv, msg.as_string())
self.logger.info("The test report has send to developer by email.")
pass
except Exception as e:
self.logger.error(str(e))
print('邮件发送失败!!!',e)
else:
print("邮件发送成功!!!")
self.smtp.quit() #关闭邮箱服务
(10)之前基本都封装好了,这里增加一个log文件。用于输出log。当然也可以不封装,自带的logging模块。直接用简单的logger.info()就好了,我这里封装主要是输出一个log文件。方便定位是运行到哪个文件开始保错的,方便后期维护.....
代码如下(log.py).可以选择自己需要的借鉴哦
import os
from testFile import readConfig
import logging
from datetime import datetime
import threading
from testFile import getpathInfo
localReadConfig = readConfig.ReadConfig()
class Log:
def __init__(self):
global logPath, resultPath, proDir
path = getpathInfo.get_path()#获取teseFile文件路径
proDir=os.path.dirname(path)#获取interface路径,也就是项目路径
# print(proDir)
resultPath = os.path.join(proDir, "result") #把得到的结果result文件放入interface路径下
# print(resultPath)
if not os.path.exists(resultPath):
os.mkdir(resultPath)
logPath = os.path.join(resultPath, str(datetime.now().strftime("%Y%m%d"))) #%Y%m%d%H%M%S
# print(logPath)
if not os.path.exists(logPath):
os.mkdir(logPath)
self.logger = logging.getLogger()
#设置日志级别info以上的
self.logger.setLevel(logging.INFO)
# defined handler,输出日志文件名为output.log,FileHandler用于写入日志文件
handler = logging.FileHandler(os.path.join(logPath, "output.log"))
# defined formatter,按照年月日时分秒输出格式,formatter格式器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
#给handler添加formatter
handler.setFormatter(formatter)
# 给logger添加handler,也就是handler这个规则, 把文件日志对象添加到日志处理器logger中
self.logger.addHandler(handler)
def get_logger(self):
"""
get logger
:return:
"""
return self.logger
def build_start_line(self, case_no):
"""
write start line
:return:
"""
self.logger.info("--------" + case_no + " START--------")
def build_end_line(self, case_no):
"""
write end line
:return:
"""
self.logger.info("--------" + case_no + " END--------")
def build_case_line(self, case_name, code, msg):
"""
write test case line
:param case_name:
:param code:
:param msg:
:return:
"""
self.logger.info(case_name+" - Code:"+code+" - msg:"+msg)
def get_report_path(self):
"""
get report file path
:return:
"""
report_path = os.path.join(logPath, "report.html")
return report_path
def get_result_path(self):
"""
get test result path
:return:
"""
return logPath
def write_result(self, result):
"""
:param result:
:return:
"""
result_path = os.path.join(logPath, "report.txt")
fb = open(result_path, "wb")
try:
fb.write(result)
except FileNotFoundError as ex:
logger.error(str(ex))
class MyLog:
log = None
mutex = threading.Lock()
def __init__(self):
pass
@staticmethod
def get_log():
if MyLog.log is None:
MyLog.mutex.acquire()
MyLog.log = Log()
MyLog.mutex.release()
return MyLog.log
if __name__ == "__main__":
log = MyLog.get_log()
logger = log.get_logger()
logger.debug("test debug")
logger.info("test info")