物业系统自主研发接口测试框架
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 pymysqlglobal 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分钟了,# 主动调用登录接口,重新更新tokenrtime = 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=tokenreturn 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_resultif __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_urlclass login_interface():# 定义一个属性def __init__(self):self.uuid=''#增加token属性self.token=''#方法1:获取验证码对应的uuiddef 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 uuidself.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):# 进行检查点的验证# 提取msgmsg=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 resultif __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 jsonimport requests
import pymysqlfrom test_driver.driverV1 import glob_url, driver_runclass 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'])# 比对结果:直接比对接口返回msgself.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 resultif __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%的存在,为社会创造更大的价值,为公司节约更多的成本,为自己和家庭谋求更高的收入,所有人不受职业年龄限制,越老越吃香,直至财富自由;愿测试技术越来越进步,软件质量进一步得到提高,效率提高。愿祖国更加美好,人民更加幸福。多喜乐,常安宁。
相关文章:
物业系统自主研发接口测试框架
1、自主研发框架整体设计 1.1、什么是测试框架? 在了解什么是自动化测试框架之前,先了解一下什么叫框架?框架是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架…...
手机和电脑通过TCP传输
一.工具 手机端:网络调试精灵 电脑端:野火网络调试助手 在开始通信之前,千万要查看一下电脑的防火墙是否关闭,否则可能会无法通信 在开始通信之前,千万要查看一下电脑的防火墙是否关闭,否则可能会无法通信…...
Git 在commit后,撤销commit
1. 撤销已经add,但是没有commit的问题 git reset HEAD 2. 撤销已经commit,但是没有push到远端的文件(仅撤销commit 保留add操作) 撤销上一次的提交 git reset --soft HEAD^windows 系统使用提示 more,需要多加一个…...
多模态大模型 - MM1
1. 摘要 本文主要通过分析模型结构和数据选择讨论如何构建一个好的多模态大模型(MLLM),并同时提出了MM1模型,包括30B dense版本和64B的MoE版本。 具体贡献: 模型层面:影响效果的重要性排序为:…...
FPGA设计之跨时钟域(CDC)设计篇(2)----如何科学地设计复位信号?
1、复位是干嘛的? 时钟信号和复位信号应该是一个数字系统最重要和最常用的两个信号了。时钟的重要性大家都懂,没有时钟整个系统就无法同步,自然也就谈不上运行了。那么复位(reset)到底是干嘛的? 所有的数字系统在上电的时候都会进行复位,这样才能确保该系统的初始运行状…...
GPS北斗标准时钟同步服务器结构是什么?安徽京准
GPS北斗标准时钟同步服务器结构是什么?安徽京准 GPS北斗标准时钟同步服务器结构是什么?安徽京准 电厂时钟同步系统组成及配置 随着计算机和网络通信技术的飞速发展,火电厂热工自动化系统数字化、网络化的时代已经到来。一方面它为控制和信息系…...
9.5 栅格图层符号化多波段彩色渲染
文章目录 前言多波段彩色渲染QGis设置为多波段彩色二次开发代码实现多波段彩色 总结 前言 介绍栅格图层数据渲染之多波段彩色渲染说明:文章中的示例代码均来自开源项目qgis_cpp_api_apps 多波段彩色渲染 以“3420C_2010_327_RGB_LATLNG.tif”数据为例,…...
力扣第九题
回文数 提示: 给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 代码展示&#…...
鞭炮插画:成都亚恒丰创教育科技有限公司
鞭炮插画:年味里的绚烂记忆 在岁末年初的温柔时光里,总有一抹色彩,能瞬间唤醒沉睡的年味——那便是鞭炮插画中跃动的红与金,成都亚恒丰创教育科技有限公司 它们不仅仅是纸与墨的交织,更是情感与记忆的桥梁,…...
python 循环
循环 while语句 for语句 循环控制语句 break 立即退出循环。 continue 跳过当前循环的剩余部分,并开始下一次迭代。 else for 和 while 循环都可以有一个可选的 else 子句,当循环正常结束时执行。 嵌套 占位符pass pass 是一个空操作语句。当你需要在代…...
映美精黑白相机IFrameQueueBuffer转halcon的HObject
映美精黑白相机,用wpfhalcon开发取图 1.到官网下载,开发包 1sdk 2c开发例子 3c#开发例子 引入TIS.Imaging.ICImagingControl35.dll 3.ICImagingControl使用这个类控制相机 /// <summary> /// 相机控制 /// </summary> public ICImagingC…...
Linux的load(负载)
负载(load)是Linux机器的一个重要指标,直观了反应了机器当前的状态。 在Linux系统中,系统负载是对当前CPU工作量的度量,被定义为特定时间间隔内运行队列中的平均线程数。 Linux的负载高,主要是由于CPU使用、内存使用、10消…...
杜比全景声——空间音频技术
什么是杜比?是否是标清、高清、超清之上的更清晰的格式?杜比全景声 和传统多声道立体声的差别?杜比全景声音频的渲染方式?车载平台上杜比技术的应用? 杜比技术的起源 杜比实验室(Dolby Laboratories&…...
C 语言指针进阶
1.0 指针的定义 指针是内存中一个最小单元的编号(内存单元的编号称之为地址【地址就是指针指针就是地址】)指针通常是用来存放内存地址的一个变量。本质上指针就是地址:口语上说的指针起始是指针变量,指针变量就是一个变量&#…...
SpringBootWeb 篇-入门了解 Swagger 的具体使用
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 Swagger 介绍 1.1 Swagger 和 Yapi 的使用场景 2.0 Swagger 的使用方式 2.1 导入 knife4j 的 maven 坐标 2.2 在配置类中加入 knife4j 相关配置 2.3 设置静态资源…...
Python面试题:如何在 Python 中处理大数据集?
在 Python 中处理大数据集可能面临许多挑战,包括内存限制、计算性能和数据处理效率等。以下是一些处理大数据集的常见方法和技术: 1. 使用高效的数据处理库 1.1 Pandas Pandas 是一个强大的数据分析库,可以处理中等大小的数据集࿰…...
C++:入门基础
1.命名空间 1.1namespace的价值 在C/C中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称都将存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,避免命名冲突或者名字…...
微信小游戏 彩色试管 倒水游戏 逻辑 (二)
最近开始研究微信小游戏,有兴趣的 可以关注一下 公众号, 记录一些心路历程和源代码。 定义一个 Water class 1. **定义接口和枚举**: - WaterInfo 接口定义了水的颜色、高度等信息。 - PourAction 枚举定义了水的倒动状态,…...
【链表】算法题(一) ---- 力扣 / 牛客
一、移除链表元素 移除链表中值为val的元素,并返回新的头节点 思路: 题目上这样说,我们就可以创建一个新的链表,将值不为val的节点,尾插到新的链表当中,最后返回新链表的头节点。 typedef struct ListNo…...
Linux系统之部署盖楼小游戏
Linux系统之部署盖楼小游戏 一、小游戏介绍1.1 小游戏简介1.2 小游戏玩法基本介绍1.3 项目预览二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍2.3 版本要求三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本四、安装node.js4.1 安装nvm4.2 查看nvm版本4.3 安装…...
联邦学习实战解析:FedAvg算法在非独立同分布数据下的优化策略
1. FedAvg算法在非独立同分布数据中的核心挑战 非独立同分布(Non-IID)数据是联邦学习中最常见的现实场景。想象一下,十个不同地区的医院合作训练医疗影像模型:北京医院的CT扫描以肺部疾病为主,上海医院的数据集可能更多…...
BK1086/88 DSP收音机Arduino库详解
1. 项目概述PU2CLR BK108X 是一款专为 BEKEN BK1086 和 BK1088 高集成度数字信号处理(DSP)广播接收芯片设计的 Arduino 库。该库并非通用型通信封装,而是面向射频接收系统工程实践的底层控制框架,其核心价值在于将芯片复杂的寄存器…...
小程序开发首选免费源码网:全开源生态下的创新加速器
一、全开源免费源码:破解开发难题的“钥匙”1. 降低技术门槛,加速产品落地对于初创团队或个人开发者而言,全开源免费源码的价值在于其“开箱即用”的特性。以GitHub和码云(Gitee)为例,这两个全球最大的开源…...
回溯算法双杀:子集 + 电话号码的字母组合 | 经典模板题解析
目录 一、LeetCode 78:子集 题目描述 核心思路(回溯法) 完整代码 关键解析 二、LeetCode 17:电话号码的字母组合 题目描述 核心思路(回溯法) 完整代码 关键解析 三、两道题核心对比 总结 一、L…...
告别HASH_MOD报错:手把手教你为Sharding-JDBC 5.5.0编写自定义分表算法(附完整代码)
深度定制Sharding-JDBC分片策略:从算法原理到生产实践 当数据库表数据量突破千万级时,单表查询性能会显著下降。这时我们需要将数据分散到多个物理表中存储——这就是分表的核心价值。Sharding-JDBC作为轻量级的Java分库分表中间件,其内置的H…...
Flet实战:教你用Python把Todo应用打包成exe可执行文件(含界面美化技巧)
用Flet和Python打造专业级Todo应用:从开发到打包的完整指南 在当今快节奏的工作环境中,一个美观实用的Todo应用能显著提升个人效率。Python开发者现在有了一个强大的新选择——Flet框架,它让我们能够用纯Python构建跨平台的桌面应用…...
AI辅助地图开发:用自然语言告诉快马你想要什么样的智能地图应用
AI辅助地图开发:用自然语言告诉快马你想要什么样的智能地图应用 最近在做一个旅游推荐项目,需要展示杭州的几个著名景点在地图上的分布。传统做法可能需要手动查找每个地点的经纬度坐标,然后编写大量代码来添加标记点和实现筛选功能。但在In…...
华硕笔记本合盖不休眠解决方案:GHelper智能模式完全指南
华硕笔记本合盖不休眠解决方案:GHelper智能模式完全指南 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, …...
ComfyUI 自动化生产 3D资产 工作流笔记
ComfyUI 自动化生产 3D资产 工作流笔记 概念与初衷: 针对个人开发者,实现 AI 转 高质量3D资产的 积分限制,次数限制,降低生成成本。 零、工具网站: 1、HugginFace (模型下载站) 2、魔搭社区 …...
别再乱调Spacing了!用SimpleITK给医学图像做重采样,这份避坑指南请收好
医学图像重采样实战:如何科学设置Spacing参数提升模型性能 当你在处理3D医学图像时,是否遇到过这样的困惑:明明按照教程完成了重采样,但模型性能却不升反降?或者在不同数据集上使用相同的Spacing参数,效果…...

