def md5_file(self, filename): ''' 比较两个文件内容的md5值 ''' m = md5() try: with open(filename, 'rb') as a_file: # 需要使用二进制格式读取文件内容 m.update(a_file.read()) except Exception as e: log.error("文件读取失败:" + e) return m.hexdigest()
def read_json(self, filename): ''' 读取json格式文件的数据,进行内容分割 ''' try: with open(filename, 'r', encoding='utf-8') as fileHandle: text = fileHandle.read().splitlines() return text except IOError as e: log.error("文件读取失败:" + e) sys.exit()
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 diff_json(self, filename1, filename2): ''' 比较两个文件内容的md5值;比较两个文件并输出到html文件中 ''' file1Md5 = self.md5_file(filename1) file2Md5 = self.md5_file(filename2) if file1Md5 != file2Md5: # log.info('两个json数据文件md5不一样:') text1_lines = self.read_json(filename1) text2_lines = self.read_json(filename2) d = difflib.HtmlDiff() # context=True时只显示差异的上下文,默认显示5行,由numlines参数控制,context=False显示全文,差异部分颜色高亮,默认为显示全文 result = d.make_file( text1_lines, text2_lines, filename1, filename2, context=True) # 内容保存到result.html文件中 try: with open(diffFile, 'a', encoding='utf-8') as result_file: result_file.write(result) except Exception as e: log.error("写入文件失败:" + e)
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'