接口自动化测试系列-excel管理测试用例

代码源码:
框架结构
在这里插入图片描述

核心代码

excel用例demo
在这里插入图片描述

excel数据处理

from configureUtil.LogUtil import getlog
logger = getlog(targetName='HandleData')
import xlrd
from openpyxl import load_workbook,workbook
from openpyxl.styles import Font, colors
import openpyxl
import os
# from Common.FunctionStart import MoveSpace
# from openpyxl import load_workbook
# from openpyxl.reader.excel import load_workbook
# from openpyxl.styles import Color, Font, Alignment
# from openpyxl.styles import colors
'''
1、cope一份用例所保存的excel,当做执行环境保证测试数据清洁。
2、读取excle数据,返回dick形式的结果。
'''class ExcelHander():'''excel操作类,对外提供取excle返回dick结果功能、新增excel、sheet、cope excel功能、写入excel功能等。'''def __init__(self,filepath):self.filepath=filepathself.wb=xlrd.open_workbook(filepath)#加载excelself.sheet_names=self.wb.sheet_names()#获取excel所有sheet名集合形如:['test', 'test2', 'test3']def ExcelDick(self,SheetName):''':param SheetName: excel的sheet名字:return: 返回读取excel字典类型数据'''table = self.wb.sheet_by_name(SheetName)# 获取总行数rowNum = table.nrows# 获取总列数colNum = table.ncolsif rowNum<=1:logger.error('总行数小于等于1行')else:logger.debug('开始解析excel----excel总行数:%s'%rowNum)# 获取第一行(表头)keys = table.row_values(0)print(keys)r=[]j=1for i in range(rowNum-1):s={}# 从第二行开始values=table.row_values(j)print(values)for x in range(colNum):s[keys[x]]=values[x]r.append(s)j+=1# logger.debug('返回列名:%s'%r)ExcelDick={}ExcelDick[SheetName]=rlogger.debug('ExcelDick:%s' % ExcelDick)return ExcelDick #形如ExcelDick{'sheetName':[{列名:values},{列名:values}]}def sheet_method(self,work_book, add_sheet=[]):wk = work_book# rename default sheetss_sheet = wk["Sheet"]# ss_sheet = wk.get_sheet_by_name('Sheet')ss_sheet.title = add_sheet[0]for i in range(1, len(add_sheet)):# add new sheetwk.create_sheet(add_sheet[i])# switch to active sheet# sheet_num = wk.get_sheet_names()sheet_num = wk.sheetnameslast_sheet = len(sheet_num) - 1sheet_index = sheet_num.index(sheet_num[last_sheet])wk.active = sheet_indexdef CreateExcel(self,filepath,add_sheet=[]):''':param filepath: excel地址:return: 无'''# 新建一个工作簿p1=os.path.exists(filepath)#判断是否存在if p1:os.remove(filepath)wb2 = workbook.Workbook()self.sheet_method(wb2,add_sheet)logger.debug('新建excle:%s' % filepath)wb2.save(filepath)def CopeExcel(self,filepath,newexcelPath,i=0):''':param filepath: 原excel地址:param newexcelPath: 新excel地址:param SheetName: 原sheet的名字:return: 无'''# 读取数据logger.debug('读取数据excle:%s' % filepath)source = openpyxl.load_workbook(filepath)target = openpyxl.load_workbook(newexcelPath)sheets1 = source.sheetnamessheets2 = target.sheetnameslogger.info('源sheet列表:%s,目标sheet列表:%s'%(sheets1,sheets2))sheet1 = source[sheets1[i]]logger.debug('获取sheet:%s' % sheet1)sheet2 = target[sheets2[i]]table = self.wb.sheet_by_name(sheets1[i])# 获取总行数max_row = table.nrows# 获取总列数max_cloumn = table.ncolsfor m in list(range(1, max_row + 1)):for n in list(range(97, 97 + max_cloumn)):  # 字母a=97n = chr(n)i = '%s%d' % (n, m)cell1 = sheet1[i].value  # 获取文本数据# log.debug('获取文本数据:%s'%cell1)sheet2[i].value = cell1logger.debug('保存数据')target.save(newexcelPath)  # 保存数据source.close()target.close()def WriteExcel(self,filepath,row,cloumn,values,i):''':param filepath: excel地址:param row: 行号:param cloumn: 列号:param values: 值:param i: sheet的索引:return: 无'''excelpath = load_workbook(filepath)sheets = excelpath.sheetnamesexcelpath[sheets[i]].cell(row, cloumn).value = valuesexcelpath.save(filepath)logger.debug('写数据完成:sheet:%s 行:%s,列:%s,值:%s' % (sheets[i],row, cloumn, values))def AssembleCase(filepath,newexcelPath):'''测试用例组装工厂:return: 测试用例'''#新增同名excel、sheettest = ExcelHander(filepath)#实例化add_sheet = test.sheet_names#获取sheetname列表:['sheet1','sheet2']test.CreateExcel(newexcelPath, add_sheet)#创建excel及sheet(cope原excel新建空的execle)#给excel填充数据for i in range(len(add_sheet)):test.CopeExcel( filepath, newexcelPath, i)#按sheet分组,组装request数据wb = xlrd.open_workbook(newexcelPath)  # 加载新excelsheet_names = wb.sheet_names()  # 获取excel所有sheet名集合形如:['sheet1', 'sheet2', 'sheet3']caselist=[]for i in range(len(sheet_names)):caselist.append(test.ExcelDick(sheet_names[i]))#返回所有sheet集合,形如ExcelDick[{'sheetName':[{列名:values},{列名:values}]},{'sheetName':[{列名:values},None]#接口请求数据return caselistdef wordFormat(filepath,postition,size,name,bold,italic,i=0):'''格式化表格数据postition,位置如A1size,字体大小name,字体类型名color,字体颜色bold,是否加粗italic,是否斜体i,sheet索引:param filepath:指定excle:return:'''#激活exclewb = openpyxl.load_workbook(filepath)sheet1 = wb.worksheets[i]italic24Font = Font(size=size, name=name, bold=bold ,italic=italic)sheet1[postition].font = italic24Fontwb.save(filepath)def backFormat(filepath,n,m,fgColor,i=0):''':param n: 行号:param m: 列号:param fgColor: 颜色 # blue 23ff00 greet 6e6fff  red ff0f06:param i: sheet索引:return:'''import openpyxl.styles as stywb = openpyxl.load_workbook(filepath)sheet1 = wb.worksheets[i]sheet1.cell(row=n, column=m).fill = sty.fills.PatternFill(fill_type='solid',fgColor=fgColor)wb.save(filepath)def excleFormat(filepath):'''filepath 格式化excle:return:excel表头宋体斜体加粗背景色blue 12号 6e6fff其他内容宋体背景色无 11号 ffffff成功的 宋体背景色绿色 11号 23ff00失败 宋体背景色绿色 11号 ff0f06'''wb = xlrd.open_workbook(filepath)#加载sheet_names = wb.sheet_names()  # 获取excel所有sheet名集合形如:['test', 'test2', 'test3']#######字体if sheet_names==[]:logger.debug('excel是空sheet')passelse:for i,SheetName in enumerate(sheet_names)  :table = wb.sheet_by_name(SheetName)# logger.debug('获取第%s个sheet=%s'%(i,SheetName))# 获取总行数rowNum = table.nrows# logger.debug('行数:%s'%(rowNum))# 获取总列数colNum = table.ncols# logger.debug('列数:%s' % (colNum))name='Times New Roman'if rowNum<1:# logger.debug('空sheet')passelse:for m in list(range(1, rowNum + 1)):for n in list(range(97, 97 + colNum)):  # 字母a=97if m==1:n = chr(n)postition = '%s%d' % (n, m)color='6e6fff'bold=Trueitalic=Truesize=12# logger.debug('格式第一行数据')wordFormat(filepath, postition, size, name, bold, italic, i)fgColor='6e6fff'backFormat(filepath,m, ord(n)-96, fgColor, i)else:n = chr(n)postition = '%s%d' % (n, m)color = '6e6fff'bold = Falseitalic = Falsesize = 11# logger.debug('格式化%s行数据'%(m))wordFormat(filepath, postition, size, name, bold, italic, i)cell_value = table.cell_value(m-1,10)if cell_value=='TRUE'or cell_value==1 :fgColor='23ff00'# logger.debug('获取到结果:TRUE')backFormat(filepath,m, 11, fgColor, i)elif cell_value=='FLASE' or cell_value==0:fgColor = 'ff0f06'# logger.debug('获取到结果:FLASE')backFormat(filepath,m, 11, fgColor, i)else:logger.error('行号:%s ' % (m - 1))# logger.error('没有获取到结果:%s'%cell_value)########背景色if __name__=='__main__':filepath = r'E:\plant\AutoUniversalInterface\Common\TestCase\demo.xlsx'newexcelPath=r'E:\plant\AutoUniversalInterface\Common\TestResult\demo.xlsx'# 打开excelpostition='A1'size=14#大小name='Times New Roman'#字体color=colors.BLACK#字体颜色bold = False #是否加粗italic = True #是否斜体# headerFormat(filepath, postition,size, name, color,bold,italic)# wordFormat(filepath, postition, size, name, bold, italic, i=0)# fgColor = '23ff00'# n=2# m=11# backFormat(filepath,n, m, fgColor, i=0)# wb = xlrd.open_workbook(filepath)# table = wb.sheet_by_name('test')## cell_value = table.cell_value(1, 10)# print(cell_value)excleFormat(newexcelPath)

requests请求封装

import requests
# 禁用安全请求警告
import urllib3
urllib3.disable_warnings()
import jsondef callInterface(session,url, param=None,parammode='data', method='post', headers=None,verify=False,  jsonResponse=True):"""封装的http请求方法,接受session url, param, method, verify, headers 发起http请求并返回接口返回的json:param session: requests session 对象:param url: 请求地址:param param: 请求参数:param parammode:请求参数传入方式 data/json:param method: 请求方式 默认post:param verify: ssl检验 默认关:param headers: http headers:param jsonResponse: 是否json格式response标志:return: 接口返回内容/None"""logger.debug(f'开始调用接口:{url},参数为:{param}')res = NonereturnJson = Noneif method == 'POST':logger.debug(f'请求方法为:%s'%method)if parammode=='data':logger.debug(f'请求参数类型为:%s' % parammode)res = session.post(url, data=param, verify=verify, headers=headers)elif parammode=='json':logger.debug(f'请求参数类型为:%s' % parammode)res = session.post(url, json=param, verify=verify, headers=headers)elif method == 'GET':logger.debug(f'请求方法为:%s' % method)res = session.get(url, params=param, verify=verify, headers=headers)try:if res.status_code == 200:logger.debug(f'接口响应码:200')if jsonResponse:try:returnJson = res.json()except (TypeError, json.JSONDecodeError) as e:logger.error(f'请求接口:{url}出错,返回:{res.text}')logger.error(e)return {'fail':str(e)}else:try:returnJson = {'returnText': res.text[:1000]}except Exception as e:logger.error('请求接口出错')logger.error(e)return {}else:logger.error('请求接口失败!响应码非200!')logger.debug(f'接口调用完成 返回:{returnJson}')return returnJsonexcept Exception as e:return {'fail':str(e)}

检查点函数

"""
检查中心
1、检查结果是否包含于预期结果
2、结果的sql执行结果是否等于预期
3、没有检查条件走默认检查
"""
from configureUtil.LogUtil import getlog
logger = getlog(targetName='CheckPoint')
from configureUtil.DataManangerl import DBmananger#判断dict1的key是否存在dict2中
def KeyExist(dict1,dict2):n = 0if dict1=={}:return Falsefor key in dict1.keys():if key in dict2.keys():passn=n+1if n==len(dict1):return Trueelse:return False#判断dict2是否包含dict1
def Compare_ListDict(dick1, dick2):flag = Falsen = 0keyexist=KeyExist(dick1, dick2)if keyexist ==True:for i in dick1.keys():n=n+1if dick1[i] != dick2[i]:breakelif n==len(dick1):flag = Trueelif dick1=={}:flag = Trueelse:passreturn flag"""判断sql结果是否为()"""def JudgeSqlEmpty(sql,env):''':param sql: 需要执行sql:param env: 执行环境:return: 执行结果:true或者false'''try:result=DBmananger(env).callMysql(sql)logger.debug(result)except Exception as e:logger.error(e)result=()if result==():return Falseelse:return True

数据处理工厂

# 预置条件、用例依赖处理中心:
# 1、用例依赖标志
# 2、数据处理:支持sql增删改查操作
from configureUtil.LogUtil import getlog
from Common.FunctionStart import MoveSpace
logger = getlog(targetName='Precondition')
def DataSplit(SplitSign=';',StringOne=''):if isinstance(StringOne,str):result=StringOne.split(SplitSign,-1)else:result=[]result=list(filter(None, result))#去掉列表空字符及Nonereturn resultdef todict(func,SplitSign=';',StringOne=''):'''数据分离器:param StringOne: string类型入参:param SplitSign: 分离标志:如以冒号分离,则传入":":return: 分离list结果:{[{'SQL':[,]}],['$':[,]]}'''MoveSpace(StringOne)SplitSign = ';'SplitSign1 = (func(SplitSign,StringOne))# print(SplitSign1)dict = {}list1 = []list2 = []list3 = []# print(SplitSign1)import re# keys=re.findall(r'SQL:',StringOne,re.I)+re.findall(r'(\$[a-z]+):',StringOne,re.I)for i in SplitSign1:values = i.split(':')list1.append(MoveSpace(values[-1]))  # valueslist2.append(MoveSpace(values[0]))  # keysif MoveSpace(values[0]) in dict.keys():for i in dict[MoveSpace(values[0])]:list3.append(i)list3.append(MoveSpace(values[-1]))dict[MoveSpace(values[0])] = list3else:list4=[]list4.append(MoveSpace(values[-1]))dict[MoveSpace(values[0])] = list4return dict

发送邮件函数

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email import encoders
from email.mime.base import MIMEBase
from email.utils import parseaddr, formataddr
from configureUtil.DataFile import mailenv# 格式化邮件地址
def formatAddr(s):name, addr = parseaddr(s)return formataddr((Header(name, 'utf-8').encode(), addr))
def sendMail(body, attachment,title='接口自动化测试报告'):# smtp_server = 'smtp.163.com'smtp_server = 'mail.suishouji.com'smtp_server = mailenv['smtp_server']from_mail = mailenv['from_mail']mail_pass =mailenv['smtp_server']mail_passwd=mailenv['mail_passwd']to_mail = mailenv['to_mail']cc_mail = mailenv['cc_mail']# 构造一个MIMEMultipart对象代表邮件本身msg = MIMEMultipart()# msg = MIMEText('hello, send by Python...', 'plain', 'utf-8')# Header对中文进行转码msg['From'] = formatAddr('<%s>' % (from_mail))msg['To'] = formatAddr('<%s>' % (to_mail))msg['Cc'] = formatAddr('<%s>' % (cc_mail))msg['Subject'] = Header('%s'% title).encode()# to_mail = to_mail.split(',')# cc_mail= cc_mail.split(',')to_mail.extend(cc_mail)# plain代表纯文本msg.attach(MIMEText(body, 'plain', 'utf-8'))# 二进制方式模式文件for i in range(len(attachment)):with open(attachment[i], 'rb') as f:# MIMEBase表示附件的对象mime = MIMEBase('text', 'txt', filename=attachment[i])# filename是显示附件名字,加上必要的头信息:mime.add_header('Content-Disposition', 'attachment', filename=attachment[i])mime.add_header('Content-ID', '<0>')mime.add_header('X-Attachment-Id', '0')# 获取附件内容mime.set_payload(f.read())# 用Base64编码:encoders.encode_base64(mime)# 作为附件添加到邮件msg.attach(mime)# msg.attach(MIMEText(html, 'html', 'utf-8'))try:server = smtplib.SMTP(smtp_server, "25")server.set_debuglevel(1)server.login(from_mail, mail_passwd)server.sendmail(from_mail,to_mail,msg.as_string())  # as_string()把MIMEText对象变成strlogger.info ("邮件发送成功!")server.quit()except smtplib.SMTPException as e:logger.error ("Error: %s" % e)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/129467.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【HCIE】03.BGP高级特性

每一条BGP路由都可以携带多个路径属性&#xff0c;针对其属性也有特有的路由匹配工具&#xff0c;包括&#xff1a;AS Path Filter和Community Filter。 import方向的属性&#xff0c;出现在如策略里面&#xff0c;加入到BGP路由表中&#xff0c;再传给路由表里&#xff0c;出去…

如何使用聊天GPT自定义说明

推荐&#xff1a;使用 NSDT场景编辑器 快速搭建3D应用场景 OpenAI ChatGPT正在席卷全球。一周又一周&#xff0c;更新不断提高您可以使用这种最先进的语言模型做什么的标准。 在这里&#xff0c;我们深入研究了OpenAI最近在ChatGPT自定义指令上发布的公告。此功能最初以测试版…

蓝桥杯打卡Day4

文章目录 首字母大写字符串转换整数 一、首字母大写IO链接 本题思路:本题就是语法题 #include <bits/stdc.h>int main() {std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);std::string str;std::getline(std::cin,str);for(int i0;i&…

# Spring MVC与RESTful API:如何设计高效的Web接口

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Spring02

Spring02 1.Spring简介 Spring 是一个生态圈Spring是一个开源的Java企业级应用框架&#xff0c;提供了广泛的功能和特性&#xff0c;用于开发和管理Java应用程序。它的核心原则是基于IOC&#xff08;Inversion of Control&#xff0c;控制反转&#xff09;和AOP&#xff08;A…

分享一下奶茶店怎么在小程序上做商城功能

随着移动互联网的普及&#xff0c;越来越多的消费者倾向于在手机上完成购物需求。对于奶茶店来说&#xff0c;在小程序上开设商城功能不仅可以扩大销售渠道&#xff0c;还能提高品牌知名度和用户体验。本文将探讨如何在小程序上为奶茶店实现商城功能。 对于奶茶店的商城功能&am…

Java从入门到精通-类和对象(一)

0. 类和对象 1. 面向对象概述 Java面向对象编程&#xff08;Object-Oriented Programming&#xff0c;OOP&#xff09;是一种强大的编程范式&#xff0c;它基于对象、类、封装、继承和多态等核心概念。这种编程范式使得代码更加模块化、可维护、可重用和可扩展。 1.1 对象和类…

docker系列(2) - 常用命令篇

文章目录 2. docker常用命令2.1 参数说明(tomcat案例)2.2 基本命令2.3 高级命令2.4 其他 2. docker常用命令 2.1 参数说明(tomcat案例) 注意如果分成多行&#xff0c;\后面不能有空格 # 拉取运行 docker run \ -d \ -p 8080:8080 \ --privilegedtrue \ --restartalways \ -m…

比较Visual Studio Code中的文件

目录 一、比较两个文件 1.1VS code中的文件大致分为两类&#xff1a; 1.2如何比较VS code中的两个文件&#xff1f; 二、并排差异模式&#xff1a;VS code中的一种差异模式 三、内联差异模式&#xff1a;VS code中的另一种差异模式 四、VS code忽略在行首或者行尾添加或删除…

图像分割笔记(二): 使用YOLOv5-Seg对图像进行分割检测完整版(从自定义数据集到测试验证的完整流程))

文章目录 一、图像分割介绍二、YOLOv5-Seg介绍三、代码获取四、视频讲解五、环境搭建六、数据集准备6.1 数据集转换6.2 数据集验证七、模型训练八、模型验证九、模型测试十、评价指标一、图像分割介绍 图像分割是指将一幅图像划分为若干个互不重叠的区域,每个区域内的像素具有…

关于安卓grovvy开发(一)bugly混淆自动上报

背景 打包&#xff0c;mapping&#xff0c;上传&#xff0c;这些是不是都困扰了开发很多。苦于复制粘贴&#xff1f;反正我是。于是&#xff0c;有了这个 最终效果 最终的效果&#xff0c;就是点击项目的打包gradle&#xff0c;复制mapping文件且进行bugly混淆的自动上报。 …

LeetCode141.环形链表

这个题非常简单&#xff0c;我一下子就想到了用HashSet&#xff0c;从前往后把节点放入hashset中&#xff0c;如果set中存在这个节点说明存在环&#xff0c;如果把链表遍历完了说明不存在环&#xff0c;直接返回false&#xff0c;以下时我的代码&#xff1a; public class Sol…

环境扫描/透射电子显微镜气体样品架的真空压力和微小流量控制解决方案

摘要&#xff1a;针对环境扫描/透射电子显微镜对样品杆中的真空压力气氛环境和流体流量精密控制控制要求&#xff0c;本文提出了更简单高效和准确的国产化解决方案。解决方案的关键是采用动态平衡法控制真空压力&#xff0c;真空压力控制范围为1E-03Pa~0.7MPa&#xff1b;采用压…

Pytest模式执行python脚本不生成allure测试报告

1.安装allure 下载allure的zip安装包 将allure.zip解压到python的lib目录中 将allure的bin路径添加到环境变量path中(注意&#xff1a;配置环境变量后&#xff0c;一定要重启电脑。因为环境变量没生效&#xff0c;我搞了半天在pycharm不能生成报告&#xff0c;在cmd中可以生成…

【Redis】.net core Redis事件订阅与发布,基础篇

2023年&#xff0c;第38周。给自己一个目标&#xff0c;然后坚持总会有收货&#xff0c;不信你试试&#xff01; 发布与订阅&#xff08;Publish/Subscribe&#xff0c;也简称为 Pub/Sub&#xff09;是一种消息传递模式&#xff0c;用于解耦发布者和订阅者之间的关系。 目录 一…

华清远见第六课程day4作业

仿照string类&#xff0c;完成myString 类 #include <iostream> #include <cstring>using namespace std;class myString{ private:char *str;int size; public:myString():size(10){str new char[size];strcpy(str,"");}myString(const char*s){size …

【FPGA零基础学习之旅#12】三线制数码管驱动(74HC595)串行移位寄存器驱动

&#x1f389;欢迎来到FPGA专栏~三线制数码管驱动 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;FPGA学习之旅 文章作者技术和水平有限&#xff0c;如果文中出现错误&#xff0c;希望大家能指…

Transformer(二)—— ResNet(残差网络)

Transformer&#xff08;二&#xff09;—— ResNet&#xff08;残差网络&#xff09; 一、背景1.1 梯度消失/爆炸1.2 网络退化(Degradation) 二、思路2.1 为什么需要更深的网络2.2 理想中的深网络表现 三、实践和实验效果3.1 构造恒等映射&#xff1a;残差学习&#xff08;res…

0016Java程序设计-springboot幼儿园管理系统

摘 要目 录系统设计开发环境 摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于幼儿园管理系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了幼儿园管理系统&a…

【进阶篇】MySQL的MVCC实现机制详解

文章目录 0.前言1.基础介绍1.1. 什么是MVCC?1.1. 什么是当前读和快照读&#xff1f;1.1. 当前读&#xff0c;快照读和MVCC的关系1.1. MVCC能解决什么问题&#xff0c;好处是&#xff1f;1.1.1. 提高并发性能1.1.2. 避免死锁1.1.3. 解决脏读、不可重复读和幻读等问题1.1.4. 实现…