案例故事:Testlink导入xml格式的用例过程中,还会碰到一个小问题:
如何尽量确保生成的xml尽量小于400kb呢,只能考虑对excel进行切割拆分了,
以下案例假设一个大的测试模块的Excel,内含1000条用例,
需要考虑用Python实现切割,切割拆分成5个子excel,每个Excel是200条左右,
当然如果某个测试模块的Excel,只包含200条以内的用例,肯定用不着切割了。
小提示:本案例不再考虑input.xlsx, output_1/2/3/4/5.xlsx这种输入输出的思维,
而采用python cut_excel.py 1000.xlsx 200 类似这种参数输入处理的形式,
其实很多命令行工具都是采用以上这种多参数实现处理的,比如adb, ffmpeg命令等。
准备阶段
- 准备一个包含1000条用例的excel表格,名字不限制,
比如取名为:1000.xlsx, 我们计划切割成10个小的Excel,每个Excel 100条, - 参数输入,肯定涉及sys模块的argv参数的使用,以下是argv的使用示例:
命令 | 参数解析 |
---|---|
python cut_excel.py 1000.xlsx 200 | sys.argv=["cut_excel.py","1000.xlsx","200"]即: 参数0:"cut_excel.py" 参数1:"1000.xlsx" 参数2: "200" 备注:其实将cut_excel.py编译打包成cut_excel.exe就和以下adb.exe一样了。 |
adb logcat -v time | sys.argv=["adb","logcat","-v", "time"] 即: 参数0:"adb" 参数1:"logcat" 参数2: "-v" 参数3:"time" |
Python批处理脚本形式
记住批处理脚本的精髓:批量顺序执行语句
# coding=utf-8
import os
import sys
import openpyxl
excel_file = sys.argv[1] # 需要切割拆分的excel文件
limit = int(sys.argv[2]) # 以多少行为一个切割单位限制,比如100行为一个单位限制
excel = openpyxl.load_workbook(excel_file)
_, excel_name = os.path.split(excel_file)
sheet = excel.active
max_rows = sheet.max_row
# 如果行数太大了,比设定的单位限制还小或者相等,当然无法切割了。
if max_rows <= limit:
print("你设置的切割单位太大了,无法进行切割拆分, 必须小于excel行数%s" % max_rows)
sys.exit() # 直接退出程序
# 获取所有的行,并放到一个字典去。
excel_dict = {}
row_num = 1
for row in sheet.iter_rows():
temp_list = []
for cell in row:
temp_list.append(cell.value)
excel_dict[row_num] = temp_list
row_num = row_num + 1
# 切割(拆分)并填充到新的excel里去。
start_row = 1
for i in range(0, int(max_rows / limit) + 1): # 新建倍数个文件
part_excel = openpyxl.Workbook() # 初始化一个空表
part_sheet = part_excel.active
if start_row != 1: # 如果不是第一行
part_sheet.append(excel_dict[1]) # 写入第一行标题行
for j in range(start_row, (i + 1) * limit + 1):
try: # 如果最后可能没到unit_num的倍数,则捕捉异常,直接pass
part_sheet.append(excel_dict[j]) # 写入其他行
except:
pass
save_file = "%s_%s_%s.xlsx" % (excel_name, start_row, (i + 1) * limit)
part_excel.save(save_file) # 保存表格。
print("已经切割并保存到了:%s" % save_file)
start_row = start_row + limit # 继续下一个单位倍数。
os.system("pause")
Python面向过程函数形式
面向过程函数的编程思维应该是这样的:
你需要多少个功能(函数),才能做成这个事。
最好把功能(函数)都尽量封装好,只暴露一些的参数接口即可。
# coding=utf-8
import os
import sys
import openpyxl
def _get_excel_dict(sheet):
"""获取所有的行,并放到一个字典去"""
excel_dict = {}
row_num = 1
for row in sheet.iter_rows():
temp_list = []
for cell in row:
temp_list.append(cell.value)
excel_dict[row_num] = temp_list
row_num = row_num + 1
return excel_dict
def cut_excel(excel_file, limit):
"""切割(拆分)并填充到新的excel里去"""
excel = openpyxl.load_workbook(excel_file)
_, excel_name = os.path.split(excel_file)
sheet = excel.active
max_rows = sheet.max_row
# 如果行数太少了,比设定的单位限制还小或者相等,当然无法切割了。
if max_rows <= limit:
print("你设置的切割单位太大了,无法进行切割拆分, 必须小于excel行数%s" % max_rows)
sys.exit() # 直接退出程序
excel_dict = _get_excel_dict(sheet)
start_row = 1
for i in range(0, int(max_rows / limit) + 1): # 新建倍数个文件
part_excel = openpyxl.Workbook() # 初始化一个空表
part_sheet = part_excel.active
if start_row != 1: # 如果不是第一行
part_sheet.append(excel_dict[1]) # 写入第一行标题行
for j in range(start_row, (i + 1) * limit + 1):
try: # 如果最后可能没到unit_num的倍数,则捕捉异常,直接pass
part_sheet.append(excel_dict[j]) # 写入其他行
except:
pass
save_file = "%s_%s_%s.xlsx" % (excel_name, start_row, (i + 1) * limit)
part_excel.save(save_file) # 保存表格。
print("已经切割并保存到了:%s" % save_file)
start_row = start_row + limit # 继续下一个单位倍数。
excel_file = sys.argv[1] # 需要切割拆分的excel文件
limit = int(sys.argv[2]) # 以多少行为一个单位限制,比如100行为一个单位限制
cut_excel(excel_file, limit)
os.system("pause")
Python面向对象类形式
面向对象类的编程思维应该是这样的:
如果给你一个空白的世界,在这个世界里你需要哪些种类的事物,
这些种类的事物都具备哪些共有的属性与方法,
这些种类(类)的事物(对象),和其他种类(其他类)的事物(其他对象)有什么关系。
尽量把这些类封装好,只暴露对外的属性(变量)和方法(函数)即可。
# coding=utf-8
import os
import sys
import openpyxl
class ExcelCutter(object):
def __init__(self, excel_file):
self.excel_file = excel_file
def __get_excel_dict(self, sheet):
"""获取所有的行,并放到一个字典去"""
excel_dict = {}
row_num = 1
for row in sheet.iter_rows():
temp_list = []
for cell in row:
temp_list.append(cell.value)
excel_dict[row_num] = temp_list
row_num = row_num + 1
return excel_dict
def cut_excel(self, limit):
"""切割(拆分)并填充到新的excel里去"""
excel = openpyxl.load_workbook(self.excel_file)
_, excel_name = os.path.split(self.excel_file)
sheet = excel.active
max_rows = sheet.max_row
# 如果行数太大了,比设定的单位限制还小或者相等,当然无法切割了。
if max_rows <= limit:
print("你设置的切割单位太大了,无法进行切割拆分, 必须小于excel行数%s" % max_rows)
sys.exit() # 直接退出程序
excel_dict = self.__get_excel_dict(sheet)
start_row = 1
for i in range(0, int(max_rows / limit) + 1): # 新建倍数个文件
part_excel = openpyxl.Workbook() # 初始化一个空表
part_sheet = part_excel.active
if start_row != 1: # 如果不是第一行
part_sheet.append(excel_dict[1]) # 写入第一行标题行
for j in range(start_row, (i + 1) * limit + 1):
try: # 如果最后可能没到unit_num的倍数,则捕捉异常,直接pass
part_sheet.append(excel_dict[j]) # 写入其他行
except:
pass
save_file = "%s_%s_%s.xlsx" % (excel_name, start_row, (i + 1) * limit)
part_excel.save(save_file) # 保存表格。
print("已经切割并保存到了:%s" % save_file)
start_row = start_row + limit # 继续下一个单位倍数。
if __name__ == '__main__':
excel_file = sys.argv[1] # 需要切割拆分的excel文件
limit = int(sys.argv[2]) # 以多少行为一个单位限制,比如100行为一个单位限制
e_obj = ExcelCutter(excel_file)
e_obj.cut_excel(limit)
os.system("pause")
本案例素材下载
包括:一份待切割的测试用例,Python脚本
跳转到自拍教程官网下载
运行方式与效果
以上代码的3种实现形式都可以直接运行,比如保存为cut_excel.py并放在桌面,
cmd运行: python cut_excel.py D:\tttt\cut_excel\vts.xlsx 100,
类似这样运行,注意参数1:Excel文件的绝对路径,
运行效果及拆分效果:
代码优化方向
可以考虑对参数1, 参数2的健壮性性进行完善,
比如参数2,必须要是数字,如果不是数字,则需要给到必要的提示并退出程序。
更多更好的原创文章,请访问官方网站:www.zipython.com
自拍教程(自动化测试Python教程,武散人编著)
原文链接:https://www.zipython.com/#/detail?id=46c29fcb25af42e9b7dde45109a0d0ac
也可关注“武散人”微信订阅号,随时接受文章推送。