接口自动化简单框架
一、自动化测试分类:
1、数据驱动:根据数据(读取EXCEL数据)来测试
2、代码驱动:测试用例都是代码,通过读取代码测试
3、关键字驱动:UI自动化,根据封装好的工具,输入关键字测试,有点傻瓜式测试
点击 --> .click()
下一步
提交 --> .submit()
{
'点击':click()
'提交':submit()
}
二、自动化框架
自动化框架:可以理解为工具的集合。在日常工作中根据需要实现某些功能,封装起来。或结合其他自动化工具。
三、搭建数据驱动自动化测试框架步骤
实现步骤:
1、获取测试用例
2、调用测试接口
3、校验结果
4、发送测试报告
5、异常处理
6、日志模块
四、准备工作
1、创建框架文件结构:创建总文件:ATP
2、在ATP下创建以下几个目录:
(1)创建bin目录:存放启动文件:start.py
(2)cases目录:存放测试用例excel文件
(3)conf目录:存放配置文件:setting.py
(4)lib目录:存放操作核心代码:common.py,log.py,send_mail.py
(5)logs目录:存放生成的日志信息
(6)readme文件:记录说明信息
五、开始搭建ATP:
1、首先编写获取测试用例的类,在该类下包含:
(1)获取测试用例get_case(),获取用例中需要的数据:url,请求方式,请求数据及预期结果,放到cases列表里,excel测试用例如下:
代码如下:
import xlrd
from xlutils import copy
from lib.log import atp_log
import requests
class OpCase(object):
def get_case(self,file_path):
cases = [] #存放所有的case
if file_path.endswith('.xls') or file_path.endswith('.xlsx'):#判断文件是否为excel文件
try:#
book = xlrd.open_workbook(file_path)#打开excel
sheet = book.sheet_by_index(0)#获取sheet页
for i in range(1,sheet.nrows):#循环每一行
row_data = sheet.row_values(i)#获取每一行数据
cases.append(row_data[4:9])#将第5-8列的数据添加到case中
atp_log.info('共读取%s条用例'%(len(cases)))#一共有多少条测试用例
self.file_path = file_path#实例化file_path
except Exception as e:
atp_log.error('【%s】用例获取失败,错误信息:%s'%(file_path,e))
else:#如果文件不是excel,提示
atp_log.error('用例文件不合法的,%s'%file_path)
return cases#返回case
(2)调用接口,获取请求数据:my_request()及dataToDict()函数通过url,data请求获取返回的内容,其中获取的data需要先转成字典:
1)先将获取的excel的请求数据转换成字典:
def dataToDict(self,data):
#把数据转成字典
res = {}
data = data.split(',')
for d in data:
#a=
k,v = d.split('=')
res[k]=v
return res
2)根据转换的字典调用接口,获取请求数据:
def my_request(self,url,method,data):#参数url,method,data
method = method.upper() #传入参数有可能会有大小写,统一转成大写字母
data = self.dataToDict(data) #将获取的数据做处理,转成字典
try :
if method=='POST': #判断method的类型
res = requests.post(url,data).text #发送请求并转换成字典
elif method=='GET':
res = requests.get(url,params=data).text
else:
atp_log.warning('该请求方式暂不支持。。') #调用日志文件
res = '该请求方式暂不支持。。'
except Exception as e:
msg = '【%s】接口调用失败,%s'%(url,e)
atp_log.error(msg)
res = msg
return res #返回请求返回的内容
(3)check_res()函数:校验返回结果是否与预期结果一致,将从服务器获取的返回结果与excel表里的预期结果比较,是否一致,若一致返回“成功”并写入结果,否则失败。
1)首先要了解返回结果的内容格式样式是怎么样的:如下
2)而excel表格中预期结果却是这样的:
3)所以得先把返回的结果转换成跟excel表格一样的如下图,然后在判断预期结果是否在返回的这个字典里
实现代码如下:
def check_res(self,res,check):
res = res.replace('": "','=').replace('": ','=') #两次替换,把res里返回的字典里所有的替换成=号(因为返回的Json串格式都是一样的)
for c in check.split(','): #将预期结果里的以逗号分开
if c not in res: #判断预期结果里的list是否在返回结果res里
atp_log.info('结果校验失败,预期结果:【%s】,实际结果【%s】'%(c,res))
return '失败'
return '成功'
4)write_excel()函数,将返回的报文、测试的结果写回excel。 获取返回每条用例的执行结果cases_res。需导入xlutils模块。
注:在get_case()函数里,定义了: self.file_path = file_path ,因此在该函数write_excel()中不需要再传入file_path参数,可以直接调用,否则需要在write_excel()函数中传入参数file_path。
首先需要了解用例返回结果样式:返回一个二维数组:[['abcxx,‘通过’],[abxx2,‘失败’]....],将结果写入返回报文和测试结果列。
def write_excel(self,cases_res):
# [ ['dsfd',"通过"] ,['sdfsdf','失败'] ]
book = xlrd.open_workbook(self.file_path)#打开excel
new_book = copy.copy(book)#复制excel
sheet = new_book.get_sheet(0)
row = 1
for case_case in cases_res:#将获取的写回excel
sheet.write(row,8,case_case[0]) #写第9列
sheet.write(row,9,case_case[1]) #写第10列
row+=1
new_book.save(self.file_path.replace('xlsx','xls'))#将xlsx格式转换成xls
5)log日志文件。专门封装写日志输出日志的类,哪里需要输出日志直接调用该类函数。
写日志文件,在其他文件抛异常时,会打印日志,直接调用该文件。
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
#直接在这里实例化,用的时候就不用再实例化了
以上是从excel获取测试用例,并将结果返回写入excel的代码。
2、当测试结束之后,需要将测试的结果邮件的形式发送出去,需要用到发送邮件的函数:send_mail.py
import yagmail
from conf import setting
from lib.log import atp_log
def sendmail(title,content,attrs=None):
#以下邮箱的配置直接写在setting中,方便管理修改
m = yagmail.SMTP(host=setting.MAIL_HOST,
user=setting.MAIL_USER,
password=setting.MAIL_PASSWRD,#邮箱的授权码
smtp_ssl=True )#QQ邮箱时需要添加smtp_ssl=True
m.send(to=setting.TO,subject=title,
contents=content,
attachments=attrs)
atp_log.info('发送邮件完成')
3、建立配置文件setting.py,在ATP下新建conf文件夹,在conf文件夹下新建setting.py配置文件,配置文件里定义各种需要的变量,常量,修改时,方便。
import os
BASE_PATH = os.path.dirname(
os.path.dirname(os.path.abspath(__file__)) #获取ATP所在的路径
)
MAIL_HOST='smtp.qq.com'
MAIL_USER='***@qq.com'
MAIL_PASSWRD = '***32432'#授权码
TO = [
'****@qq.com',#收件人
]
LEVEL = 'debug' #默认日志级别
LOG_PATH = os.path.join(BASE_PATH,'logs') #存放日志的路径
CASE_PATH = os.path.join(BASE_PATH,'cases') #存放日志的路径
LOG_NAME='atp.log' #日志的文件名
4、在ATP下新建bin文件夹,并在该文件夹下建立start.py文件,start.py 文件作为一个启动文件,程序的入口,串联整个系统功能的所有逻辑。
import os,sys
BASE_PATH = os.path.dirname(
os.path.dirname(os.path.abspath(__file__))#获取ATP的路径
)
sys.path.insert(0,BASE_PATH) #将ATP目录下的所有文件加到环境变量,这样保证以后在哪里运行都可以
from lib.common import OpCase#导入读取用例的类
from lib.send_mail import sendmail#导入发送邮件的类
from conf import setting#导入配置文件
class CaseRun(object):
def find_cases(self):
op = OpCase()#实例化获取用例的类,便于调用OpCase()类下的函数
for f in os.listdir(setting.CASE_PATH):#每次循环的时候读一个excel
abs_path = os.path.join(setting.CASE_PATH,f)#拼成绝对路径,f只是一个文件名
case_list = op.get_case(abs_path)#调用OpCase()类下的获取用例的函数,获取所有用例
res_list = []
pass_count,fail_count = 0,0#设置初始的成功、失败用例个数
for case in case_list:#循环每个excel里面所有用例
url,method,req_data,check = case
res = op.my_request(url,method,req_data) #调用完接口返回的结果,res:实际结果
status = op.check_res(res,check)#调用check_res()函数,校验预期结果&实际结果
res_list.append([res,status]) #将返回结果和测试结果加入一个list,定义res_list,便于写入excel
if status=='成功':
pass_count+=1
else:
fail_count+=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)#发送测试结果邮件
CaseRun().find_cases()
以上就是简单的自动化接口框架