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='[email protected]'
MAIL_PASSWRD='xxxx'
TO=['[email protected]',]

然后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()

猜你喜欢

转载自www.cnblogs.com/emilyliu/p/9119767.html