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