├── lib ├── __init__.py ├── setup.py ├── readXmind.py └── writeExcel.py ├── upload └── __init__.py ├── templates ├── __init__.py └── index.html ├── src ├── __init__.py └── main.py ├── README.md └── app.py /lib/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /upload/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = '0.0.1' -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # xmindToTestcase 2 | Convert Xmind file to Excel testcases file. 3 | 4 | ## usage 5 | 6 | ```shell 7 | 1、运行 app.py 8 | 2、通过 localhost:5000/index 访问 9 | ``` 10 | ## xmind examples 11 | ```shell 12 | 项目名称 - 功能模块名称 - 功能名称 - 功能点 - 检查点 - 用例步骤(可以多个) - 预期结果 - 预期的结果信息(可以多个) 13 | ``` -------------------------------------------------------------------------------- /lib/setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'snailgirl' 3 | 4 | """ 5 | @author:snailgirl 6 | @time: 18/11/16 下午3:25 7 | """ 8 | try: 9 | from setuptools import setup, find_packages 10 | except ImportError: 11 | from distutils.core import setup, find_packages 12 | 13 | setup( 14 | name='UiA', 15 | keywords='', 16 | version='0.0.1', 17 | packages=find_packages(), 18 | url='', 19 | license='MIT', 20 | author='snailgirl', 21 | #author_email='test@sina.com', 22 | description='', 23 | install_requires=[ 24 | 'xmindparser', 25 | "xlwt" 26 | ] 27 | ) -------------------------------------------------------------------------------- /src/main.py: -------------------------------------------------------------------------------- 1 | #coding:utf8 2 | # import subprocess 3 | 4 | # 安装依赖包 5 | # import os 6 | # file_path = os.path.dirname(os.path.dirname(__file__)) 7 | # print(file_path) 8 | # setup_path = os.path.join(file_path, 'lib', 'setup.py') 9 | # subprocess.Popen('python3 ' + setup_path + ' install', shell=True) 10 | 11 | from lib.readXmind import * 12 | from lib.writeExcel import * 13 | import logging 14 | def get_xmind_content(xmind_file,output_file): 15 | #生成测试用例 16 | read_xmind = ReadXmindList(xmind_file) 17 | # excel_title=read_xmind.excel_title #获取模块标题 18 | write_excel = WriteExcel(output_file) 19 | testcase_list = [] 20 | read_xmind.get_list_content(read_xmind.content, testcase_list, write_excel )#写入excel 21 | write_excel.write_analysis_wooksheek()#写入测试分析excel 22 | write_excel.save_excel() #保存excel 23 | logging.info("Generate Xmind file successfully: {}".format(output_file)) 24 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | xmind to excell testcase 6 | 7 | 8 | 9 |
10 |

xmind 转化为 excel 测试用例

11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 |
19 | 20 |
{{res.error}}
21 | {{res.sucess_msg}} 22 |
23 |
24 | 25 |
26 |
27 | 28 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, render_template, request, send_from_directory,session,make_response 2 | from src.main import * 3 | import os 4 | import time 5 | import urllib 6 | 7 | upload_path = 'upload' # 文件上传下载路径 8 | app = Flask(__name__) 9 | app.secret_key = 'xmindhellodfdf' 10 | 11 | @app.route('/index',methods=['GET','POST']) 12 | def index(): 13 | session['tag'] = False 14 | if request.method == 'POST': 15 | res = { 16 | 'error': '', 17 | 'file_url': '', 18 | 'sucess_msg': '' 19 | } 20 | # 删除upload下所有的文件(除__init__.py) 21 | del_files() 22 | # 获取xmind文件名 23 | xmind_file_obj = request.files['xmindFile'] 24 | xmind_file_name = xmind_file_obj.filename 25 | # 判断xmind文件后缀是否正确 26 | if not xmind_file_name.endswith('.xmind'): 27 | res['error'] = '上传的 xmind 文件不正确!' 28 | return render_template('index.html', res = res) 29 | # 保存上传的文件 30 | save_path = os.path.join(upload_path, xmind_file_name) 31 | xmind_file_obj.save(save_path) 32 | # 生成excel文件名 33 | excel_file_name = xmind_file_name.rsplit(".", 1)[0] + '.xls' 34 | # 调用方法将xmind文件转换为excel文件 35 | get_xmind_content(save_path, os.path.join(upload_path, excel_file_name)) 36 | res['file_url'] = os.path.join('/download/', excel_file_name) 37 | res['sucess_msg'] = xmind_file_name + ' 转换成功,点击下载用例!' 38 | return render_template('index.html', res = res) 39 | return render_template('index.html', res = {}) 40 | 41 | @app.route('/download/',methods=['GET']) 42 | def download(filename): 43 | file_name = urllib.request.unquote(filename, encoding='utf-8', errors='replace') 44 | # 下载的文件路径 45 | excel_file_path = os.path.join(upload_path, file_name) 46 | if request.method == "GET": 47 | if os.path.isfile(excel_file_path): 48 | return send_from_directory(upload_path, file_name, as_attachment=True) 49 | 50 | # 删除upload下所有的文件(除__init__.py) 51 | def del_files(): 52 | for file_name in os.listdir(upload_path): 53 | del_files_path = os.path.join(upload_path, file_name) 54 | if file_name not in ['__init__.py']: 55 | # 获取文件的创建日期 56 | ctime = time.localtime(os.stat(del_files_path).st_ctime) 57 | cdate = time.strftime("%Y-%m-%d", ctime) 58 | # 获取文件创建日期小于当前日期 59 | if cdate < time.strftime("%Y-%m-%d"): 60 | os.remove(del_files_path) 61 | 62 | if __name__ == '__main__': 63 | app.run() 64 | 65 | 66 | -------------------------------------------------------------------------------- /lib/readXmind.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from xmindparser import xmind_to_dict 3 | from .writeExcel import * 4 | class ReadXmindList(object): 5 | def __init__(self, filename): 6 | self.filename = filename #xmind文件路径 7 | self.content, self.canvas_name, self.excel_title = self.__get_dic_content(self.filename) 8 | 9 | def __get_dic_content(self, filename): 10 | """ 11 | #从Xmind读取字典形式的数据 12 | :param filename: xmind文件路径 13 | :return: 14 | """ 15 | if not os.path.exists(filename): 16 | print("[ERROR] 文件不存在") 17 | sys.exit(-1) 18 | out = xmind_to_dict(filename) 19 | dic_content = out[0] 20 | canvas_name = dic_content.get('title') # 获取画布名称 21 | cavas_values = dic_content.get('topic') 22 | if cavas_values: 23 | excel_title = cavas_values.get('title') # 获取模块名称 24 | content = [dic_content.get('topic')] 25 | return content, canvas_name, excel_title 26 | 27 | def __format_list(self, testcase_list): 28 | """ 29 | 格式化为excell需要的列表 30 | :param testcase_list: 需要处理的列表 31 | :return: 32 | """ 33 | new_testcase = [] 34 | step_list = [] 35 | expected_list = [] 36 | tag = False 37 | step_index = 1 # 用例步骤编号 38 | expected_index = 1 # 预期结果编号 39 | testcase = [item for item in testcase_list] 40 | for item in testcase: 41 | item_index = testcase.index(item) 42 | if item != '预期结果' and not tag: 43 | if item_index <= 4: 44 | new_testcase.append(item) 45 | if item_index >= 5: 46 | if step_index != 1: 47 | step_list.append('\n' + str(step_index) + '.' + item) 48 | else: 49 | step_list.append(str(step_index) + '.' + item) 50 | step_index += 1 51 | if item == '预期结果': 52 | tag = True 53 | continue 54 | if tag: 55 | if expected_index != 1: 56 | expected_list.append('\n' + str(expected_index) + '.' + item) 57 | else: 58 | expected_list.append(str(expected_index) + '.' + item) 59 | expected_index += 1 60 | if step_list: 61 | new_testcase.insert(5, step_list) 62 | return new_testcase, expected_list 63 | 64 | def get_list_content(self, content, testcase_list, write_excel): 65 | """ 66 | #从Xmind文件中读取数据,保存至excel文件中 67 | :param testcase_list: 储存处理后的列表信息 68 | :param content: xmind读取的内容 69 | :param write_excel: WriteExcel 实例对象 70 | :return: 71 | """ 72 | for dic_val in content: 73 | val = list(dic_val.values()) 74 | if val: 75 | testcase_list.append(val[0]) 76 | if len(val) == 2: 77 | self.get_list_content(val[1], testcase_list, write_excel) 78 | else: 79 | new_testcase = self.__format_list(testcase_list) # 格式化为excell需要的数据 80 | # print(new_testcase) 81 | write_excel.write_testcase_excel(new_testcase) # 写入测试用例 82 | write_excel.write_outline_excel(new_testcase) # 写入测试大纲 83 | write_excel.write_testscope_wooksheek(new_testcase) # 写入测试范围 84 | testcase_list.pop() 85 | if testcase_list: 86 | testcase_list.pop() -------------------------------------------------------------------------------- /lib/writeExcel.py: -------------------------------------------------------------------------------- 1 | 2 | import os,xlwt,datetime 3 | # from conf.settings import filename_path 4 | 5 | class WriteExcel(): 6 | style= xlwt.easyxf('pattern: pattern solid, fore_colour 0x31; font: bold on;alignment:HORZ CENTER;' 7 | 'borders:left 1,right 1,top 1,bottom 1,bottom_colour 0x3A') 8 | style_nocenter = xlwt.easyxf('pattern: pattern solid, fore_colour White;' 9 | 'borders:left 1,right 1,top 1,bottom 1,bottom_colour 0x3A')#未居中无背景颜色0x34 10 | style_center = xlwt.easyxf('pattern: pattern solid, fore_colour White;alignment:HORZ CENTER;' 11 | 'borders:left 1,right 1,top 1,bottom 1,bottom_colour 0x3A') # 无背景颜色居中 12 | style_num = xlwt.easyxf('pattern: pattern solid, fore_colour White;alignment:HORZ CENTER;' 13 | 'borders:left 1,right 1,top 1,bottom 1,bottom_colour 0x3A', num_format_str='#,##0.00') # 无背景颜色居中 14 | def __init__(self, output_file): 15 | self.testcase_filename = output_file # 生成用例的目录 16 | self.wookbook=self.__init_excel() 17 | self.testcase_wooksheek=self.__init_testcase_wooksheek() #测试用例 18 | self.testscope_wooksheek = self.__init_testscope_wooksheek() # 测试范围 19 | self.outline_wooksheek=self.__init_outline_wooksheek() #测试大纲 20 | self.analysis_wooksheek=self.__init_analysis_wooksheek() #测试分析 21 | self.__row = 1 # 测试用例、测试大纲excel行数 22 | self.__temp_list=[] #测试范围临时存储列表 23 | self.__testscope_row=1 ## 测试范围excel行数 24 | 25 | def __init_excel(self): 26 | """ 27 | 初始化excel 28 | :return: 29 | """ 30 | f = open(self.testcase_filename, 'w') 31 | f.close() 32 | wookbook = xlwt.Workbook() # 创建工作簿 33 | return wookbook 34 | 35 | def __init_outline_wooksheek(self): 36 | """ 37 | 初始化测试大纲sheet 38 | :return: 39 | """ 40 | outline_wooksheek = self.wookbook.add_sheet('测试大纲', cell_overwrite_ok='True') # 测试大纲 41 | for i in range(13): 42 | outline_wooksheek.col(i).width = (13 * 367) 43 | if i in [6, 7]: 44 | outline_wooksheek.col(i).width = (25 * 500) 45 | if i in [7]: 46 | outline_wooksheek.col(i).width = (20 * 400) 47 | if i in [4, 8, 9, 10, 11, 12]: 48 | outline_wooksheek.col(i).width = (13 * 200) 49 | # 表头标题 50 | head = ['需求编号', '功能模块', '功能名称', '功能点', '用例类型', '检查点', '用例设计', '预期结果', '类别', 51 | '责任人', '状态', '更新日期', '用例编号'] #子功能名称 52 | index = 0 53 | for head_item in head: 54 | outline_wooksheek.write(0, index, head_item, self.style) 55 | index += 1 56 | self.save_excel() 57 | return outline_wooksheek 58 | 59 | def __init_testcase_wooksheek(self): 60 | """ 61 | 初始化测试用例sheet 62 | :return: 63 | """ 64 | testcase_wooksheek = self.wookbook.add_sheet('测试用例', cell_overwrite_ok='True') # 测试用例 65 | for i in range(12): 66 | testcase_wooksheek.col(i).width = (15 * 367) 67 | if i in [3, 4]: 68 | testcase_wooksheek.col(i).width = (25 * 500) 69 | if i in [4]: 70 | testcase_wooksheek.col(i).width = (20 * 400) 71 | if i in [5, 6, 7, 8, 9, 10, 11]: 72 | testcase_wooksheek.col(i).width = (13 * 200) 73 | if i in [11]: 74 | testcase_wooksheek.col(i).width = (17 * 220) 75 | head = ['用例目录', '用例名称', '前置条件', '用例步骤', '预期结果', '用例类型', '用例状态', '用例等级', '需求ID', 76 | '创建人', '测试结果', '是否开发自测'] 77 | index = 0 78 | for head_item in head: 79 | testcase_wooksheek.write(0, index, head_item, self.style) 80 | index += 1 81 | self.save_excel() 82 | return testcase_wooksheek 83 | 84 | def __init_testscope_wooksheek(self): 85 | """ 86 | 初始化测试范围 87 | :return: 88 | """ 89 | testscope_wooksheek = self.wookbook.add_sheet('测试范围', cell_overwrite_ok='True') # 测试范围 90 | for i in range(7): 91 | testscope_wooksheek.col(i).width = (13 * 367) 92 | # 表头标题 93 | head = ['序号', '功能模块', '功能名称', '角色', '责任人', '更新日期', '备注'] #子功能名称 94 | index = 0 95 | for head_item in head: 96 | testscope_wooksheek.write(0, index, head_item, self.style) 97 | index += 1 98 | self.save_excel() 99 | return testscope_wooksheek 100 | 101 | def __init_analysis_wooksheek(self): 102 | """ 103 | 初始化测试分析 104 | :return: 105 | """ 106 | analysis_wooksheek = self.wookbook.add_sheet('测试分析', cell_overwrite_ok='True') # 测试范围 107 | # testcase_wooksheek.col(0).width = 256 108 | for i in range(10): 109 | analysis_wooksheek.col(i).width = (10 * 367) 110 | analysis_wooksheek.write_merge(1, 1, 1,9,'测试覆盖范围及执行结果', self.style) 111 | analysis_wooksheek.write(2, 1, '项目', self.style_nocenter) 112 | analysis_wooksheek.write_merge(2, 2, 2,3,'', self.style_nocenter) 113 | analysis_wooksheek.write(2, 4,'需求编号', self.style_nocenter) 114 | analysis_wooksheek.write_merge(2, 2,5,7,'', self.style_nocenter) 115 | analysis_wooksheek.write(2, 8, '产品', self.style_nocenter) 116 | analysis_wooksheek.write(2, 9, '',self.style_nocenter) 117 | analysis_wooksheek.write(3, 1, '投产日期', self.style_nocenter) 118 | analysis_wooksheek.write_merge(3, 3, 2,3,'', self.style_nocenter) 119 | analysis_wooksheek.write(3, 4,'迭代编号', self.style_nocenter) 120 | analysis_wooksheek.write_merge(3, 3,5,7,'', self.style_nocenter) 121 | analysis_wooksheek.write(3, 8, '测试周期', self.style_nocenter) 122 | analysis_wooksheek.write(3, 9, '', self.style_nocenter) 123 | analysis_wooksheek.write(4, 1, '测试人员', self.style_nocenter) 124 | analysis_wooksheek.write_merge(4, 4,2,9, '', self.style_nocenter) 125 | analysis_wooksheek.write(5, 1, '环境',self.style_nocenter) 126 | analysis_wooksheek.write_merge(5, 5,2,9, 'SIT/UAT/生产',self.style_nocenter) 127 | # 第 7 行内容 128 | lines = ['模块', 'Total', 'Pass', 'Fail', 'Block', 'NA', 'Not Run', 'Run Rate', 'Pass Rate'] 129 | index = 1 130 | for head_item in lines: 131 | analysis_wooksheek.write(6, index, head_item, self.style) 132 | index += 1 133 | self.save_excel() 134 | return analysis_wooksheek 135 | 136 | def write_outline_excel(self,new_testcase): 137 | """ 138 | 写入测试大纲excel 139 | :param new_testcase:写入的列表信息 140 | :return: 141 | """ 142 | style = xlwt.easyxf('borders:left 1,right 1,top 1,bottom 1,bottom_colour 0x3A') 143 | for i in range(13): 144 | self.outline_wooksheek.write(self.__row, i, "", style) 145 | col=1 146 | for item in new_testcase[0][1:]: 147 | if col==4: 148 | self.outline_wooksheek.write(self.__row, col, '功能', style) 149 | col+=1 150 | self.outline_wooksheek.write(self.__row, col, item, style) 151 | else: 152 | self.outline_wooksheek.write(self.__row, col, item, style) 153 | col += 1 154 | if new_testcase[1]: 155 | self.outline_wooksheek.write(self.__row, 7, new_testcase[1],style) 156 | self.outline_wooksheek.write(self.__row, 4, '功能',style) 157 | self.outline_wooksheek.write(self.__row, 10, 'Not Run',style) 158 | date_time=datetime.date.today() 159 | self.outline_wooksheek.write(self.__row, 11, str(date_time), style) 160 | self.__row+=1 161 | 162 | def write_testcase_excel(self,new_testcase): 163 | """ 164 | 写入测试用例excel 165 | :param new_testcase:写入的列表信息 166 | :return: 167 | """ 168 | style = xlwt.easyxf('borders:left 1,right 1,top 1,bottom 1,bottom_colour 0x3A') 169 | for i in range(12): 170 | self.testcase_wooksheek.write(self.__row, i, "", style) 171 | # if len(new_testcase[0])>=1: 172 | # self.testcase_wooksheek.write(self.__row, 0, new_testcase[0][0], style) 173 | if len(new_testcase[0])>=2: 174 | # self.testcase_wooksheek.write(self.__row, 0, new_testcase[0][0] + '-' +new_testcase[0][1], style) 175 | self.testcase_wooksheek.write(self.__row, 0, new_testcase[0][1], style) 176 | self.testcase_wooksheek.write(self.__row, 2, '1.进入【'+new_testcase[0][1]+'】界面;', style) 177 | if len(new_testcase[0])>=3: 178 | self.testcase_wooksheek.write(self.__row, 1, new_testcase[0][2], style) 179 | self.testcase_wooksheek.write(self.__row, 2, '1.进入【'+new_testcase[0][1]+'-'+new_testcase[0][2]+'】界面;', style) 180 | if len(new_testcase[0]) >= 5: 181 | self.testcase_wooksheek.write(self.__row, 1, new_testcase[0][3] + '-' + new_testcase[0][4], style) 182 | if len(new_testcase[0]) >= 6: 183 | self.testcase_wooksheek.write(self.__row, 3, new_testcase[0][5], style) 184 | if new_testcase[1]: 185 | self.testcase_wooksheek.write(self.__row, 4, new_testcase[1], style) 186 | self.testcase_wooksheek.write(self.__row, 5, '功能测试', style) 187 | self.testcase_wooksheek.write(self.__row, 6, '正常', style) 188 | self.testcase_wooksheek.write(self.__row, 7, '中', style) 189 | self.testcase_wooksheek.write(self.__row, 10, 'Not Run', style) 190 | self.testcase_wooksheek.write(self.__row, 11, '否', style) 191 | # self.__row+=1 192 | 193 | def write_testscope_wooksheek(self,new_testcase): 194 | """ 195 | 写入测试范围sheet 196 | :param new_testcase: 197 | :return: 198 | """ 199 | style = xlwt.easyxf('borders:left 1,right 1,top 1,bottom 1,bottom_colour 0x3A') 200 | item_list=new_testcase[0][1:3] 201 | col=1 202 | if item_list not in self.__temp_list: 203 | self.__temp_list.append(item_list) 204 | for i in range(7): 205 | self.testscope_wooksheek.write(self.__testscope_row, i, "", style) 206 | for item in item_list: 207 | self.testscope_wooksheek.write(self.__testscope_row, col, item,style) 208 | col+=1 209 | self.__testscope_row+=1 210 | 211 | def write_analysis_wooksheek(self): 212 | """ 213 | 写入测试分析excel 214 | :return: 215 | """ 216 | row=7 217 | temp_list=[] 218 | for item in self.__temp_list: 219 | if len(item)>=1: 220 | if item[0] not in temp_list: 221 | temp_list.append(item[0]) 222 | self.analysis_wooksheek.write(row,1,item[0],self.style_center) 223 | self.analysis_wooksheek.write(row,2, "=COUNTIF(测试用例!A:A,B"+str(row+1)+")", self.style_center) 224 | self.analysis_wooksheek.write(row,3, "=COUNTIFS(测试用例!A:A,B"+str(row+1)+''',测试用例!K:K,"Pass")''', self.style_center) 225 | self.analysis_wooksheek.write(row,4, "=COUNTIFS(测试用例!A:A,B"+str(row+1)+''',测试用例!K:K,"Fail")''', self.style_center) 226 | self.analysis_wooksheek.write(row,5, "=COUNTIFS(测试用例!A:A,B"+str(row+1)+''',测试用例!K:K,"Block")''', self.style_center) 227 | self.analysis_wooksheek.write(row,6, "=COUNTIFS(测试用例!A:A,B"+str(row+1)+''',测试用例!K:K,"NA")''', self.style_center) 228 | self.analysis_wooksheek.write(row,7, "=COUNTIFS(测试用例!A:A,B"+str(row+1)+''',测试用例!K:K,"Not Run")''', self.style_center) 229 | self.analysis_wooksheek.write(row,8, xlwt.Formula("SUM(D"+str(row+1)+":F"+str(row+1)+")/(C"+str(row+1)+"-G"+str(row+1)+")"), self.style_num) 230 | self.analysis_wooksheek.write(row,9, xlwt.Formula("D"+str(row+1)+"/(C"+str(row+1)+"-G"+str(row+1)+")"), self.style_num) 231 | row += 1 232 | else: 233 | lines = ['', 0, 0, 0, 0, 0, 0, '0.00%', '0.00%'] 234 | index = 1 235 | for head_item in lines: 236 | self.analysis_wooksheek.write(row, index, head_item, self.style) 237 | index += 1 238 | row += 1 239 | self.analysis_wooksheek.write(row, 1, '总计', self.style_center) 240 | self.analysis_wooksheek.write(row, 2, xlwt.Formula("SUM(C8:C"+str(row)+")"),self.style_center) 241 | self.analysis_wooksheek.write(row, 3, xlwt.Formula("SUM(D8:D"+str(row)+")"),self.style_center) 242 | self.analysis_wooksheek.write(row, 4, xlwt.Formula("SUM(E8:E"+str(row)+")"),self.style_center) 243 | self.analysis_wooksheek.write(row, 5, xlwt.Formula("SUM(F8:F"+str(row)+")"),self.style_center) 244 | self.analysis_wooksheek.write(row, 6, xlwt.Formula("SUM(G8:G"+str(row)+")"),self.style_center) 245 | self.analysis_wooksheek.write(row, 7, xlwt.Formula("SUM(H8:H"+str(row)+")"),self.style_center) 246 | self.analysis_wooksheek.write(row, 8, xlwt.Formula("SUM(D"+str(row+1)+":F"+str(row+1)+")/(C"+str(row+1)+"-G"+str(row+1)+")"), self.style_num) 247 | self.analysis_wooksheek.write(row, 9, xlwt.Formula("D"+str(row+1)+"/(C"+str(row+1)+"-G"+str(row+1)+")"), self.style_num) 248 | row += 2 249 | self.analysis_wooksheek.write(row, 1, '说明:') 250 | row+=1 251 | self.analysis_wooksheek.write(row, 1, 'Pass-验证通过 Fail-验证未通过 Block-阻塞 NA-本期不涉及 Not Run-尚未执行') 252 | row+=1 253 | self.analysis_wooksheek.write(row, 1, 'Run Rate=(Pass+Fail+Block)/(Total-NA)') 254 | self.analysis_wooksheek.write(row+1, 1, 'Pass Rate=Pass/(Total-NA)') 255 | 256 | def save_excel(self): 257 | """ 258 | 保存excel 259 | :return: 260 | """ 261 | self.wookbook.save(self.testcase_filename) 262 | --------------------------------------------------------------------------------