def __init__(self, data_source, version): self.dic_args = {} self.key_list = [] # 存储json接口返回的key值集合 self.product_dict = {} # 存储接口对应产品key值集合字典 {"1024": [xx,xxx]} self.result = Result() self.Verify = _Verify() self.upload_files = {} self.cur_path = "" self.ini_path = "" self.urlparam = "" self.default_data_dict = {} self.version = version self.data_source = data_source self.session = requests.session() self.api_len = len(data_source) / 3 # =========路径,产品,执行接口获取; eg:msp.apply.01;msp.apply:interface_a;interface_b ========== # self.data_source_apis = self.data_source[0].split(":") # 用 :对datasource的第一个元素进行拆分 # self.apis = self.json_replace_data(self.data_source_apis[1]) # 入参是接口名 取出接口名 # self.interface_path_product = self.json_replace_data(self.data_source_apis[0]) # 入参是 msp.apply.01 # self.api_name = self.interface_path_product[0].split(".")[0] # 取出了 msp # self.api_len = len(self.apis) self.api_name = self.data_source[0].split(":")[0].split(".")[0] # ================获取接口属性===================== self.api_def_dic = EnvSetting.ENV_DEF_DIC self.db_def_dic = EnvSetting.ENV_DB_DIC self.version_dict = EnvSetting.VERSION self.env_pro_dic = self.api_def_dic.get(self.api_name) self.token_key = self.env_pro_dic.get("token_key", "") self.version_info = self.version_dict.get(version) self.version_port = self.version_info.get( "port", self.env_pro_dic.get("port", "")) self.version_url = self.version_info.get( "url", self.env_pro_dic.get("url", "")) self.version_uri = self.version_info.get( "uri", self.env_pro_dic.get("uri", "")) self.version_url = self.concat_url() self.ini_name_list = self.env_pro_dic["api_ini_name"]
def __init__(self, data_source, version): self.dic_args = {} self.result = Result() self.Verify = _Verify() self.upload_files = {} self.cur_path = "" self.ini_path = "" self.urlparam = "" self.default_data_dict = {} self.version = version self.data_source = data_source # =========路径,产品,执行接口获取; eg:msp.apply.01;msp.apply:interface_a;interface_b ========== self.data_source_apis = self.data_source[0].split( ":") # 用 :对datasource的第一个元素进行拆分 self.apis = self.html_replace_data( self.data_source_apis[1]) # 入参是接口名 取出接口名 self.interface_path_product = self.html_replace_data( self.data_source_apis[0]) # 入参是 msp.01 self.api_name = self.interface_path_product[0].split(".")[0] # 取出了 msp self.api_len = len(self.apis) # ================获取接口属性===================== self.api_def_dic = EnvSetting.ENV_DEF_DIC self.db_def_dic = EnvSetting.ENV_DB_DIC self.version_dict = EnvSetting.VERSION self.env_pro_dic = self.api_def_dic.get(self.api_name) self.token_key = self.env_pro_dic.get("token_key", "") self.version_info = self.version_dict.get(version) self.version_port = self.version_info.get( "port", self.env_pro_dic.get("port", "")) self.version_url = self.version_info.get( "url", self.env_pro_dic.get("url", "")) self.version_uri = self.version_info.get( "uri", self.env_pro_dic.get("uri", "")) self.version_url = self.concat_url() self.ini_name_list = self.env_pro_dic["api_ini_name"]
def html_model_pub(data_source, version="1221", model="ride"): dic_args = {} result = Result() Verify = _Verify() upload_files = {} ini_path = "" urlparam = "" default_data_dict = {} # ============请求头信息(需要的则自行添加)=========== # 手动添加一下header防反爬 --ChunkedEncodingError: ("Connection broken: error(10054, '')", error(10054, ''))报错 headers = { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "zh-CN,zh;q=0.9", "Connection": "keep-alive", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" } headers_wechat = { "Accept": "application/json, text/plain, */*", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", "Connection": "keep-alive", "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602." } authorization = "" # =================================================== j = 0 # return if model == "ride": path = os.path.abspath('.') else: path = os.path.abspath('../..') # =============路径,产品,执行接口获取;eg:msp.apply.01;msp.apply:interface_a;interface_b============= data_source_apis = data_source[0].split(":") # 用 :对datasource的第一个元素进行拆分 apis = html_replace_data(data_source_apis[1]) # 入参是接口名 取出接口名 interface_path_product = html_replace_data( data_source_apis[0]) # 入参是 msp.apply.01 api_name = interface_path_product[0].split(".")[0] # 取出了 msp api_len = len(apis) # ================获取接口属性===================== api_def_dic = EnvSetting.ENV_DEF_DIC version_dict = EnvSetting.VERSION version_info = version_dict.get(version) version_port = version_info["port"] version_url = version_info.get("url", "") env_pro_dic = api_def_dic.get(api_name) main_url = env_pro_dic["url"] # ========获取url截取点========== main_url = change_url_port(main_url, version_port, version_url) login_url = get_login_url(main_url) # ============================== ini_name_list = env_pro_dic["api_ini_name"] # ====循环对比接口和数据ini文件,取到第一个接口数据所在的ini文件,主要是为了先获取登录参数,看第一个接口是否需要登录 for ini_name in ini_name_list: cur_path = r'%s\config\api\%s' % (path, api_name) ini_path = r"%s\%s" % (cur_path, ini_name) # 循环读取ini文件,找到接口数据所在的ini文件 default_data_dict = get_ini_default_contant(ini_path, None, None)[0] if apis[0] in default_data_dict.keys(): break # 执行案例前清空CASE_GEN_DIC '''PS:经验证不能使用Settings.CASE_GEN_DIC = {},否则后续其他用例调用值一直保持第一次的, 原因分析?: Settings.CASE_GEN_DIC = {} 对CASE_GEN_DIC的引用改变了,CASE_GEN_DIC的值未改变;clear则清空该引用中的值 ''' Settings.CASE_GEN_DIC.clear() '''获取cookies (调试接口用)=====有登陆接口传{}即可==============================================''' # default_cookies = RHIniParser(ini_path).get_ini_info("COOKIES", "SET_COOKIES") # cookies = str_to_dict(default_cookies, ";", "=") cookies = {} '''===========================================================================================''' '''========================判断系统是否需要登录==================================================''' login_sign = RHIniParser(ini_path).get_ini_info("IS_LOGIN", "LOGIN_SIGN") if login_sign is "Y": # 获取登录请求地址 # 利用有序OrderedDict 有序读取url(有些登录需要验证码,需现请求获取验证码接口,防止验证码过期) login_url_dict = json.loads(RHIniParser(ini_path).get_ini_info( "IS_LOGIN", "LOGIN_URL"), object_pairs_hook=OrderedDict) for url in login_url_dict.keys(): ini_contant = get_ini_default_contant(ini_path, url, None) request_method = ini_contant[1] in_para_dic = ini_contant[2] out_para_dic = ini_contant[2] default_re_set = ini_contant[3] post_data = transfor_to_dict(login_url_dict[url]) # 若为登录请求接口,替换对应参数兼容各个版本 change_login_dic(api_name, post_data, version_port) # 替换urlinput设置的变量--url url = change_in_html_urldic(in_para_dic, dic_args, url, urlparam) # 替换in out设置的变量--data change_in_html_dic(in_para_dic, dic_args, post_data) response_html = html_request(login_url + url, post_data, request_method) # 获取正则表达式列表 default_re = default_re_set.split(";") # 存储特定返回值 out = get_out_html_dic(out_para_dic, response_html, default_re) dic_args = get_new_dic(dic_args, out) '''===========================================================================================''' for i in xrange(api_len): # (0,2) interface_name = apis[i] api = Core.rh_get_api_name(apis[i]) # 再次循环对比接口和数据ini文件,取到接口数据所在的ini文件,支持多个ini文件存储数据 for ini_name in ini_name_list: cur_path = r'%s\config\api\%s' % (path, api_name) ini_path = r"%s\%s" % (cur_path, ini_name) # 循环读取ini文件,找到接口数据所在的ini文件 default_data_dict = get_ini_default_contant(ini_path, None, None)[0] default_dbdata_dict = get_ini_default_contant( ini_path, None, None)[4] if apis[i] in default_data_dict.keys( ) or apis[i] in default_dbdata_dict.keys(): break # 读取接口路径, 产品 [msp.apply.01; msp.apply; msp.tools.03 ] if len(interface_path_product) == 1: path_list = interface_path_product[0].split(".") model = path_list[1] if len(path_list) == 3: product_name = path_list[2] else: product_name = None else: path_list = interface_path_product[i].split(".") model = path_list[1] if len(path_list) == 3: product_name = path_list[2] else: product_name = None model_url = json.loads( RHIniParser(ini_path).get_ini_info("MODEL_URL", "MODEL_URL_DATA"))[model] ini_contant = get_ini_default_contant(ini_path, api, product_name) # 若为移动端接口,则一般为默认443或则80端口,需要把端口号去掉 --如有需要处理的,自行添加。 if "newWechat" in model or "bplan" in model: main_url = main_url.replace(version_port, "") if ".db" not in api and ".dmldb" not in api: # 读取对应api接口的默认值,请求方式,出入参设置,正则表达式,特定返回值 default_contant = ini_contant[0] request_method = ini_contant[1] in_para_dic = ini_contant[2] out_para_dic = ini_contant[2] default_re_set = ini_contant[3] # 原始数据转成dict default_contant = transfor_to_dict(default_contant) if "||" in data_source[i * 2 + 1 - j]: # 对rf的表格的取值,替换列的,注意替换项必须和url里面的一致 urlparam = data_source[i * 2 + 1 - j].split("||")[1] # 替换urlinput设置的变量--url interface_name = change_in_html_urldic(in_para_dic, dic_args, interface_name, urlparam) #szx特殊处理 if interface_name == 'savePolicyInfo.do' and product_name[ -2:] == '01': wtr_num = 0 scanmock_result = query_scanmock_result( str(default_contant["applyBarCode"])[:-2]) while (not scanmock_result.flag) and wtr_num <= 5: scanmock_result = query_scanmock_result( str(default_contant["applyBarCode"])[:-2]) # print 'waiting %s' % Settings.EXTREME_TIMEOUT sleep(Settings.EXTREME_TIMEOUT) wtr_num += 1 if api == 'addApplyInfo/passSaveApplyInfo.do': sleep(20) # 替换设置的参数值 change_para_html(default_contant, data_source[i * 2 + 1 - j].split( "||")[0]) # data_source[1] data_source[3]... #szx特殊处理 if interface_name == 'savePolicyInfo.do' and product_name[ -2:] == '02': dic_args = uw_query_ins_or_prem( str(default_contant["applyBarCode"]), dic_args) # 替换in out设置的变量--data change_in_html_dic(in_para_dic, dic_args, default_contant) # 更新token, 放入请求hearder中 authorization = change_in_token_dic(in_para_dic, dic_args, authorization) # ============请求hearder组装 如有需要,自行处理==================== # 微信快易投需要用token验证 if "newWechat" in model: headers = dict(headers_wechat, **{"authorization": "Bearer " + authorization}) '''上传照片接口单独处理获取照片''' if api.__contains__("imageUploding"): local_files = json.loads( RHIniParser(ini_path).get_ini_info( "UPLOAD", "UPLOAD_DEFAULT_FILES"))[api] upload_files = upload_files_format(local_files, path) print "请求接口: " + main_url + model_url + interface_name # print default_contant # 发送请求 response_html = html_request(main_url + model_url + interface_name, default_contant, cookies, upload_files, request_method, headers) data = Core.rh_replace_data(data_source[i * 2 + 2 - j]) for i in data: res = rh_html_check_result(i, response_html) if "[success]" not in res: logger.error( "%s failed:\n***********post data:\n%s\n***********response data:%s" % (api, default_contant, response_html)) Verify.should_contain(res, "[success]") # 获取正则表达式列表 default_re = default_re_set.split(";") # 存储特定返回值 out = get_out_html_dic(out_para_dic, response_html, default_re) dic_args = get_new_dic(dic_args, out) print "%s:%s" % (api, dic_args) # =================================================================================== # ============若无DB检查点,可以暂时忽略该部分代码,若需要添加,自行修改==================== elif ".db" in api: j += 2 # 对于DB校验sql取数,产品取db前一个接口对应的产品。 # 获取检验的sql sql_list = ini_contant # 避免程序入库事务还未完成就执行DB校验,故等待1秒 sleep(1) # 注意 此处传过去的sql为list(多条) 格式:saveApproval.slis.db if 'msp' in api_name: result = check_db(sql_list, version, api.split('.')[1], dic_args["applyBarCode"].split()) else: result = check_db(sql_list, version, api.split('.')[1]) if not result.flag: logger.info(result.msg, "%s failed" % api) print result.msg, "%s failed" % api Verify.should_be_true(result.flag) print "%s success" % api logger.info("%s success" % api) # ==========若有需要,执行回滚脚本======================================# else: j += 2 # 对于DB回滚sql取数,产品取db前一个接口对应的产品。 # 获取需要回滚的sql rollback_sqllist = ini_contant # 避免程序入库事务还未完成就执行DB校验,故等待1秒 sleep(1) # 执行回滚操作 try: dml_db(rollback_sqllist, version, api.split('.')[1]) print "%s success" % api logger.info("%s success" % api) except Exception, e: raise Exception("error occur in sql rollback, %s", str(e))
def checkout(self): glabalvalue = GetParmsValue() verify = _Verify() # 全局变量校验并入库(如果校验的时候不进行入库,那么在保存的时候有要去重新查一下全局路径对应的全局字段值) if (len(self.global_route) != 0): print(self.global_route) res = glabalvalue.get_parms_value_from_key(self.global_route, self.global_name, self.env, self.actual_response,self.user) if (res['success'] == False): return res # else: # print('未设置全局变量') # 校验值路径是否存在 if (self.route not in ('', None)): self.actual_field_list = [] route_list = self.route.split(';') for r in route_list: # 替换参数 if ('{{' in r): getparmsvalue = GetParmsValue() r = getparmsvalue.get_parms_value(self.route, self.env) try: self.actual_field_list.append(self.getmyvalue(self.actual_response, r)) except: return ({"success": False, "msg": "无法获取" + str(r) + "对应的value"}) # else: # print("该接口没有设置校验值路径") # 校验 if ((self.route in ('', None)) and (self.expected_response not in ('', None))): # 校验块内容字段 try: # 替换参数 if ('{{' in self.expected_response): getparmsvalue = GetParmsValue() self.expected_response = getparmsvalue.get_parms_value(self.expected_response, self.env) verify.should_contain(''.join(self.actual_response.split()), ''.join(self.expected_response.split())) print('返回结果中' + self.actual_response + '字段中包含预期返回值 ' + self.expected_response + "全部字段") except Exception as e: print(e) return {"success": False, "msg": "返回结果中不包含预期返回值全部字段,请检查!"} return {"success": True, "msg": "OK"} elif ((self.route not in ('', None)) and (self.expected_response in ('', None))): expected_field_list = self.expected_field.split(';') print('') i = 0 for route, actual_field,check_type in zip(self.route.split(';'), self.actual_field_list,self.types.split(';')): i += 1 # 替换参数 try: if ('{{' in expected_field_list[i - 1]): getparmsvalue = GetParmsValue() expected_field_list[i - 1] = getparmsvalue.get_parms_value(expected_field_list[i - 1], self.env) if(check_type=='equal' or check_type == ''): if (actual_field == expected_field_list[i - 1]): print('接口返回数据中' + str(route) + '校验路径字段值匹配成功为' + actual_field) else: return {"success": False, "msg": '接口返回数据中' + str(route) + '校验路径字段值应该为' + expected_field_list[ i - 1] + ',而不是' + actual_field} elif(check_type=='regex'): actual_field = actual_field.strip('"') if('\\\\'in expected_field_list[i - 1]): # expected_field_new=eval(expected_field_list[i - 1]) expected_field_new=expected_field_list[i - 1].replace('\\\\','\\') regex_result=re.search(expected_field_new,actual_field,re.I|re.M|re.S) else: # A=expected_field_list[i - 1] regex_result=re.search(expected_field_list[i - 1],actual_field,re.I|re.M|re.S) if(regex_result): print('接口返回数据中' + str(route) + '校验路径字段值正则匹配成功为' + actual_field) else: return {"success": False, "msg": '接口返回数据中' + str(route) + '路径的字段值' + actual_field + '匹配正则'+expected_field_list[ i - 1]+'失败'} else: return {"success": False, "msg": "校验类型无法匹配"} except: return {"success": False, "msg": "请检查使用的全局变量"} return {"success": True, "msg": "OK"} elif ((self.route not in ('', None)) and (self.expected_response not in ('', None))): # 校验某些字段 try: # 替换参数 if ('{{' in self.expected_response): getparmsvalue = GetParmsValue() self.expected_response = getparmsvalue.get_parms_value(self.expected_response, self.env) verify.should_contain(''.join(self.actual_response.split()), ''.join(self.expected_response.split())) print('返回结果中' + self.actual_response + '字段中包含预期返回值 ' + self.expected_response + "全部字段") except: return {"success": False, "msg": '返回结果中不包含预期返回值全部字段,' + "请检查!"} expected_field_list = self.expected_field.split(';') i = 0 for route, actual_field,check_type in zip(self.route.split(';'), self.actual_field_list,self.types.split(';')): print("route=" + route) print("actual_field=" + actual_field) i += 1 # 替换参数 try: if ('{{' in expected_field_list[i - 1]): getparmsvalue = GetParmsValue() expected_field_list[i - 1] = getparmsvalue.get_parms_value(expected_field_list[i - 1], self.env) if (check_type == 'equal' or check_type == ''): if (actual_field == expected_field_list[i - 1]): # print('接口返回数据中' + '第' + str(i) + '校验路径字段值匹配成功为' + actual_field) print('接口返回数据中' + str(route) + '校验路径字段值匹配成功为' + actual_field) else: return {"success": False, "msg": '接口返回数据中' + str(route) + '校验路径字段值应该为' + expected_field_list[ i - 1] + ',而不是' + actual_field} elif (check_type == 'regex'): actual_field = actual_field.strip('"') if ('\\\\' in expected_field_list[i - 1]): # expected_field_new=eval(expected_field_list[i - 1]) expected_field_new = expected_field_list[i - 1].replace('\\\\', '\\') # regex_result = re.match(expected_field_new, actual_field) regex_result=re.search(expected_field_new,actual_field,re.I|re.M|re.S) else: # regex_result = re.match(expected_field_list[i - 1], actual_field) regex_result=re.search(expected_field_list[i - 1],actual_field,re.I|re.M|re.S) if (regex_result): print('接口返回数据中' + str(route) + '校验路径字段值正则匹配成功为' + actual_field) else: return {"success": False, "msg": '接口返回数据中' + str(route) + '路径的字段值' + actual_field + '匹配正则'+expected_field_list[ i - 1]+'失败'} else: return {"success": False, "msg": "校验类型无法匹配"} except: return {"success": False, "msg": "请检查使用的全局变量"} return {"success": True, "msg": "OK"}
def xml_model_pub(data_source, model="ride"): dic_args = {} result = Result() Verify = _Verify() j = 0 if model == "ride": path = os.path.abspath('.') else: path = os.path.abspath('../..') data_source_apis = data_source[0].split(":") apis = xml_replace_data(data_source_apis[1]) product_path = xml_replace_data(data_source_apis[0]) project_name = product_path[0].split(".")[0] api_len = len(apis) ini_path = "%s/config/api/bank/%s/para_configuration.ini" % (path, project_name) ybt_def_dic = EnvSetting.ENV_DEF_DIC ybt_pro_dic = ybt_def_dic.get(project_name) Settings.CASE_GEN_DIC = {} for i in xrange(api_len): api = Core.rh_get_api_name(apis[i]) if ".xml" in api: if len(product_path) == 1: project_all_path = "/".join(product_path[0].split(".")) model_path = '%s/config/api/bank/%s/' % (path, project_all_path) else: project_all_path = "/".join(product_path[i - j / 2].split(".")) model_path = '%s/config/api/bank/%s/' % (path, project_all_path) xml = model_path + api in_para_dic = Core.rh_load_default_api_dic(api, ini_path, "PARA", "DICT_IN_OUT") soup = get_soup(xml) change_in_soup_dic(in_para_dic, dic_args, soup) change_para_soup(soup, data_source[i * 2 + 1 - j]) response_soup = soup_post(ybt_pro_dic["url"], soup) data = Core.rh_replace_data(data_source[i * 2 + 2 - j]) for i in data: res = rh_soup_check_result(i, response_soup) if "[success]" not in res: logger.error( "%s failed:\n***********post data:\n%s\n***********response data:%s" % (api, soup, response_soup)) Verify.should_contain(res, "[success]") out_para_dic = Core.rh_load_default_api_dic( api, ini_path, "PARA", "DICT_IN_OUT") out = get_out_soup_dic(out_para_dic, response_soup) dic_args = get_new_dic(dic_args, out) print "%s:%s" % (api, dic_args) else: j += 2 # if project_name=="ccb": # p_num = dic_args["InsPolcy_No"] # else: p_num = dic_args["PolNumber"] if api == "bia_to_core.db": result = bia_to_core(p_num, ybt_pro_dic["db_bia_usr"], ybt_pro_dic["db_bia_pwd"], ybt_pro_dic["db_ip"], ybt_pro_dic["db_name"]) elif api == "fin_check.db": result = fin_check(p_num, ybt_pro_dic["db_fin_usr"], ybt_pro_dic["db_fin_pwd"], ybt_pro_dic["db_ip"], ybt_pro_dic["db_name"]) elif api == "biab_to_core.db": result = biab_to_core(p_num, ybt_pro_dic["db_bia_usr"], ybt_pro_dic["db_bia_pwd"], ybt_pro_dic["db_ip"], ybt_pro_dic["db_name"]) elif api == "upload_file": result = upload_file(ybt_pro_dic, dic_args, path, name="pub.jpg") if not result.flag: print result.msg "%s failed" % api Verify.should_be_true(result.flag) logger.info("%s success" % api) print "%s success" % api
def checkout(self): glabalvalue = GetParmsValue() verify = _Verify() # 全局变量校验并入库(如果校验的时候不进行入库,那么在保存的时候有要去重新查一下全局路径对应的全局字段值) if (len(self.global_route) != 0): # print(self.global_route) res = glabalvalue.get_parms_value_from_key(self.global_route, self.global_name, self.env, self.actual_response,self.user) if (res['success']==False): self.flag = False self.msg.append(res['msg']) # if(res!=None): # return res # else: # print('未设置全局变量') # 校验值路径是否存在 if (self.route): self.actual_field_list = [] # print(self.route) route_list = self.route.split(';') for r in route_list: # 替换参数 if ('{{' in r): getparmsvalue = GetParmsValue() r = getparmsvalue.get_parms_value(self.route, self.env) try: self.actual_field_list.append(self.getmyvalue(self.actual_response, r)) self.msg.append("全局校验OK~~") except: # print("校验失败,无法获取" + str(self.route) + "对应的value") self.flag = False self.msg.append("校验失败,无法获取" + str(r) + "对应的value") # else: # print("该接口没有设置校验值路径") # 校验 if (self.route in ('', None, []) and self.expected_response): # 校验块内容字段 try: # 替换参数 if ('{{' in self.expected_response): getparmsvalue = GetParmsValue() self.expected_response = getparmsvalue.get_parms_value(self.expected_response, self.env) verify.should_contain(''.join(self.actual_response.split()), ''.join(self.expected_response.split())) # print('返回结果中' + self.actual_response + '字段中包含预期返回值 ' + self.expected_response + "全部字段") self.msg.append("校验OK~~,"+'返回结果中' + self.actual_response + '字段中包含预期返回值 ' + self.expected_response + "全部字段") except Exception as e: self.flag = False # print("校验失败,返回结果中不包含预期返回值全部字段,请检查!") self.msg.append("校验失败,返回结果中不包含预期返回值全部字段,请检查!") elif (self.route and self.expected_response in ('', None, [])): expected_field_list = self.expected_field.split(';') i = 0 for route, actual_field,check_type in zip(self.route.split(';'), self.actual_field_list,self.types.split(';')): i += 1 # 替换参数 try: if ('{{' in expected_field_list[i - 1]): getparmsvalue = GetParmsValue() expected_field_list[i - 1] = getparmsvalue.get_parms_value(expected_field_list[i - 1], self.env) if (check_type == 'equal'): if (actual_field == expected_field_list[i - 1]): # print('接口返回数据中' + str(route) + '校验路径字段值匹配成功为' + actual_field) self.msg.append("校验OK~~,"+'接口返回数据中' + str(route) + '校验路径字段值匹配成功为' + actual_field) else: self.flag = False # print("校验失败,接口返回数据中" + str(route) + '校验路径字段值应该为' + expected_field_list[i - 1] + ',而不是' + actual_field) self.msg.append("校验失败,接口返回数据中" + str(route) + '校验路径字段值应该为' + expected_field_list[ i - 1] + ',而不是' + actual_field) elif (check_type == 'regex'): actual_field = actual_field.strip('"') if ('\\\\' in expected_field_list[i - 1]): # expected_field_new=eval(expected_field_list[i - 1]) expected_field_new = expected_field_list[i - 1].replace('\\\\', '\\') # regex_result = re.match(expected_field_new, actual_field) regex_result=re.search(expected_field_new,actual_field,re.I|re.M|re.S) else: # regex_result = re.match(expected_field_list[i - 1], actual_field) regex_result=re.search(expected_field_list[i - 1],actual_field,re.I|re.M|re.S) if (regex_result): self.msg.append("校验OK~~," + '接口返回数据中' + str(route) + '路径字段值' + actual_field + '匹配正则' + expected_field_list[ i - 1]+'成功') else: self.flag = False self.msg.append("校验失败,接口返回数据中" + str(route) + '路径的字段值'+actual_field+'匹配正则'+expected_field_list[ i - 1]+'匹配失败') else: self.flag = False self.msg.append("校验失败,校验类型无法匹配") except Exception as e: self.flag = False # print(e) self.msg.append(e) elif (self.route and self.expected_response not in ('', None, [])): # 校验某些字段 try: # 替换参数 if ('{{' in self.expected_response): getparmsvalue = GetParmsValue() self.expected_response = getparmsvalue.get_parms_value(self.expected_response, self.env) verify.should_contain(''.join(self.actual_response.split()), ''.join(self.expected_response.split())) # print('返回结果中' + self.actual_response + '字段中包含预期返回值 ' + self.expected_response + "全部字段") self.msg.append("校验OK~~"+'返回结果中' + self.actual_response + '字段中包含预期返回值 ' + self.expected_response + "全部字段") except: self.flag = False # print("校验失败,返回结果中不包含预期返回值全部字段") self.msg.append("校验失败,返回结果中不包含预期返回值全部字段") expected_field_list = self.expected_field.split(';') i = 0 for route, actual_field,check_type in zip(self.route.split(';'), self.actual_field_list,self.types.split(';')): i += 1 # 替换参数 try: if ('{{' in expected_field_list[i - 1]): getparmsvalue = GetParmsValue() expected_field_list[i - 1] = getparmsvalue.get_parms_value(expected_field_list[i - 1], self.env) if (check_type == 'equal'): if (actual_field == expected_field_list[i - 1]): self.msg.append("校验OK~~"+'接口返回数据中' + str(route) + '校验路径字段值匹配成功为' + actual_field) else: self.flag = False self.msg.append("校验失败,接口返回数据中" + str(route) + '校验路径字段值应该为' + expected_field_list[ i - 1] + ',而不是' + actual_field) elif (check_type == 'regex'): actual_field = actual_field.strip('"') if ('\\\\' in expected_field_list[i - 1]): # expected_field_new=eval(expected_field_list[i - 1]) expected_field_new = expected_field_list[i - 1].replace('\\\\', '\\') # regex_result = re.match(expected_field_new, actual_field) regex_result=re.search(expected_field_new,actual_field,re.I|re.M|re.S) else: # regex_result = re.match(expected_field_list[i - 1], actual_field) regex_result=re.search(expected_field_list[i - 1],actual_field,re.I|re.M|re.S) if (regex_result): self.msg.append("校验OK~~," + '接口返回数据中' + str(route) + '路径字段值' + actual_field + '匹配正则' + expected_field_list[ i - 1] + '成功') else: self.flag = False self.msg.append( "校验失败,接口返回数据中" + str(route) + '路径的字段值' + actual_field + '匹配正则'+expected_field_list[ i - 1]+'失败') else: self.flag = False self.msg.append("校验失败,校验类型无法匹配") except Exception as e: self.flag = False # print(e) self.msg.append(e) if (self.flag == False): return {'success':self.flag,'msg':self.msg} else: return {'success': self.flag, 'msg': self.msg}
def json_model_pub(data_source, version="1221", model="ride"): dic_args = {} result = Result() Verify = _Verify() upload_files = {} ini_path = "" token = "" urlparam = "" default_data_dict = {} # ============请求头信息(需要的则自行添加)=========== headers = {} # =================================================== j = 0 if model == "ride": path = os.path.abspath('.') else: path = os.path.abspath('../..') # =========路径,产品,执行接口获取; eg:msp.apply.01;msp.apply:interface_a;interface_b ========== data_source_apis = data_source[0].split(":") # 用 :对datasource的第一个元素进行拆分 apis = json_replace_data(data_source_apis[1]) # 入参是接口名 取出接口名 interface_path_product = json_replace_data( data_source_apis[0]) # 入参是 msp.apply.01 api_name = interface_path_product[0].split(".")[0] # 取出了 msp api_len = len(apis) # ================获取接口属性===================== api_def_dic = EnvSetting.ENV_DEF_DIC version_dict = EnvSetting.VERSION version_info = version_dict.get(version) version_port = version_info["port"] version_url = version_info.get("url", "") env_pro_dic = api_def_dic.get(api_name) main_url = env_pro_dic["url"] # ========获取url截取点========== main_url = change_url_port(main_url, version_port, version_url) login_url = get_login_url(main_url) # ============================== ini_name_list = env_pro_dic["api_ini_name"] # ====循环对比接口和数据ini文件,取到第一个接口数据所在的ini文件,支持多个ini文件存储数据,PS:同一案例中的接口需放在同一个ini文件=== for ini_name in ini_name_list: cur_path = r'%s\config\api\%s' % (path, api_name) ini_path = r"%s\%s" % (cur_path, ini_name) # 循环读取ini文件,找到接口数据所在的ini文件 default_data_dict = get_ini_default_contant(ini_path, None, None)[0] if apis[0] in default_data_dict.keys(): break # 执行案例前清空CASE_GEN_DIC '''PS:经验证不能使用Settings.CASE_GEN_DIC = {},否则后续其他用例调用值一直保持第一次的, 原因分析?: Settings.CASE_GEN_DIC = {} 对CASE_GEN_DIC的引用改变了,CASE_GEN_DIC的值未改变;clear则清空该引用中的值 ''' Settings.CASE_GEN_DIC.clear() '''===========================================================================================''' '''====================【对于固定登录的可以抽出来单独处理】--判断系统是否需要登录=================''' login_sign = RHIniParser(ini_path).get_ini_info("IS_LOGIN", "LOGIN_SIGN") if login_sign is "Y": # 获取登录请求地址 # 利用有序OrderedDict 有序读取url(有些登录需要验证码,需现请求获取验证码接口,防止验证码过期) login_url_dict = json.loads(RHIniParser(ini_path).get_ini_info( "IS_LOGIN", "LOGIN_URL"), object_pairs_hook=OrderedDict) for url in login_url_dict.keys(): ini_contant = get_ini_default_contant(ini_path, url, None) request_method = ini_contant[1] in_para_dic = ini_contant[2] out_para_dic = ini_contant[2] default_re_set = ini_contant[3] # 走html-urlencode格式 if "highest" in url or "rest.jsf" in url or "j_security_check" in url: post_data = transfor_to_dict(login_url_dict[url]) # 登录走json参数格式 else: post_data = json.dumps(login_url_dict[url]) # 若为登录请求接口,替换对应参数兼容各个版本 change_login_dic(api_name, post_data, version_port) # 替换urlinput设置的变量--url url = change_in_json_urldic(in_para_dic, dic_args, url, urlparam) # 替换in out设置的变量--data change_in_json_dic(in_para_dic, dic_args, post_data) response_json = json_request(login_url + url, post_data, request_method) # 获取正则表达式列表 default_re = default_re_set.split(";") # 存储特定返回值 out = get_out_json_dic(out_para_dic, response_json[0], default_re) dic_args = get_new_dic(dic_args, out) '''===========================================================================================''' for i in xrange(api_len): # (0,2) interface_name = apis[i] api = Core.rh_get_api_name(apis[i]) # 再次循环对比接口和数据ini文件,取到接口数据所在的ini文件,支持多个ini文件存储数据 for ini_name in ini_name_list: cur_path = r'%s\config\api\%s' % (path, api_name) ini_path = r"%s\%s" % (cur_path, ini_name) # 循环读取ini文件,找到接口数据所在的ini文件 default_data_dict = get_ini_default_contant(ini_path, None, None)[0] default_dbdata_dict = get_ini_default_contant( ini_path, None, None)[4] if apis[i] in default_data_dict.keys( ) or apis[i] in default_dbdata_dict.keys(): break # 读取接口路径, 产品 [msp.apply.01; msp.apply; msp.tools.03 ] if len(interface_path_product) == 1: path_list = interface_path_product[0].split(".") model = path_list[1] if len(path_list) == 3: product_name = path_list[2] else: product_name = None else: path_list = interface_path_product[i].split(".") model = path_list[1] if len(path_list) == 3: product_name = path_list[2] else: product_name = None model_url = json.loads( RHIniParser(ini_path).get_ini_info("MODEL_URL", "MODEL_URL_DATA"))[model] # 读取对应api接口的默认值 ini_contant = get_ini_default_contant(ini_path, api, product_name) if ".db" not in api and ".dmldb" not in api: # 对应api接口的默认值,请求方式,出入参设置,正则表达式,特定返回值 default_contant = ini_contant[0] request_method = ini_contant[1] in_para_dic = ini_contant[2] out_para_dic = ini_contant[2] default_re_set = ini_contant[3] if "||" in data_source[i * 2 + 1 - j]: # 对rf的表格的取值,替换列的,注意替换项必须和url里面的一致 urlparam = data_source[i * 2 + 1 - j].split("||")[1] if "highest" in interface_name or "rest.jsf" in interface_name or "j_security_check" in interface_name: default_contant = transfor_to_dict(default_contant) # 替换urlinput设置的变量--url interface_name = change_in_json_urldic(in_para_dic, dic_args, interface_name, urlparam) # 替换in out设置的变量--data change_in_json_dic(in_para_dic, dic_args, default_contant) # 替换设置的参数值 change_para_json(default_contant, data_source[i * 2 + 1 - j].split( "||")[0]) # data_source[1] data_source[3]... # 走html处理的,或者是json 的get请求,不需要dumps if "highest" in interface_name or "j_security_check" in interface_name or request_method == "get": # #####==get请求参数要传dict,且dict中嵌套的list或者dict需要转换为str才能识别。=========######### for k in default_contant: if isinstance(default_contant[k], dict): default_contant[k] = json.dumps(default_contant[k]) elif isinstance(default_contant[k], list): default_contant[k] = str(default_contant[k]) else: # post请求参数为json,做dumps处理 default_contant = json.dumps(default_contant) # 更新token, 放入请求hearder中 token = change_in_token_dic(in_para_dic, dic_args, token) # ============请求hearder组装START 如有需要,自行处理==================== # iaas_cloud : token验证 if 'cloud_manage' in api_name or "auto_engine" in api_name: headers = { "Content-Type": 'application/json', 'X-Auth-Token': token.encode('utf-8') } else: headers = {"Content-Type": 'application/json'} # ============请求hearder组装END======================================== print "请求接口: " + main_url + model_url + interface_name # print default_contant response_json = json_request(main_url + model_url + interface_name, default_contant, request_method, headers) data = Core.rh_replace_data(data_source[i * 2 + 2 - j]) for i in data: if re.search('code', str(i)) != None: status_code = rh_get_rf_code(i) if int(status_code) == response_json[1]: logger.info("code(%s) check success" % status_code) else: logger.error( "%s failed:\n***********post code:\n%s\n***********response code:%s" % (api, status_code, response_json[1])) raise Exception("api(%s) fail " % api) else: res = rh_json_check_result(i, response_json[0]) if "[success]" not in res: logger.error( "%s failed:\n***********post data:\n%s\n***********response data:%s" % (api, default_contant, response_json[0])) Verify.should_contain(res, "[success]") # 获取正则表达式列表 default_re = default_re_set.split(";") # 存储特定返回值 out = get_out_json_dic(out_para_dic, response_json[0], default_re) dic_args = get_new_dic(dic_args, out) print "%s:%s" % (api, dic_args) # =================================================================================== # ============若无DB检查点,可以暂时忽略该部分代码,若需要添加,自行修改==================== elif ".db" in api: j += 2 # 对于DB校验sql取数,产品取db前一个接口对于的产品。 # 获取检验的sql sql_list = ini_contant # 避免程序入库事务还未完成就执行DB校验,故等待1秒 sleep(1) # 注意 此处传过去的sql为list(多条) 格式:saveApproval.slis.db if 'msp' in api_name: result = check_db(sql_list, version, api.split('.')[1], dic_args["applyBarCode"].split()) else: result = check_db(sql_list, version, api.split('.')[1]) if not result.flag: logger.info(result.msg, "%s failed" % api) print result.msg, "%s failed" % api Verify.should_be_true(result.flag) print "%s success" % api logger.info("%s success" % api) # ==========若有需要,执行回滚脚本======================================# else: j += 2 # 对于DB回滚sql取数,产品取db前一个接口对应的产品。 # 获取需要回滚的sql rollback_sqllist = ini_contant # 避免程序入库事务还未完成就执行DB校验,故等待1秒 sleep(1) # 执行回滚操作 格式:saveApproval.slis.dmldb try: # 特殊处理 if "applyInfoIntefaceToFH.slis.dmldb" in api: dml_db(rollback_sqllist, version, api.split('.')[1], dic_args["applyBarCode"].split()) else: dml_db(rollback_sqllist, version, api.split('.')[1]) print "%s success" % api logger.info("%s success" % api) except Exception, e: raise Exception("error occur in sql rollback, %s", str(e))