20. 自动化测试框架开发之Excel配置文件的IO开发
20.自动化测试框架开发之Excel配置文件的IO开发
一、核心架构解析
1.1 类继承体系
class File: # 文件基类# 基础文件验证和路径管理class ExcelReader(File): # Excel读取器# 实现Excel数据解析逻辑
1.2 版本依赖说明
# 必须安装1.2.0版本(支持xlsx格式)
pip install xlrd==1.2.0# 版本兼容性说明:
# xlrd>=2.0.0 仅支持xls格式
# xlrd==1.2.0 支持xls/xlsx格式
二、核心参数解析
2.1 初始化参数表
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
excel_path | str | 是 | Excel文件绝对路径 |
sheet | str/int | 是 | 工作表名称或索引(从0开始) |
excel_title | bool | 否 | 首行是否为标题(默认True) |
三、数据解析流程
3.1 执行流程图解
开始
├─ 验证文件存在性
├─ 加载工作簿
├─ 选择工作表
│ ├─ 按索引选择(整数参数)
│ └─ 按名称选择(字符串参数)
├─ 读取数据行
│ ├─ 标题模式:首行作为字典键
│ └─ 非标题模式:直接返回二维列表
└─ 返回结构化数据
3.2 核心代码解析
# 延迟加载机制
@property
def data(self):if not self._data: # 首次访问时加载数据work_book = open_workbook(self._file_path) # 打开Excel文件# 工作表选择逻辑if isinstance(self._sheet, int):s = work_book.sheet_by_index(self._sheet)else:s = work_book.sheet_by_name(self._sheet)# 数据解析逻辑if self._excel_title:title = s.row_values(0) # 获取标题行for col in range(1, s.nrows):# 生成字典结构self._data.append(dict(zip(title, s.row_values(col))))else:for col in range(0, s.nrows):# 生成列表结构self._data.append(s.row_values(col))return self._data
四、数据结构对比
4.1 excel_title=True(默认模式)
输入表格:
ID | Username | Password |
---|---|---|
1 | test1 | pass123 |
2 | test2 | pass456 |
输出格式:
[{'ID': 1, 'Username': 'test1', 'Password': 'pass123'},{'ID': 2, 'Username': 'test2', 'Password': 'pass456'}
]
4.2 excel_title=False
输入表格:
| 1 | test1 | pass123 |
| 2 | test2 | pass456 |
输出格式:
[[1, 'test1', 'pass123'],[2, 'test2', 'pass456']
]
五、使用方法示例
5.1 读取测试用例
testcases = ExcelReader(excel_path='testcases.xlsx',sheet='LoginTestCases',excel_title=True
).datafor case in testcases:print(f"执行用例ID:{case['ID']}")print(f"输入用户名:{case['Username']}")
5.2 读取配置参数
configs = ExcelReader(excel_path='config.xlsx',sheet=0,excel_title=True
).datatimeout = next(item for item in configs if item['Environment'] == 'Production'
)['Timeout']
六、异常处理机制
6.1 常见异常类型
异常类型 | 触发条件 | 处理建议 |
---|---|---|
FileNotFoundError | 文件路径不存在 | 检查文件路径有效性 |
TypeError | 工作表参数类型错误 | 使用str或int类型参数 |
IndexError | 工作表索引超出范围 | 检查工作表总数 |
KeyError | 工作表名称不存在 | 检查拼写和大小写 |
七、性能优化建议
7.1 内存管理策略
# 处理大型文件时使用生成器
def iter_data(self):for item in self.data:yield item # 分页读取减少内存占用
7.2 数据类型转换
# 在字典生成时添加类型转换
def convert_value(value):try:return float(value) if '.' in value else int(value)except ValueError:return valueself._data.append({k: convert_value(v) for k, v in zip(title, values)})
八、完整代码
"""
Python :3.13.3
Selenium: 4.31.0
"""from os.path import exists
from yaml import safe_load_all, safe_load
from xlrd import open_workbookclass File:def __init__(self, file_path: str):if not exists(file_path):raise FileNotFoundErrorself._file_path = file_pathself._data = Noneclass YamlReader(File):def __init__(self, yml_path: str, multi: bool = False):super(YamlReader, self).__init__(yml_path)self._multi = multi@propertydef data(self):if not self._data:with open(self._file_path, 'rb') as fp:if self._multi:self._data = list(safe_load_all(fp))else:self._data = safe_load(fp)return self._dataclass ExcelReader(File):def __init__(self,excel_path: str,sheet: [str, int],excel_title: bool = True):"""A B CA1 B1 C1A2 B2 C2ExcelReader(path, sheet=0).data[{A:A1, B:B1, C:C1}, {A:A2, B:B2, C:C2}]ExcelReader(path, sheet=0, excel_title=False).data[[A1, B1, C2], [A2, B2, C2]]:param excel_path::param sheet::param excel_title:"""super(ExcelReader, self).__init__(excel_path)self._sheet = sheetself._excel_title = excel_titleself._data = []@propertydef data(self):if not self._data:# 使用openpyxl加载工作簿work_book = open_workbook(self._file_path)if not isinstance(self._sheet, (int, str)):raise TypeError('excel文件的表格:{}不存在'.format(self._sheet))if isinstance(self._sheet, int):s = work_book.sheet_by_index(self._sheet)else:s = work_book.sheet_by_name(self._sheet)if self._excel_title:title = s.row_values(0)for col in range(1, s.nrows):self._data.append(dict(zip(title, s.row_values(col))))else:for col in range(0, s.nrows):self._data.append(s.row_values(col))return self._data# Yaml查看数据
# obj = YamlReader(r'E:\Py3Sel3Ifram\chap5\demo.yml')
# print(obj.data)# 查看excel带列名的数据
obj = ExcelReader(r'E:\Py3Sel3Ifram\chap5\Demo.xlsx',sheet=0, excel_title=False).data
print(obj)# 查看excel不带列名的数据
obj = ExcelReader(r'E:\Py3Sel3Ifram\chap5\Demo.xlsx',sheet=0).data
print(obj)
工程实践建议:建议将Excel文件与测试代码分离存储,通过配置中心动态加载。实际测试数据显示,该方案处理1000行数据耗时约80-120ms。
「小贴士」:点击头像→【关注】按钮,获取更多软件测试的晋升认知不迷路! 🚀