• python学习(三十四)第一个框架


    1、自动化三种方式:

    1)数据驱动
    根据数据去测试
    2)代码驱动
    测试用例都是写代码来测试
    3)关键字驱动
    UI自动化,依靠一些关键字执行
    方法都是封装好了,根据关键字执行相应的方法

    2、数据驱动测试实例

    自动读取用例信息,调用接口,把返回结果和是否通过写入Excel,并将测试结果发送到邮箱

    从该需求中整理出需要做的步骤如下:

    1、获取用例
    2、调用接口
    3、校验结果
    4、发送测试报告
    5、异常处理
    6、日志

    1)因为在进行的每一步都会用到写日志,所以先说日志模块的代码怎么写。

    新建文件夹ATP,并在该文件夹下创建如图所示几个文件夹

     

    在lib面下新建一个python文件,名为log.py,在这个文件里面把之前我们封装的日志模块写进来

    import logging,os
    from logging import handlers
    from conf import setting
    class MyLogger():
        def __init__(self,file_name,level='info',backCount=5,when='D'):
            logger = logging.getLogger()  # 先实例化一个logger对象,先创建一个办公室
            logger.setLevel(self.get_level(level))  # 设置日志的级别的人
            cl = logging.StreamHandler()  # 负责往控制台输出的人
            bl = handlers.TimedRotatingFileHandler(filename=file_name, when=when, interval=1, backupCount=backCount, encoding='utf-8')
            fmt = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')
            cl.setFormatter(fmt)  # 设置控制台输出的日志格式
            bl.setFormatter(fmt)  # 设置文件里面写入的日志格式
            logger.addHandler(cl)
            logger.addHandler(bl)
            self.logger = logger
    
        def get_level(self,str):
            level = {
                'debug':logging.DEBUG,
                'info':logging.INFO,
                'warn':logging.WARNING,
                'error':logging.ERROR
            }
            str = str.lower()
            return level.get(str)
    
    path=os.path.join(setting.LOG_PATH,setting.LOG_NAME)
    
    atp_log=MyLogger(path,setting.LEVEL).logger

    最后两行代码,一个是存放日志的路径及日志文件名,一个实例化这个类。在这两行代码中,需要输入文件路径,文件名及日志等级,这些如果写死的话,一旦想改,就得改这块的代码,所以我们可以把这些作为配置放到配置文件夹下,然后导入该配置文件,使用里面的配置。这样,如果要修改这些的时候,只用修改配置文件就可以了。

    2)配置文件是在conf文件夹里面新建一个setting.py文件,然后在这个文件中写入以下代码:

    import os
    
    BASE_PATH=os.path.dirname(
        os.path.dirname(os.path.abspath(__file__))
    )    #获取路径
    LOG_PATH=os.path.join(BASE_PATH,'logs')  #存放日志路径
    
    LEVEL='debug'   #日志级别
    
    LOG_NAME='atp.log'  #日志文件名

    在log.py中用from conf import setting导入setting文件,就可以使用setting中的数据了。

    3)接下来按照步骤来说要获取用例

    从3)--7)步骤是在一个类里面,都写在lib文件夹下新建的common.py中,只是现在先分开来说每个类里面函数的含义

    
    
    import  xlrd
    from lib.log import atp_log
    class OpCase(object):
        def get_case(self,file_path):  #获取所有用例的方法
            cases=[]  #存放所有的case
            if file_path.endswith('xls') or file_path.endswith('.xlsx'):  #判断用例是否
                try:
                    book=xlrd.open_workbook(file_path) #打开用例文件
                    sheet=book.sheet_by_index(0)  #根据索引找到tab页第一页
                    for i in range(1,sheet.nrows):  #循环取用例中的每行信息
                        row_data=sheet.row_values(i)  #将读取的每行信息放到一个数组中
                        cases.append(row_data[4:8])   #取数组中的第4个元素到第7个元素放到另一个数组中
                    atp_log.info('共读取%s条用例'%(len(cases)))  #统计读取的用例条数
                    self.file_path=file_path  #定义变量,可以在类的其他函数中用
                except Exception as e:
                    atp_log.error('【%s】用例打开失败,错误信息:%s'%(file_path,e))  #异常处理
            else:
                atp_log.error('用例文件不合法:%s'%file_path)  #异常处理
            return cases  #返回所有的用例信息

    在获取用例的时候要往日志中写东西,那就要使用log.py文件中的日志模块。使用  from lib.log import atp_log ,将文件导入,因为在log.py文件中也已经实例化了,所以直接使用该实例方法就可以,如atp_log.info(),atp_log.error等。后面的地方就不再赘述日志的使用,每个地方都在用到。

    4)把数据转换成字典

    得到的用例信息,调接口之前要把该用例信息转换为字典类型,所以需要一个函数来讲数据转化为字典

     
    def dataToDict(self,data): #把数据转成字典 res={} data=data.split(',') #按照逗号分隔,存放在数组中 for d in data: k,v=d.split('=') #按照=分隔数组中的每个元素 res[k]=v #将分割的元素转换成字典 return res #返回字典

    5)调用接口

    通过接口地址将请求方式,请求数据发送并获取返回结果

    import  requests
    from lib.log import atp_log

    def my_request(self,url,method,data): #调接口要用到的url地址,请求方式及请求数据传入 method=method.upper() #将请求方式转换为小写 data=self.dataToDict(data) #调用数据转字典方法,将请求数据转换为字典,便于调用接口 try: if method == 'POST': res=requests.post(url, data).text #判断请求方式是post,则用post方法调用,并将结果赋给res elif method == 'GET': res=requests.get(url, params=data).text#判断请求方式是post,则用get方法调用,并将结果赋给res else: atp_log.warning('该请求方式暂不支持') #非这两种方式提示不支持 res='该请求方式暂不支持' except Exception as e: msg='【%s】接口调用失败,%s'%(url,e) atp_log.error(msg) #接口调用失败,将信息写入日志中 res=msg #将失败信息赋给res return res

    6)返回的数据要跟期望结果进行对比,看是否一致,是否测试通过

    from lib.log import atp_log
        def check_res(self,res,check):
            res=res.replace('": "','=').replace('": ','=')   #因为返回的结果是json串,要把json串转换成跟预期结果中一样的形式才能进行对比
            for c in check.split(','):
                if c not in res:
                    atp_log.info('结果校验失败,预期结果:【%s】,实际结果【%s】'%(c,res))
                    return '失败'
                return '成功' #判断如果返回的结果在预期结果里,返回成功

    因为返回的结果是json串,要将json串里面的error_code等取出来,就要进行转换。

    7)将返回的报文和用例执行结果写回到Excel用例的对应列

    from xlutils import copy
    import  xlrd
        def write_excel(self,cases_res):
            book=xlrd.open_workbook(self.file_path)
            new_book=copy.copy(book)  #将用例复制一份
            sheet=new_book.get_sheet(0)
            row=1
            for case_case in cases_res:  #从第一行写起,直到写到用例最后一行
                sheet.write(row,8,case_case[0]) #写第8列
                sheet.write(row,8,case_case[1])  #写第9列
                row+=1
            new_book.save(self.file_path.replace('xlsx','xls'))

    8)最后要将执行的结果发送邮件

    在lib下新建send_mail.py文件

    import  yagmail
    from conf import setting
    from lib.log import atp_log
    def sendmail(title,content,attrs=None):
        m=yagmail.SMTP(host=setting.MAIL_HOST,
                       user=setting.MAIL_USER,
                       password=setting.MAIL_PASSWRD)
        m.send(to=setting.TO,
               subject=title,
               contents=content,
               attachments=attrs)
        atp_log.info('发送邮件完成')

    发送邮件的时候,要传收件人,主题,内容及附件等,这这些如果写死了,后面想改动就要改代码,所以这些我们也放到setting文件里

    在conf的setting文件里增加如下内容:

    MAIL_HOST='smtp.163.com'
    MAIL_USER='521bbtjia@163.com'
    MAIL_PASSWRD='xxxx'
    TO=['xxxx@qq.com',]

    然后sen_mail文件中用 from conf import setting导入,就可以使用了。

    9)最后的步骤就是要把之前这些串联起来执行

    在bin文件夹下增加start.py文件

    import os,sys
    BASE_PATH = os.path.dirname(
        os.path.dirname(os.path.abspath(__file__))
    )
    sys.path.insert(0,BASE_PATH)
    
    from lib.common import OpCase
    from lib.send_mail import sendmail
    from conf import setting
    class CaseRun(object):
        def find_cases(self):
            op = OpCase()
            for f in os.listdir(setting.CASE_PATH):#每次循环的时候读一个excel
                abs_path = os.path.join(setting.CASE_PATH,f)  #Excel的路径
                case_list = op.get_case(abs_path)  #调用获取用例方法,将用例获取结果放到case_list里
                res_list = []
                pass_count,fail_count = 0,0  #设置成功和失败的条数默认为0
                for case in case_list:#循环每个excel里面所有用例
                    url,method,req_data,check = case
                    res = op.my_request(url,method,req_data) #传入url及请求方式,请求数据调用接口获得返回的结果
                    status = op.check_res(res,check)  #调用结果验证的方法
                    res_list.append([res,status])#将返回的报文和用例执行结果方法一个数组中
                    if status=='成功':
                        pass_count+=1   #如果用例执行成功,成功数量加1
                    else:
                        fail_count+=1     #如果用例执行失败,成功数量加1
                op.write_excel(res_list)  #调用写入excel的方法,将返回报文和用例执行状态写入用例中
                msg = '''
                xx你好:
                    本次共运行%s条用例,通过%s条,失败%s条。
                '''%(len(res_list),pass_count,fail_count)   #发送邮件的正文
                sendmail('测试用例运行结果',content=msg,attrs=abs_path)  #调用发送邮件方法,附件是Excel用例
    
    
    CaseRun().find_cases()
  • 相关阅读:
    Coherence的NameService
    监控Coherence成员的加入和离开集群事件
    Coherence的集群成员的离开和加入机制研究
    Coherence对象压缩以及对象大小计算
    Coherence代理的负载均衡
    Oracle Service Bus Socket Adapter调整的参数
    Coherence生产环境异常定位过程
    Automatic Diagnostic Repository
    docker(三)反正我不喜欢敲命令,daocloud.io管理你的docker,安装远程下载工具aria2 迅雷远程下载 xware
    docker(二)不管怎么样,先跑起来。运行一个samba,运行一个hello world。
  • 原文地址:https://www.cnblogs.com/emilyliu/p/9119767.html
Copyright © 2020-2023  润新知