python3 unittest+request+HTMLTestRunner接口自动化(四)

(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")

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值