使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 25--数据驱动--参数化处理 Excel 文件 2
测试学习记录,仅供参考!
数据驱动
结合 pytest 框架参数化处理对测试用例做参数化;介绍 Json 格式文件、yaml 格式文件、Excel 格式文件 三种文件方式去做测试用例参数化;
三、使用Excel文件对测试用例做参数化
简介
在日常工作中,经常需要处理Excel 数据,例如读取、写入、修改、分析等等。
使用Excel文件存放测试用例,可以使得测试数据更加直观和易于管理。
Python 是一种强大的编程语言,可以通过其丰富的第三方库来操作 Excel。但是,直接使用原生库进行操作可能会比较繁琐,不够简洁高效。因此,可以封装一个工具类,来简化Excel的操作过程,提高开发、测试效率。
使用 openpyxl 模块处理 Excel 数据(若选择其他第三方库,其他模块自行学习了解);
示例:封装读取 Excel 文件方法
处理列数据
9、有些输入数据只需要一列,这种情况下只需要读取这一列的数据即可;
再写一个方法处理列数据,可参照处理行数据信息;
from openpyxl import load_workbook
from openpyxl.utils.exceptions import InvalidFileException
from util_tools.logs_util.recordlog import logs
import osclass ExcelDataReader:def __init__(self, file_path):self.file_path = file_pathabspath = os.path.abspath(self.file_path)if not os.path.isfile(abspath):raise FileNotFoundError(f'文件路径不存在:{abspath}')self.workbook = load_workbook(self.file_path, read_only=False)def read_entire_column(self, sheet_name='Sheet1', column_index=1):"""获取Excel文件一整列的数据:param sheet_name: sheet页名称:param column_index: 要返回哪一列的数据,索引从1开始:return:"""sheet = self.workbook[sheet_name]for row in sheet.iter_rows(min_row=1, min_col=column_index, max_col=column_index):# 迭代器对象--获取的结果是单元格名称,例如:A1、A2、A3...)print(row)def close(self):self.workbook.close()if __name__ == '__main__':exl = ExcelDataReader('../../data/login_test.xlsx')print(exl.read_entire_column())9-1、 从运行结果可以查看到是一个元组类型;
(<Cell 'Sheet1'.A1>,)
(<Cell 'Sheet1'.A2>,)
(<Cell 'Sheet1'.A3>,)
(<Cell 'Sheet1'.A4>,)
(<Cell 'Sheet1'.A5>,)
None进程已结束,退出代码为 09-2、需要再循环这个迭代器对象,然后用循环的值去获取单元格的数据
from openpyxl import load_workbook
from openpyxl.utils.exceptions import InvalidFileException
from util_tools.logs_util.recordlog import logs
import osclass ExcelDataReader:def __init__(self, file_path):self.file_path = file_pathabspath = os.path.abspath(self.file_path)if not os.path.isfile(abspath):raise FileNotFoundError(f'文件路径不存在:{abspath}')self.workbook = load_workbook(self.file_path, read_only=False)def read_entire_column(self, sheet_name='Sheet1', column_index=1):"""获取Excel文件一整列的数据:param sheet_name: sheet页名称:param column_index: 要返回哪一列的数据,索引从1开始:return:"""sheet = self.workbook[sheet_name]for row in sheet.iter_rows(min_row=1, min_col=column_index, max_col=column_index):# 循环迭代器对象,然后用循环的值去获取单元格的数据print(row[0].value)def close(self):self.workbook.close()if __name__ == '__main__':exl = ExcelDataReader('../../data/login_test.xlsx')print(exl.read_entire_column())9-3、 成功获取到第一列每一行的数据内容;
username
admin123
admin111
admin123
admin
None进程已结束,退出代码为 09-4、 定义一个列表把每一行数据存储起来;
from openpyxl import load_workbook
from openpyxl.utils.exceptions import InvalidFileException
from util_tools.logs_util.recordlog import logs
import osclass ExcelDataReader:def __init__(self, file_path):self.file_path = file_pathabspath = os.path.abspath(self.file_path)if not os.path.isfile(abspath):raise FileNotFoundError(f'文件路径不存在:{abspath}')self.workbook = load_workbook(self.file_path, read_only=False)def read_entire_column(self, sheet_name='Sheet1', column_index=1):"""获取Excel文件一整列的数据:param sheet_name: sheet页名称:param column_index: 要返回哪一列的数据,索引从1开始:return:"""column_data = []sheet = self.workbook[sheet_name]for row in sheet.iter_rows(min_row=1, min_col=column_index, max_col=column_index):column_data.append(row[0].value)return column_datadef close(self):self.workbook.close()if __name__ == '__main__':exl = ExcelDataReader('../../data/login_test.xlsx')print(exl.read_entire_column())9-5、 运行查看结果,已经能够成功获取到第一列的数据;
['username', 'admin123', 'admin111', 'admin123', 'admin']进程已结束,退出代码为 09-6、获取指定列数据(例如第二列)
if __name__ == '__main__':exl = ExcelDataReader('../../data/login_test.xlsx')# 获取第二列的数据print(exl.read_entire_column(column_index=2))运行结果:
['password', 123456, 123456, 111111, None]进程已结束,退出代码为 09-7、添加 异常处理、日志、关闭文件 释放内容空间资源操作;
# 引进 openpyxl 模块 load_workbook 方法
from openpyxl import load_workbook
# 引入 openpyxl 的一个异常处理
from openpyxl.utils.exceptions import InvalidFileException
# 引入日志
from util_tools.logs_util.recordlog import logs
# 引入os模块
import os# 创建一个类
class ExcelDataReader:"""读取Excel文件数据"""# 写一个初始化构造方法def __init__(self, file_path):# 定义实例属性self.file_path = file_path# 写一下相对路径并返回出去abspath = os.path.abspath(self.file_path)# if判断 传进来的文件路径不存在(没有找到)时if not os.path.isfile(abspath):# 抛出异常提示raise FileNotFoundError(f'文件路径不存在:{abspath}')# read_only:控制工作簿是否以只读模式打开,若为True,工作簿以只读模式打开,不允许对工作簿进行修改self.workbook = load_workbook(self.file_path, read_only=False)def read_entire_row(self, sheet_name='Sheet1', row_index=1):"""获取Excel文件一整行的数据:param sheet_name: sheet页名称:param row_index: 要返回哪一行的数据,索引从1开始:return:"""# 调用上面初始化的打开这个文件的对象 self.workbook 列表里面是获取哪一行它的名称sheet = self.workbook[sheet_name]# 列表推导式rows_data = [cell.value for cell in sheet[row_index]]return rows_datadef read_multiple_rows(self, sheet_name='Sheet1'):"""读取Excel多行的数据,每一行数据组成一个列表:param sheet_name: sheet页名称:return: 返回list,例如:[['admin123','123456'],[],[],...]"""try:# 在最外层定义一个空列表all_rows_data = []# 第一步跟上面一样,先拿到sheet这个对象sheet = self.workbook[sheet_name]# 调用 max_column 方法获取到最大的列数(行数 .max_row)max_col = sheet.max_columnfor row in sheet.iter_rows(min_row=1, max_row=sheet.max_row, min_col=1, max_col=max_col):# row 是一个迭代器对象--但是不是需要获取的结果# print(row)# 列表推导式row_data = [cell.value for cell in row]# 调用append方法追加每一行的数据all_rows_data.append(row_data)return all_rows_dataexcept Exception as e:logs.error(f'读取所有行数据异常,原因为:{e}')finally:self.close()def read_entire_column(self, sheet_name='Sheet1', column_index=1):"""获取Excel文件一整列的数据:param sheet_name: sheet页名称:param column_index: 要返回哪一列的数据,索引从1开始:return:"""column_data = []try:sheet = self.workbook[sheet_name]for row in sheet.iter_rows(min_row=1, min_col=column_index, max_col=column_index):column_data.append(row[0].value)return column_dataexcept Exception as e:logs.error(f'读取整列数据异常,原因为:{e}')finally:self.close()def close(self):self.workbook.close()# 调试查看
if __name__ == '__main__':# 实例化类--里面是文件路径exl = ExcelDataReader('../../data/login_test.xlsx')print(exl.read_entire_column(column_index=2))获取某一个单元格的数据
10、读取某一个单元格的数据;
# 引进 openpyxl 模块 load_workbook 方法
from openpyxl import load_workbook
# 引入 openpyxl 的一个异常处理
from openpyxl.utils.exceptions import InvalidFileException
# 引入日志
from util_tools.logs_util.recordlog import logs
# 引入os模块
import os# 创建一个类
class ExcelDataReader:"""读取Excel文件数据"""# 写一个初始化构造方法def __init__(self, file_path):# 定义实例属性self.file_path = file_path# 写一下相对路径并返回出去abspath = os.path.abspath(self.file_path)# if判断 传进来的文件路径不存在(没有找到)时if not os.path.isfile(abspath):# 抛出异常提示raise FileNotFoundError(f'文件路径不存在:{abspath}')# read_only:控制工作簿是否以只读模式打开,若为True,工作簿以只读模式打开,不允许对工作簿进行修改self.workbook = load_workbook(self.file_path, read_only=False)def read_entire_row(self, sheet_name='Sheet1', row_index=1):"""获取Excel文件一整行的数据:param sheet_name: sheet页名称:param row_index: 要返回哪一行的数据,索引从1开始:return:"""try:# 调用上面初始化的打开这个文件的对象 self.workbook 列表里面是获取哪一行它的名称sheet = self.workbook[sheet_name]# 列表推导式rows_data = [cell.value for cell in sheet[row_index]]return rows_dataexcept Exception as e:logs.error(f'读取Excel文件一整行的数据数据异常,原因为:{e}')finally:self.close()def read_multiple_rows(self, sheet_name='Sheet1'):"""读取Excel多行的数据,每一行数据组成一个列表:param sheet_name: sheet页名称:return: 返回list,例如:[['admin123','123456'],[],[],...]"""try:# 在最外层定义一个空列表all_rows_data = []# 第一步跟上面一样,先拿到sheet这个对象sheet = self.workbook[sheet_name]# 调用 max_column 方法获取到最大的列数(行数 .max_row)max_col = sheet.max_columnfor row in sheet.iter_rows(min_row=1, max_row=sheet.max_row, min_col=1, max_col=max_col):# row 是一个迭代器对象--但是不是需要获取的结果# print(row)# 列表推导式row_data = [cell.value for cell in row]# 调用append方法追加每一行的数据all_rows_data.append(row_data)return all_rows_dataexcept Exception as e:logs.error(f'读取所有行数据异常,原因为:{e}')finally:self.close()def read_entire_column(self, sheet_name='Sheet1', column_index=1):"""获取Excel文件一整列的数据:param sheet_name: sheet页名称:param column_index: 要返回哪一列的数据,索引从1开始:return:"""column_data = []try:sheet = self.workbook[sheet_name]for row in sheet.iter_rows(min_row=1, min_col=column_index, max_col=column_index):column_data.append(row[0].value)return column_dataexcept Exception as e:logs.error(f'读取整列数据异常,原因为:{e}')finally:self.close()def read_cell_value(self, row_index, column_index, sheet_name='Sheet1'):"""获取单元格的数据:param sheet_name: sheet页名称(sheet_name='Sheet1' 关键字参数放到形式参数后面就不会有报错提醒了):param row_index: 行索引,从1开始:param column_index: 列索引,从1开始:return:"""try:sheet = self.workbook[sheet_name]# 直接调用获取单元格方法 sheet.cellreturn sheet.cell(row=row_index, column=column_index).valueexcept Exception as e:logs.error(f'读取单元格数据异常,原因为:{e}')finally:self.close()def close(self):"""关闭文件操作(释放内存空间资源)"""self.workbook.close()# 调试查看
if __name__ == '__main__':# 实例化类--里面是文件路径exl = ExcelDataReader('../../data/login_test.xlsx')print(exl.read_cell_value(row_index=4, column_index=2))11、最后都加上异常处理;其他别的方法可以根据测试数据格式是否需要继续增加(根据自己的需求去自定义);
其他
12、 列表解包(列表亦可以通过元组解包的方式进行解包里面的元素);
if __name__ == '__main__':# 实例化类--里面是文件路径exl = ExcelDataReader('../../data/login_test.xlsx')# print(exl.read_multiple_rows())data = ['admin123', '123456']username, password = dataprint(username, password)# 运行结果
admin123 123456进程已结束,退出代码为 013、若数据里面有三组数据,只想解包前面一组数据,后面两组还是一个列表;
data = ['admin123', '123456', '789']username, *password = dataprint(username, password)# 运行结果
admin123 ['123456', '789']进程已结束,退出代码为 0Web UI 自动化测试数据驱动

未完待续。。。
