网站开发项目需求书,长沙最新确诊病例,泰安诚信的企业建站公司,帮别人制作网页多少钱混合测试自动化框架(关键字数据驱动)
关键字驱动或表驱动的测试框架 这个框架需要开发数据表和关键字。这些数据表和关键字独立于执行它们的测试自动化工具#xff0c;并可以用来“驱动#xff02;待测应用程序和数据的测试脚本代码#xff0c;关键字驱动测试看上去与手工测…混合测试自动化框架(关键字数据驱动)
关键字驱动或表驱动的测试框架 这个框架需要开发数据表和关键字。这些数据表和关键字独立于执行它们的测试自动化工具并可以用来“驱动待测应用程序和数据的测试脚本代码关键字驱动测试看上去与手工测试用例很类似。在一个关键字驱动测试中把待测应用程序的功能和每个测试的执行步骤一起写到一个表中。 这个测试框架可以通过很少的代码来产生大量的测试用例。同样的代码在用数据表来产生各个测试用例的同时被复用。
混合测试自动化框架 最普遍的执行框架是上面介绍的所有技术的一个结合取其长处弥补其不足。这个混合测试框架是由大部分框架随着时间并经过若干项目演化而来的。
unittest关于测试报告展示用例名称的细节:
在unittest有两个内置属性,可以自定义用例名称
之前的效果 自动化测试相关教程推荐 2023最新自动化测试自学教程新手小白26天入门最详细教程,目前已有300多人通过学习这套教程入职大厂_哔哩哔哩_bilibili 2023最新合集Python自动化测试开发框架【全栈/实战/教程】合集精华学完年薪40W_哔哩哔哩_bilibili 测试开发相关教程推荐 2023全网最牛字节测试开发大佬现场教学从零开始教你成为年薪百万的测试开发工程师_哔哩哔哩_bilibili postman/jmeter/fiddler测试工具类教程推荐 讲的最详细JMeter接口测试/接口自动化测试项目实战合集教程学jmeter接口测试一套教程就够了_哔哩哔哩_bilibili 2023自学fiddler抓包请一定要看完【如何1天学会fiddler抓包】的全网最详细视频教程_哔哩哔哩_bilibili 2023全网封神B站讲的最详细的Postman接口测试实战教学小白都能学会_哔哩哔哩_bilibili 使用内置属性效果 框架设计目标 设计出来的框架是直接给测试人员而且其他的测试人员只需要简单的向里面不断的补充测试用例即可所以我们的框架设计必须三简化即操作简单维护简单扩展简单。 设计框架的同时一定要结合业务流程而不仅仅靠技术实现其实技术实现不难难点对业务流程的理解和把握。 设计框架时要将基础的封装成公用的如get请求、post请求和断言封装成同基础通用类。 测试用例要与代码分开这样便于用例管理采用数据驱动框架实现。
如下图所示 通过在excel录入测试用例框架运行后自动进行用例执行产生html网页版本的测试报告。 报告结果 框架用到的技术点
1、语言python
2、测试框架unittestassertEqual或pytest
3、接口调用requestsAPI非常简洁
4、数据驱动paramunittest 组装一定的格式数据就可以参数化
5、数据管理xlrd读取excel文件数据、configparser读取配置文件
6、数据格式的转换astjson
7、日志处理logging ---清晰的执行过程快速定位问题
8、测试报表HTMLTestReportCN由网友制作设计显示清晰美观
9、测试邮件发送测试报告smtplib(邮件内容格式设置)、email收发邮件
10、持续集成Jenkins按策略执行接口测试脚本
推荐混合测试自动化框架关键字数据驱动
数据源实现
数据源目前使用excel数据如下
链接https://pan.baidu.com/s/1VvvGYRvGbElSlP6ngg0ktw 提取码ppua 思路使用python读取excel数据使用xlrd3
框架01新建项目API_KEY_WORD_TEST_FRAME;
步骤1、在项目根目录下新建common的py文件夹和conf的普通文件夹samples文件夹是用来写测试代码的demo; 步骤2、在conf下新建config.ini文件 编写代码
[default]# 主机地址
hosts api.weixin.qq.com
步骤3、在common下新建ini_file_utils.py文件和config_utils.py文件
ini_file_utils.py文件如下 编写代码 # encoding: utf-8
# author: Jeffrey
# file: ini_file_utils.py
# time: 2022/8/4 22:23
# desc: 读取、写入ini文件
import os
import configparserclass IniFileUtils: #和框架业务无关的底层代码》公共底层代码def __init__(self,file_path):self.ini_file_path file_pathself.conf_obj configparser.ConfigParser()self.conf_obj.read(self.ini_file_path, encodingutf-8)def get_config_value(self,section, key):value self.conf_obj.get(section, key)return valuedef set_config_value(self,section, key, value):设置config.ini文件中的值self.conf_obj.set(section, key, value)config_file_obj open(self.ini_file_path, w)self.conf_obj.write(config_file_obj)config_file_obj.close()if __name__ __main__:current_path os.path.dirname(__file__)config_file_path os.path.join(current_path, ../conf/config.ini)ini_file IniFileUtils(config_file_path)print(ini_file.get_config_value(default, HOSTS)) config_utils.py文件如下 编写代码 # encoding: utf-8
# author: Jeffrey
# file: config_utils.py
# time: 2022/8/4 22:26
# desc: 封装读取ini文件的方法import os
from common.ini_file_utils import IniFileUtilscurrent_path os.path.dirname(os.path.abspath(__file__))
config_file_path os.path.join(current_path, ../conf/config.ini)class LocalConfig(): # #和框架业务有关系的底层代码def __init__(self,file_path config_file_path):self.ini_file_obj IniFileUtils(file_path)propertydef get_hosts(self):获取ini文件中的hosts值hosts_value self.ini_file_obj.get_config_value(default, hosts)return hosts_valuelocal_config LocalConfig()if __name__ __main__:print(local_config.get_hosts) 步骤4、在samples文件下编写线性脚本读取excel中的合并单元格
Excel表格如下 编写代码 # encoding: utf-8
# author: Jeffrey
# file: demo01.py
# time: 2022/8/7 14:53
# desc: excel中合并单元格的读取
import xlrd3work_book xlrd3.open_workbook(test_data.xlsx) # 创建一个工作簿对象
sheet_obj work_book.sheet_by_name(Sheet1) # 创建一个表格对象
print(sheet_obj.cell_value(1,2)) # 获取单元格的值行列从0开始计算行列实际序号-1
print(sheet_obj.cell_value(7,3)) # 获取单元格的值print(sheet_obj.cell_value(1,0)) # 合并的单元格获取的值为空
print(sheet_obj.cell_value(7,0)) # 合并的单元格获取的值为空# 包含四个元素起始行结束行其实列结束列 包前不包后
print(sheet_obj.merged_cells) # [(1, 5, 0, 1), (5, 9, 0, 1)]
# 思路步骤一判断一个单元格是否是合并的单元格
x 3 ; y 0
if x1 and x5:if y0 and y1:print(合并单元格)else:print(非合并单元格)
else:print(非合并单元格)# 思路步骤二for循环的写法
for (min_row,max_row,min_col,max_col) in [(1, 5, 0, 1), (5, 9, 0, 1)]:print(min_row,max_row,min_col,max_col)# 思路步骤三把思路一和二整合进单元格判断是否是合并的单元格
x 6 ; y 0
for (min_row,max_row,min_col,max_col) in sheet_obj.merged_cells:if x min_row and x max_row:if y min_col and y max_col:print(合并单元格)breakelse:print(非合并单元格)else:print(非合并单元格)# 思路步骤四让合并单元格的值都等于合并第一个单元格的值非合并单元格为原值
x 4 ; y 1
cell_value None
for (min_row,max_row,min_col,max_col) in sheet_obj.merged_cells:if x min_row and x max_row:if y min_col and y max_col:cell_value sheet_obj.cell_value(min_row,min_col)breakelse:cell_value sheet_obj.cell_value(x, y)else:cell_value sheet_obj.cell_value(x, y)
print(cell_value)# 把上诉代码做成一个方法
def get_merged_cell_value(row_index,col_index):cell_value Nonefor (min_row, max_row, min_col, max_col) in sheet_obj.merged_cells:if row_index min_row and row_index max_row:if col_index min_col and col_index max_col:cell_value sheet_obj.cell_value(min_row, min_col)breakelse:cell_value sheet_obj.cell_value(row_index, col_index)else:cell_value sheet_obj.cell_value(row_index, col_index)return cell_valueprint(get_merged_cell_value(8,0))# 获取excel中所有的数据 线性脚本
# 步骤一线性脚本
head sheet_obj.row_values(0)
print(head) # [学习课程, 步骤序号, 步骤操作, 完成情况]
excel_list []
excel_dict {}
excel_dict[head[0]] get_merged_cell_value(1,0)
excel_dict[head[1]] get_merged_cell_value(1,1)
excel_dict[head[2]] get_merged_cell_value(1,2)
excel_dict[head[3]] get_merged_cell_value(1,3)
excel_list.append(excel_dict)
print(excel_list)# 步骤二 使用for循环封装
head sheet_obj.row_values(0)
excel_data_list []
for j in range(1,sheet_obj.nrows):row_value_dict {}for i in range(sheet_obj.ncols):row_value_dict[head[i]] get_merged_cell_value(j,i)excel_data_list.append(row_value_dict)
print(excel_data_list)for data in excel_data_list:print(data) 步骤5、在common下新建excel_file_utils.py文件 编写代码 # encoding: utf-8
# author: Jeffrey
# file: excel_file_utils.py
# time: 2022/8/7 15:52
# desc: 封装读取excel文件
import os
import xlrd3class ExcelFileUtils():def __init__(self,excel_file_path, sheet_name):self.excel_file_path excel_file_pathself.sheet_name sheet_nameself.sheet_obj self.get_sheet()def get_sheet(self):根据excel路径已经表名称 创建一个表格对象workbook xlrd3.open_workbook(self.excel_file_path)sheet workbook.sheet_by_name(self.sheet_name)return sheetdef get_row_count(self):获取表格实际行数row_count self.sheet_obj.nrowsreturn row_countdef get_col_count(self):获取表格的实际列数col_count self.sheet_obj.ncolsreturn col_countdef get_merged_cell_value(self,row_index, col_index)::param row_index: 行下标:param col_index: 列下标:return: 获取单元格的内容cell_value Nonefor (min_row, max_row, min_col, max_col) in self.sheet_obj.merged_cells:if row_index min_row and row_index max_row:if col_index min_col and col_index max_col:cell_value self.sheet_obj.cell_value(min_row, min_col)breakelse:cell_value self.sheet_obj.cell_value(row_index, col_index)else:cell_value self.sheet_obj.cell_value(row_index, col_index)return cell_valuedef get_all_excel_data_list(self):获取excel中所有的数据,以列表嵌套字典的形式excel_data_list []head self.sheet_obj.row_values(0)for j in range(1,self.get_row_count()):row_value_dict {}for i in range(self.get_col_count()): # sheet_obj.ncols 动态获取表格多少列row_value_dict[head[i]] self.get_merged_cell_value(j,i)excel_data_list.append(row_value_dict)return excel_data_listif __name__ __main__:current_path os.path.dirname(__file__)file_path os.path.join(current_path, ../samples/test_data.xlsx)excel_obj ExcelFileUtils(file_path, Sheet1)print(excel_obj.get_all_excel_data_list())print(excel_obj.get_col_count()) 测试执行结果 步骤6、在项目根目录下新建test_data普通文件夹把测试用例文件放里面 步骤7、在common下新建testcase_data_utils.py文件把测试用例的数据转换成框架需要用到的格式 编写代码 # encoding: utf-8
# author: Jeffrey
# file: testcase_data_utils.py
# time: 2022/8/7 17:02
# desc: 数据格式转换把测试用例数据转换成框架需要用到的格式
import os
from common.excel_file_utils import ExcelFileUtilscurrent_path os.path.dirname(__file__)
file_path os.path.join(current_path, ../test_data/testcase_infos.xlsx)class TestCaseDataUtils:def __init__(self):self.test_data ExcelFileUtils(excel_file_pathfile_path,sheet_nameSheet1)\.get_all_excel_data_list()def convert_testcase_data_to_dict(self):把excel中的测试用例数据转换为[{},{},{}]转换成{:[],:[],:[]}test_case_data_dict {}for row_data in self.test_data:test_case_data_dict.setdefault( row_data[测试用例编号],[] )\.append(row_data)return test_case_data_dictdef convert_testcase_data_to_list(self):把数据{:[],:[],:[]} 转换成[case_id:key,case_step:value]test_case_data_list []for key, value in self.convert_testcase_data_to_dict().items():case_info_dict {}case_info_dict[case_id] keycase_info_dict[case_step] valuetest_case_data_list.append(case_info_dict)return test_case_data_listif __name__ __main__:# print(TestCaseDataUtils().convert_testcase_data_to_dict())print(TestCaseDataUtils().convert_testcase_data_to_list()) convert_testcase_data_to_dict()方法的目的是把用例数据以用例编号和用例数据分开
把excel中的测试用例数据转换为[{},{},{}]转换成{:[],:[],:[]}
查看执行结果 总结 光学理论是没用的要学会跟着一起敲要动手实操才能将自己的所学运用到实际当中去这时候可以搞点实战案例来学习。 如果对你有帮助的话点个赞收个藏给作者一个鼓励。也方便你下次能够快速查找。
如有不懂还要咨询下方小卡片博主也希望和志同道合的测试人员一起学习进步
在适当的年龄选择适当的岗位尽量去发挥好自己的优势。
我的自动化测试开发之路一路走来都离不每个阶段的计划因为自己喜欢规划和总结
测试开发视频教程、学习笔记领取传送门