案例故事:Testlink导入xml格式的用例过程中,还会碰到一个小问题:
《自拍教程64》Python Testlink用例导入拆分Excel工具 Python 第1张
如何尽量确保生成的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命令等。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

准备阶段
  1. 准备一个包含1000条用例的excel表格,名字不限制,
    比如取名为:1000.xlsx, 我们计划切割成10个小的Excel,每个Excel 100条,
  2. 参数输入,肯定涉及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文件的绝对路径,
运行效果及拆分效果:
《自拍教程64》Python Testlink用例导入拆分Excel工具 Python 第2张

代码优化方向

可以考虑对参数1, 参数2的健壮性性进行完善,
比如参数2,必须要是数字,如果不是数字,则需要给到必要的提示并退出程序。

更多更好的原创文章,请访问官方网站:www.zipython.com
自拍教程(自动化测试Python教程,武散人编著)
原文链接:https://www.zipython.com/#/detail?id=46c29fcb25af42e9b7dde45109a0d0ac
也可关注“武散人”微信订阅号,随时接受文章推送。
《自拍教程64》Python Testlink用例导入拆分Excel工具 Python 第3张

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄