每每咱们在自动化测试汇总,会将数据放在 Excel 文件、CSV文件、数据库数据库
Python中处理 excel 数据的模块很是多,好比: xlxd(只读)、xlwd(只写)、openpyxl(可读写)app
咱们会采用数据驱动思想,使用 openpyxl 当中的 load_workbook 来处理已存在的 Excel 文件数据,只能读写已 .xlsx 为拓展名的文件;函数
以 .xlsx 为拓展名的文件,为一个 Excel 文件对象,一个excel对象中, 每每会有多个表单,一个表单中,有多个单元格对象;测试
问:对excel相关操做使用类来封装? 封装有什么好处呢?spa
1、基本的使用excel
Excel 文件和下面的py文件代码必定要在同一个文件夹内,否则须要指定具体的 Excel 文件路径-------你们都是大佬我就很少说了code
读取数据不须要关闭文件,写入必须关闭文件;orm
from openpyxl import load_workbook # 第一步. 打开excel文件:使用load_workbook(译:楼的个人不可)传入文件名 wb = load_workbook("cases.xlsx") # 返回建立一个Workbook的对象, 至关是一个excel文件 # 第二步. 定位表单两种方式 # active(译:艾克体舞)是默认第一个表单 # ws = wb.active # 默认获取第一个激活的表单, 会建立一个Worksheet对象, 至关于一个表单 # 也能够指定表单 ws = wb['multiply'] # 第三步. 定位单元格 cell(译:赛欧),row:(译:肉)行、column:(译:犒劳木)列 one_cell = ws.cell(row=2, column=2) # 会建立一个Cell对象, 至关于一个单元格 # 使用 Cell(译:赛欧)对象中的value属性, 能获取单元格中的值 # print(one_cell.value) # 方法一: 定位单元格后,使用value属性,将数据写入到指定的单元格 one_cell.value = "休想" # 修改单元格的值 # 方法二: 定位表单,使用cell方法,将数据写入到指定的单元格 ws.cell(row=2, column=3, value="休想") # 保存excel文件 save(译:赛乌) # 写入若是报错:PermissionError: [Errno 13] Permission denied: 'cases.xlsx' ,必定是excel文件未关闭 wb.save("cases.xlsx")
Excel 文件及打印结果:对象
2、获取下面表单中数据blog
方法一:cell 方法:
---不推荐使用,由于只能获取固定的行到行、列到列之间的数据
from openpyxl import load_workbook # 对已经存在的excel进行读写操做 # 1. 打开excel文件 wb = load_workbook("cases.xlsx") # 会建立一个Workbook的对象, 是一个excel文件 # 2. 定位表单 ws = wb['aaa'] # 3. 定位单元格 # 方法一:获取表单中数据:使用ws(译:我可谁特)当中的cell(译:赛欧)方法 # range(译:软解) # min_row(译:敏.绕)表明最小行号:max_row(译:马克思.肉):最大行号 # min_column(译:敏.犒劳木)最小列号、max_column(译:敏.犒劳木):最大列号 for row in range(ws.min_row+1, ws.max_row+1): # 获取行号 for col in range(ws.min_column, ws.max_column+1): # 获取列号 data = ws.cell(row, col).value # 获取值,使用value属性 print("值为: {}\n类型为: {}".format(data, type(data))) # 打印结果
代码执行结果文档第一行:
方法二:使用 load_workbook 中 iter_rows(译:艾特.肉死)方法 + zip 函数 获取表单中数据
-----推荐使用这用,在自动化测试过程当中每执行一条测试用例,均可以使用表头来获取具体的值
from openpyxl import load_workbook # 对已经存在的excel进行读写操做 # 1. 打开excel文件 wb = load_workbook("cases.xlsx") # 会建立一个Workbook的对象, 是一个excel文件 # 2. 定位表单 ws = wb['aaa'] # min_row(译:敏.绕)表明最小行号:max_row(译:马克思.肉):最大行号 # min_column(译:敏.犒劳木)最小列号、max_column(译:敏.犒劳木):最大列号 # 3. 定位单元格 # 方法二:使用 load_workbook 中 iter_rows(译:艾特.肉死)方法获取表单中数据 # openpyxl 版本为2.6以上,要不没有参数:values_only # 获取的是单元格位置 使用 values_only = False 属性默认获取单元格对象 # 获取的是单元格位置 使用 values_only = True 后获取的是单元格的值 # 获取表头元祖,表头位置为0,表头为第一行,最小行号能够不写1,由于最大行号是1 # 结果为生成器对象,须要使用 tuple 转换为元祖,转换后为嵌套元祖的元祖 head_data_tuple = tuple(ws.iter_rows(min_row=1, max_row=1, values_only=True))[0] print(head_data_tuple) # 获取除表头外测试用例数据,和获取表头同样,最大行,最小列能够不写 for one_tuple in tuple(ws.iter_rows(min_row=2, max_row=5, min_col=1, max_col=7, values_only=True)): print(one_tuple) # 表头和测试数据结果 # ('case_id', 'title', 'l_data', 'r_data', 'expected', 'actual', 'result') # (1, '负数与负数相乘', -2, -4, 8, None, None) # (2, '负数与正数相乘', -3, 4, 12, None, None) # (3, '零与零相乘', 0, 0, 0, None, None) # (4, '正数与正数相乘', 5, 3, -15, None, None) head_data_tuple1 = tuple(ws.iter_rows(min_row=1, max_row=1, values_only=True))[0] one_list1 = [] for one_tuple1 in tuple(ws.iter_rows(min_row=2, max_row=5, min_col=1, max_col=7, values_only=True)): # 表头的元祖和数据元祖,使用 zip 方法进行转换(返回zip的生成器对象) # 在使用dict(译:迪克特)转换成字典 # 使用append(译:额喷的)添加到列表当中,获取到一个嵌套字典的列表 one_list1.append(dict(zip(head_data_tuple1, one_tuple1))) print(one_list1) # 打印结果 # 结果: # [{'case_id': 1, 'title': '负数与负数相乘', 'l_data': -2, 'r_data': -4, 'expected': 8, 'actual': None, 'result': None}, # {'case_id': 2, 'title': '负数与正数相乘', 'l_data': -3, 'r_data': 4, 'expected': 12, 'actual': None, 'result': None}, # {'case_id': 3, 'title': '零与零相乘', 'l_data': 0, 'r_data': 0, 'expected': 0, 'actual': None, 'result': None}, # {'case_id': 4, 'title': '正数与正数相乘', 'l_data': 5, 'r_data': 3, 'expected': -15, 'actual': None, 'result': None}]
3、openpyxl 模块的封装:
from openpyxl import load_workbook class HandleExcel: """ 封装excel文件处理类 """ def __init__(self, filename, sheetname=None): """ :param filename: 文件名 :param sheetname: 表单名,若是表单名只有一个能够设置为默认值 """ self.filename = filename self.sheetname = sheetname def get_cases(self): """ 获取全部的测试用例,实例方法 :return: """ # 打开文件:使用load_workbook(楼的个人不可)传入文件名 wb = load_workbook(self.filename) # 返回建立一个Workbook的对象, 至关是一个excel文件 if self.sheetname is None: # 定位表单,判断是否制定表单默认空,为第一个表单 ws = wb.active # active 获取第一个表单 else: ws = wb[self.sheetname] # 不然获取指定的表单 # min_row=最小行号,max_row=最大行号(能够不写) # min_col=最小列号,max_col=最大列号 # values_only=获取单元格的值 # 获取表头的信息,使用iter_rows(艾特木肉丝)方法,嵌套元祖的元祖,省略最小行号 head_data_tuple = tuple(ws.iter_rows(max_row=1, values_only=True))[0] one_list = [] for one_tuple in tuple(ws.iter_rows(min_row=2, values_only=True)): # 不须要表头最小行号为2,不须要最大行号,最大最小列号 # zip函数将表头的元祖与每一行用例所在的元祖进行拼接,dict转换为字典后,添加到列表当中one_list = [] one_list.append(dict(zip(head_data_tuple, one_tuple))) return one_list def get_one_case(self, row): """ 获取某一条测试用例 :param row: 行号 :return: """ return self.get_cases()[row - 1] def write_result(self, row, actual, result): """ 写入数据到测试用例指定的行列中 :param row: 行号 :param actual: 实际结果 :param result: 用例执行的结果(Pass或者Fail) :return: """ # 同一个Workbook对象, 若是将数据写入到多个表单中, 那么只有最后一个表单能写入成功,须要建立不一样的对象 other_wb = load_workbook(self.filename) # 建立对象 = 打开一个文件 if self.sheetname is None: other_ws = other_wb.active else: other_ws = other_wb[self.sheetname] # 写入 if isinstance(row, int) and (2 <= row <= other_ws.max_row): # 不能修改表头,下一行开始 other_ws.cell(row=row, column=6, value=actual) # 在第六行写入实际结果 other_ws.cell(row=row, column=7, value=result) # 在第七行写入用例执行的结果 other_wb.save(self.filename) # save保存文件 other_wb.close() # close关闭-----读数据的时候不须要关闭,写数据的时候可关闭或不关闭 else: # 若是不是整数,行号小于2,而且大于最大的行号 print("传入的行号有误, 行号应为大于1的整数") if __name__ == '__main__': # 本身写的模块本身用使用 main 函数 filename = "cases.xlsx" sheetname = "Sheet1" # 指定第二个表单名 # 建立一个对象,filename=文件名和sheetname=表单名能够不传 # do_excel = HandleExcel(filename) # 不传默认第一个表单 do_excel = HandleExcel(filename, sheetname) # 获取全部的测试用例cases cases = do_excel.get_cases() print(cases) # 写入在第二行写入"初心", "青柠" a = do_excel.write_result(2, "初心7", "青柠") print(a)
*******请你们尊重原创,如要转载,请注明出处:转载自:https://www.cnblogs.com/shouhu/ 谢谢!!*******