物业系统自主研发接口测试框架
1、自主研发框架整体设计
1.1、什么是测试框架?
在了解什么是自动化测试框架之前,先了解一下什么叫框架?框架是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面,而后者是从目的方面给出的定义。从框架的定义可以了解,框架可以是被重用的基础平台;框架也可以是组织架构类的东西。其实后者更为贴切,因为框和架本来就是组织和归类所用的。
所以自动化测试框架的定义为:由一个或多个自动化测试基础模块、自动化测试管理模块自动化测试统计模块等组成的工具集合。
框架的定义来分,自动化测试框架可以分为:基础功能测试框架、管理执行框架;按不同的测试类型来分,可以分为:功能自动化测试框架、性能自动化测试框架;按测试阶段来分,可以分为:单元自动化测试框架、接口自动化测试框架、系统自动化测试框架;按组成结构来分,可以分为:单一自动化测试框架、综合自动化测试框架;按部署方式来分,可以分为:单机自动化测试框架、分布式自动化测试框架。
看到这里,也许大家看完也不清楚上面到底讲的是什么。因为没有实际接触过,不知道具体功用,只是用一种抽象解释另一种抽象,另外只是描述了结论,没有描述推演的过程。
1.2、那么如何打破阻碍呢?
方法如下:
1、工作遇到了什么问题,需要使用XX技术?
2、这个技术能解决当下的工作问题吗?解决到什么程度呢?
3、这个技术能做什么,不能做什么?
4、具体如何实现的过程?
当前有下面的脚本需要接入到框架中。
要有以终为始的逆向思维方式,从最下面往上面分析。
1.3、框架测试报告初期规划:
执行时间,执行人,执行环境..
XXX时间:执行了XXX接口,接口执行结果
XXX时间:脚本报错信息
框架脚本整体执行情况统计
把框架测试结果发给相关责任人
1.4测试框架驱动设计
1、设置全局环境数据结构
2、读取测试框架配置文件
3、按照配置文件制定内容执行对应的测试脚本
4、创建测试报告,并写入总体初始化内容
5、若执行完所有的测试脚本,输出最终的测试报告,否则继续执行下一个脚本
6、写入新的测试报告内容
7、保存测试报告。
1.5 测试框架整体结构
本次测试框架分为三个层。分别为驱动层test_driver,报告层test_report,测试脚本层test_script。
其中config.csv是存放的测试脚本及路径 。
driverV1.py是驱动的执行程序。
report1.py存放的是测试报告
testcase_report1.txt存放的是单个用例不同数据的执行结果。
2、登录接口自研框架实践_global+csv+system文件
driver通过读取config.csv里面的信息,读取脚本名,再到test_script下面去找对应的脚本执行。
驱动读取框架配置文件
3、自研框架类图及流程图设计梳理
框架整体流程图:
config.csv内容
3.1 驱动类设计
进行实例化对象
#导入类库 import csv,os import datetime # 试验1:普通全局变量的使用 import pymysql global glob_url glob_url='https://svr-6-9009.share.51env.net/prod-api' print(glob_url) # 封装成一个驱动类 class driver_run(): #读取配置文件,获取py文件名 def run_testpy(self): # 设置脚本程序对应的路径 path = "..\\test_script\\" csvfile=open("config.csv",'r') rows=csv.reader(csvfile) # 跳过标题行 next(rows) # 逐行读取配置文件内容 for row in rows: print(row[2]) self.number=row[0] self.name = row[1] # 判断是否创建测试用例报告头部 if row[4]=='Y': if row[3] == '1': self.create_testcase_report() # 调用指定的接口脚本文件 os.system("python "+path+row[2]) # return row[0],row[1] 不能用面向过程的方法,要用面向对象的方法 # 调用报告写入内容方法 self.write_report() self.endtime=datetime.datetime.now() # 获取当前框架程序运行的总时长,如果时长已经大于50分钟了, # 主动调用登录接口,重新更新token rtime = self.endtime - self.starttime # 判断时间差是否超过50分钟 if (rtime.seconds // 60) >= 50: # 调用登录接口 os.system("..\\test_script\\loginV4.py") # 定义创建测试报告并写入头部公共信息 def create_report(self): self.starttime = datetime.datetime.now() # print(self.starttime) # 时间进行格式化 starttime = self.starttime.strftime("%Y-%m-%d %H:%M:%S") print(starttime) # 将时间戳写入txt文件 txtReport = open('..\\test_report\\report1.txt', "w") txtReport.write("*****************************************************************""\n") txtReport.write("智慧物业系统接口测试框架"+"\n") txtReport.write(starttime+" shangshang"+" "+"\n") txtReport.write("接口测试执行环境说明:"+glob_url+"\n") txtReport.write("*****************************************************************"+"\n") txtReport.close() # 定义创建测试用例报告并写入头部公共信息 def create_testcase_report(self): starttime = datetime.datetime.now() print(starttime) # 时间进行格式化 starttime = starttime.strftime("%Y-%m-%d %H:%M:%S") print(starttime) # 将时间戳写入txt文件 txttestReport = open('..\\test_report\\testcase_report1.txt', "w") txttestReport.write("*****************************************************************""\n") txttestReport.write("该测试用例运行开始时间:"+starttime+"\n") txttestReport.write("接口编号"+self.number+" ") txttestReport.write('接口名称'+self.name+"\n") txttestReport.write("*****************************************************************"+"\n") txttestReport.close() def write_report(self): txtReport = open('..\\test_report\\report1.txt', "a") txtReport.write("接口编号:"+self.number+" 接口名称:"+self.name) # 读取comresult文件中的测试结果 comfile=open("commonresult.txt", 'r') for result in comfile: txtReport.write(" 接口测试结果:"+result+"\n") comfile.close() txtReport.close() def write_commonresult(self,result): # 写入接口测试结果到公共文件中 comfile = open("..\\test_driver\\commonresult.txt", 'w') # 把result存入data文件中 comfile.write(result) comfile.close() #取出token文件中的token的值 def get_token(self): tokenfile=open("..\\test_driver\\token.txt","r") for token in tokenfile: tokenvalue=token return tokenvalue #连接数据库进行查询返回查询结果 def db_connect(self,sql): # 打开数据库连接 db=pymysql.connect(host='vip.51env.net', user='readonly', password='******', port=30001, db='******', charset='utf8') # 用cursor()方法获取操作游标 cursor = db.cursor() # 使用execute方法执行SQL语句 cursor.execute(sql) # 使用fetchall()方法获取一条数据 db_result=cursor.fetchall() # 关闭数据库连接 db.close() # 返回查询结果 return db_result if __name__ == '__main__': #实例化驱动类的对象 objdriver=driver_run() # 创建测试报告头部 objdriver.create_report() # 调用接口文件 objdriver.run_testpy()
3.2 登录类
实例化登录类
# ******************************************************************************** # 登录接口V5.0脚本实现 # 功能:1、调用图片验证码接口获取uuid # 2、将获取到的uuid传入登录接口中 # 3、分别对两个功能进行面向对象封装 # 修改内容: 增加token属性,为其他接口提供验证 # ******************************************************************************** # 导入类库 import requests import json # 定义一个类:包含两个方法和一个属性 from test_driver.driverV1 import driver_run,glob_url class login_interface(): # 定义一个属性 def __init__(self): self.uuid='' #增加token属性 self.token='' #方法1:获取验证码对应的uuid def getuuid(self): # 取验证码图片接口uuid # 定义获取验证码接口地址 CaptchaURL = 'https://svr-6-9009.share.51env.net/prod-api/captchaImage' # 发送请求 response = requests.get(CaptchaURL).json() # 获取uuid # print(type(response)) # 全局uuid引用说明 # global uuid self.uuid = response['uuid'] # print(self.uuid) # return uuid # 执行登录接口的测试 def login_test(self): # 定义接口地址 url = "https://svr-6-9009.share.51env.net/prod-api/login" # 定义接口参数 # print("登录方法中", self.uuid) userinfo = { "username": "admin", "password": "admin123", "code": "51testing", "uuid": self.uuid } # print(type(userinfo)) # 将字典类型转化为json类型 userjson = json.dumps(userinfo) # print(type(userjson)) # 发送接口请求 response = requests.post(url, data=userjson, headers={"Content-Type": "application/json"}).json() # print(response) # print(response["msg"]) # 对比实际和预期结果 if response["msg"] == '操作成功' and response["username"] == 'admin': result="登录接口成功" self.token=response["token"] tokenfile=open("..\\test_driver\\token.txt","w") tokenfile.write(self.token) tokenfile.close() else: result="登录接口失败" return result # 进行实例化调用 if __name__ == '__main__': # 实例化对象 loginObj=login_interface() # 调用其中的方法 loginObj.getuuid() result=loginObj.login_test() print(result) # 实例化驱动类对象 objdriver=driver_run() # 调用写入公共文件方法 objdriver.write_commonresult(result)
3.3 获取用户信息接口
代码:
# ********************************************************** # 获取登录用户信息接口V3.0脚本实现 # 功能:常量参数传递 # 问题1:引用登录接口类 # 问题2:运行登录接口类,并获取最新的token # 问题3:用面向对象的方法将获取到的最新的token传入获取用户信息接口 # *********************************************************** # 引入登录接口类 from test_driver.driverV1 import glob_url,driver_run # 导入类库 import requests # ************************************************** class GetUserInfo(): def getuser_test(self,token): # 定义接口地址 url=glob_url+'/getInfo' header={'Authorization':'Bearer '+token} # 发送请求并获取 self.response=requests.get(url,headers=header).json() print(self.response) def getuser_check(self): # 进行检查点的验证 # 提取msg msg=self.response['msg'] # print(msg) # 通过assert断言进行msg的验证 # 提取电话 phone=self.response['user']['phonenumber'] # print(phone) # 提取邮箱 email=self.response['user']['email'] # print(email) # 提取用户名 username=self.response['user']['userName'] # print(username) #对assert进行异常捕获 try: assert msg == '操作成功' assert phone=='13800138000' assert email=='13800138000@139.com' assert username=='admin' except: result="获取用户信息接口测试失败" else: result = "获取用户信息接口测试成功" return result if __name__ == '__main__': objdriver=driver_run() token=objdriver.get_token() print(token) #实例化获取用户信息对象类 objgetuser=GetUserInfo() objgetuser.getuser_test(token) result=objgetuser.getuser_check() # 将测试执行结论放入comresult.txt中 objdriver.write_commonresult(result)
3.4 创建商铺接口
#创建商铺接口V1.0接口脚本实现 #功能:常量参数传递 #************************************************************************* # 导入类库 import datetime import json import requests import pymysql from test_driver.driverV1 import glob_url, driver_run class createhouse_interface(): def createhouse_test(self,token): # 打开测试用例报告文件 txttestReport = open('..\\test_report\\testcase_report1.txt', "a") # 定义接口地址 url=glob_url+'/baseconfig/House' for i in range(1,3): # 传入接口参数,获取实际返回值 self.code='05-09-'+str(i) housedata={ "block": "01", "code": self.code, "buildingsquare": "100", "usesquare": "50", "state": "empty", "floor": "12", "rentFee": "12000", "remark": "test" } housejson=json.dumps(housedata) # 传入token参数 header = {'Authorization': 'Bearer ' + token, "Content-Type":"application/json"} # 比对结果1:接口返回值 response=requests.post(url,data=housejson,headers=header).json() print(response['msg']) # 比对结果:直接比对接口返回msg self.msg=response['msg'] if self.msg=='新建成功': result='创建商铺接口测试用例'+self.code+"接口测试用例成功" else: result = '创建商铺接口测试用例' + self.code + "接口测试用例失败" # 将接口测试用例的执行结果及数据内容写入对应的测试用例报告中 # 写入是第几次测试,测试商铺编号,测试结论 txttestReport.write('测试用例编号:'+str(i)) txttestReport.write(" 创建商铺的编号为:"+self.code) txttestReport.write(" 测试用例执行结果:"+result+"\n") txttestReport.write("*****************************************************************" + "\n") #共执行多少条数据 txttestReport.write("共执行" + str(i) +"条测试用例"+ "\n") # 获取系统时间,来写入结束时间 endtime = datetime.datetime.now() # 时间进行格式化 endtime = endtime.strftime("%Y-%m-%d %H:%M:%S") # 时间格式进行格式化 txttestReport.write('该接口测试执行结束时间:'+endtime+"\n") txttestReport.close() #连接后台数据库进行ID的检查,并给出测试结论 def createhouse_checkCode(self): id='5c7100ce60d044768223daf1546b3b61' sql="SELECT * FROM `config_house` WHERE id ='"+id+"'" dbresult=objdriver.db_connect(sql) print(dbresult) db_code=dbresult[0][1] print(db_code) # #判断是否执行成功 if db_code==self.code and self.msg=='新建成功': result="创建商铺列表接口测试通过" print(self.code) else: result="创建商铺列表接口测试失败" print(self.code) return result if __name__ == '__main__': objdriver = driver_run() token = objdriver.get_token() print(token) # 实例化创建商铺接口类对象 objcreatehouse = createhouse_interface() objcreatehouse.createhouse_test(token) # 调用数据库检查点 result=objcreatehouse.createhouse_checkCode() # 将测试执行结论放入comresult.txt中 objdriver.write_commonresult(result)
4、框架报告+测试用例报告
愿每个测试都能成为测试开发,提高职业技能,成为前1%的存在,为社会创造更大的价值,为公司节约更多的成本,为自己和家庭谋求更高的收入,所有人不受职业年龄限制,越老越吃香,直至财富自由;愿测试技术越来越进步,软件质量进一步得到提高,效率提高。愿祖国更加美好,人民更加幸福。多喜乐,常安宁。