def copy_file(self, srcPath, destPath): ''' srcPath:源文件(夹)路径 destPath:目标文件(夹)路径,必须不存在 return: ''' destfile = self.get_file_list(destPath) srcfile = self.get_file_list(srcPath) file_list = [] for df in destfile: file_list.append(df.split("\\")[len(df.split("\\")) - 1]) for sf in srcfile: if sf.split("\\")[len(sf.split("\\")) - 1] not in file_list: log.info( "{}文件不存在于备份目录才执行".format(sf.split("\\")[len(sf.split("\\")) - 1])) # print(config.back_path + sf.split("\\")[len(sf.split("\\")) - 2] + '\\' + sf.split("\\")[len(sf.split("\\")) - 1]) destDir = config.back_path + \ sf.split("\\")[len(sf.split("\\")) - 2] + "\\" if not os.path.exists(destDir): os.makedirs(destDir) shutil.copyfile( sf, destDir + sf.split("\\")[len(sf.split("\\")) - 1])
def set_section_value(self, section, option, value): '''设置section:option的值''' if not self.conf.has_section(section): log.info("{}不存在,需要新增!".format(section)) self.conf.add_section(section) self.conf.set(section, option, value) self.conf.write(open(self.file_path, "w")) else: self.conf.set(section, option, value) self.conf.write(open(self.file_path, "w"))
def write_data(res, json_path): """ 把处理后的参数写入json文件 :param res: :param json_path: :return: """ if isinstance(res, dict) or isinstance(res, list): with open(json_path, 'w', encoding='utf-8') as f: json.dump(res, f, ensure_ascii=False, sort_keys=True, indent=4) logger.info('Interface Params Total:{} ,write to json file successfully!'.format(len(res))) else: logger.error('\n:{} Params is not dict.\n'.format(write_data.__name__))
def copy_dir(self, srcPath, destPath): ''' copytree:文件(夹)移动,不可覆盖 srcPath:源文件(夹)路径 destPath:目标文件(夹)路径,必须不存在 return: ''' # 判断目录是否存在 if os.path.isdir(destPath): log.info("{}存在则删除".format(destPath)) shutil.rmtree(destPath) try: shutil.copytree(srcPath, destPath) except Exception as e: raise e
def get_file_list(self, filepath): ''' 获取文件夹下所有文件名 filepath:文件路径 return:返回文件夹下及子目录的所有文件 ''' filepath_list = [] for root_dir, sub_dir, files in os.walk(filepath): # print('root_dir:', root_dir) # 当前目录路径 # print('sub_dirs:', sub_dir) # 当前路径下所有子目录 log.info(sub_dir) # print('file_name:', files) # 当前路径下所有非目录子文件 for i in range(0, len(files)): filepath_list.append(root_dir + "\\" + files[i]) return filepath_list
def read_excel(file_path, sheet_name="Sheet1"): '''读取excel表格''' datas = [] # 储存xlsx文件的所有数据 xlsx_file = {} # 存储源xls文件 wb = xlrd.open_workbook(file_path) # 打开目标文件 # sheet_num = len(wb.sheets()) #获取xlsx表单数量 sheet_name_list = wb.sheet_names() # 获取xlsx表单名字 if sheet_name in sheet_name_list: sheet_name = wb.sheet_by_name(sheet_name) for rows in range(0, sheet_name.nrows): orign_list = sheet_name.row_values(rows) # 源表i行数据 xlsx_file[rows] = orign_list # 源表写入字典 else: log.info("{}子表名不存在{}文件中!".format(sheet_name, file_path)) for row in range(1, len(xlsx_file)): data = dict(zip(xlsx_file[0], xlsx_file[row])) datas.append(data) return datas
def diff_dir_file(self, srcPath, destPath): ''' 比较两个文件夹及子目录下的文件 ''' if os.path.isfile(diffFile): try: # 删除文件前先备份文件 shutil.copyfile(diffFile, backupDiffFile) os.remove(diffFile) except Exception as e: log.error("备份/删除文件:%s,失败!" % diffFile) raise e else: log.info("no such file:%s" % diffFile) # 获取目录下的所有文件,返回list srcfile = self.get_file_list(srcPath) destfile = self.get_file_list(destPath) for sf in srcfile: for df in destfile: if sf.split("\\")[len(sf.split("\\")) - 1] == df.split("\\")[len(df.split("\\")) - 1]: self.diff_json(sf, df)
def analysis_json_data(self, isDuplicated=False): """ 解析json格式数据的主函数 :return: """ # swagger接口文档地址,其中运营后台的接口地址,请求分模块,全量或者其他服务菜单 if "9527" in self.url: try: # 这才是swagger接口请求的地址 res = requests.get(self.url + '/v2/api-docs?group=全量接口').json() write_data(res, 'data.json') except Exception as e: log.error('请求swagger地址错误. 异常如下: {}'.format(e)) raise e else: try: # 这才是swagger接口请求的地址 res = requests.get(self.url + '/v2/api-docs').json() write_data(res, 'data.json') except Exception as e: log.error('请求swagger地址错误. 异常如下: {}'.format(e)) raise e # 生成完整的json测试用例之后,开始备份接口数据 ,以备作为接口变更的依据 if isDuplicated: # 备份文件,如果不存在备份目录则备份,否则的实现方案在其他方法内 if not os.path.exists(config.back_path): handlefile.copy_dir(config.case_path, config.back_path) self.data = res['paths'] # 取接口地址返回的path数据,包括了请求的路径 self.basePath = res['basePath'] # 获取接口的根路径/hcp # 第一错,swagger文档是ip地址,使用https协议会错误,注意接口地址的请求协议 self.url = 'http://' + res['host'] self.title = res['info']['title'] # 获取接口的标题 self.http_suite['config']['name'] = self.title # 在初始化用例集字典更新值 self.http_suite['config']['base_url'] = self.url self.definitions = res['definitions'] # body参数 for tag_dict in res['tags']: self.tags_list.append(tag_dict['name']) i = 0 for tag in self.tags_list: self.http_suite['testcases'].append({ "name": "", "testcase": "", "variables": {} }) self.http_suite['testcases'][i]['name'] = tag self.http_suite['testcases'][i][ 'testcase'] = 'testcases/' + tag + '.json' i += 1 suite_path = config.testsuites_path # 测试用例集目录不存在,则创建 if not os.path.exists(suite_path): os.makedirs(suite_path) testsuite_json_path = os.path.join( suite_path, '{}_testsuites.json'.format(self.title)) # 数据写入 write_data(self.http_suite, testsuite_json_path) if isinstance(self.data, dict): # 判断接口返回的paths数据类型是否dict类型 # 前面已经把接口返回的结果tags分别写入了tags_list空列表,再从json对应的tag往里面插入数据 for tag in self.tags_list: self.http_case = { "config": { "name": "", "base_url": "", "variables": {} }, "teststeps": [] } for key, value in self.data.items(): for method in list(value.keys()): params = value[method] # deprecated字段标识:接口是否被弃用,暂时无法判断,使用consumes偷换 if not 'deprecated' in value.keys(): if params['tags'][0] == tag: self.http_case['config']['name'] = params[ 'tags'][0] self.http_case['config']['base_url'] = self.url case = self.wash_params( params, key, method, tag) self.http_case['teststeps'].append(case) else: log.info( 'interface path: {}, if name: {}, is deprecated.' .format(key, params['operationId'])) break testcases_path = config.testcases_path # testcases目录不存在则创建 if not os.path.exists(testcases_path): os.makedirs(testcases_path) testcase_json_path = os.path.join(testcases_path, tag + '.json') # 生成testcase文件 write_data(self.http_case, testcase_json_path.replace("/", "_")) else: log.error('解析接口数据异常!url 返回值 paths 中不是字典.') return 'error'