def get_main(self, url, data=None, json=None, headers=None, verify=None, cert=None, new_session=False): res = None if new_session: s = requests.Session() #s.proxies = {'http': ''} #res = s.get(url=url,data=data,headers=headers,verify=verify) else: s = glo.get_value('Session') #获取全局变量Session if headers is None: res = s.get(url=url, params=data, json=json, verify=verify, cert=cert) else: res = s.get(url=url, params=data, json=json, headers=headers, verify=verify, cert=cert) glo.set_value('Session', s) return res
def delete_main(self, url, data=None, json=None, headers=None, verify=False, cert=None, new_session=False): res = None if new_session: s = requests.Session() else: s = glo.get_value('Session') #获取全局变量Session if headers is None: res = s.delete(url=url, params=data, json=json, verify=verify, cert=cert) else: res = s.delete(url=url, params=data, json=json, headers=headers, verify=verify, cert=cert) glo.set_value('Session', s) return res
def get_current_timestamp(n=0, convert_str=False, get_round=False): """ :param n: 需乘以10的n次方 :param convert_str: 是否需要转换为字符串 :return: """ result = time.time() * pow(10, n) if get_round: result = round(result) if convert_str: result = str('{:.0f}'.format(result)) #大整数取消科学计数法显示 glo.set_value("timestamp", result) return result
def post_main(self, url, data=None, json=None, headers=None, verify=False, cert=None, new_session=False): #def post_main(self, url, json, headers=None, verify=False, new_session=False): res = None if new_session: s = requests.Session() #res = s.post(url=url,data=data,headers=headers,verify=verify) else: s = glo.get_value('Session') #获取全局变量Session #res = s.post(url=url,data=data,verify=verify) if headers is None: # knews必须使用data参数, 否则post请求不成功, inews post json格式的数据必须使用json参数 res = s.post(url=url, data=data, json=json, verify=verify, cert=cert) else: res = s.post(url=url, data=data, json=json, headers=headers, verify=verify, cert=cert) if new_session: glo.set_value('Session', s) #return res.json() return res
def init_conn_pool(dbname='DB'): if get_db_type(dbname).upper() == "MYSQL": #@TODO: 根据不同数据库选择不同 驱动 pool = PooledDB(pymysql, 5, host=get_db_host(dbname), user=get_db_user(dbname), passwd=get_db_pwd(dbname), db=get_db_database(dbname), port=int(get_db_port(dbname))) #glo.set_value("db_pool",pool) elif get_db_type(dbname).upper() == "ORACLE": pool = PooledDB(cx_Oracle, user=get_db_user(dbname), password=get_db_pwd(dbname), dsn="%s:%s/%s" % (get_db_host(dbname), get_db_port(dbname), get_db_service_name(dbname)), mincached=20, maxcached=200) else: pool = None poolname = (dbname + '_pool').lower() glo.set_value(poolname, pool)
def test_interface(self, casedata): '''测试接口''' if (casedata['Case_Level'] in get_run_case_level() or get_run_case_level() == []) and casedata['是否运行'].upper( ) == 'Y': #如果不在指定运行的case level中或未标注运行,则该testcase跳过 #执行SetUp内容 if 'SetUp' in casedata.keys() and casedata['SetUp'] != "": #eval_from_string(casedata['SetUp'], return_str=False, json_str = True) eval_from_string(casedata['SetUp']) #执行测试内容 exec_step = ExecuteStep() res = exec_step.execute(casedata) # 调试输出resonse文本 ''' if not os.path.exists('../testreport'): os.makedirs('../testreport') now=time.strftime("%Y-%m-%d %H_%M_%S",time.localtime()) with open(r"../testreport/ResponsePage-%s-%s.html"%(casedata['Case_Name'],now),'w',encoding='utf-8-sig') as f: # 中文即使用utf-8也还是乱码 f.write(res.text) ''' expected_status_code = casedata['期望响应代码'] # # inews测试prod连接不稳定 # #pdb.set_trace() # if res.status_code==403 and 'message' in res.json().keys() and res.json()['message']=='forbidden2' and expected_status_code!=403: # #pdb.set_trace() # self.fail("Token Expired") # raise ExpireError("Token Expired") logging.debug(res.status_code) #try: self.assertEqual( str(res.status_code), expected_status_code, 'Status Code not as expected! Expected:%s, Actual: %s, %s' % (expected_status_code, res.status_code, res.text)) #except: # raise # res.raise_for_status() expected_res_txt = casedata['期望响应文本'] if expected_res_txt != "": if casedata['对比方法'] == "" or casedata['对比方法'] is np.nan: #logging.error("需要输入对比方法!") self.fail("需要输入对比方法!") else: logging.debug("casedata['对比方法']:%s" % casedata['对比方法']) eval("self." + casedata['对比方法'])(str(expected_res_txt), res.text, 'Response text not as expected!') expected_json = casedata['期望返回Json内容'] if expected_json != "": # 验证返回的Json内容 try: if 'Content-Type' in res.headers.keys( ) and 'application/json' in res.headers['Content-Type']: actual_json_obj = res.json() else: actual_json_obj = {} if re.compile("^\${.+}$").match( expected_json) is not None: # 仅包含${...}函数表达式 #eval_result = eval_from_string(expected_json,return_str=True,json_str=True) #expected_json = eval_from_string(expected_json, return_str=True, json_str=True) expected_json = eval_from_string(expected_json) # 进行字符串替换时返回结果已转换成字符串,需要解码json对象,作为jsonmatch的参数 eval_result = json.loads( json.dumps(eval(expected_json)) ) #由于eval_result包含单引号,需要先用json.dumps(eval(xxx))进行转换 logging.debug("expected Json string: %s" % repr(eval_result)) logging.debug("Json string in response:%s" % repr(actual_json_obj)) self.assertTrue(jsonmatch(eval_result, actual_json_obj)) elif re.compile("^{.+}$").match( expected_json) is not None: #仅包含{}json表达式 logging.debug("expected Json string: %s" % repr(expected_json)) logging.debug("Json string in response:%s" % repr(actual_json_obj)) self.assertTrue( jsonmatch(json.loads(expected_json), actual_json_obj)) else: #按json_path处理 for element in expected_json.split(';'): if element.strip( ) == "": #最常见的情况是case的最后一个json表达式末尾也跟了一个分号; #logging.warning("json expression is empty") continue #跳过 #rparser = RuleParser(element.strip(),actual_json_obj) rparser = RuleParser(element.strip(), res) if 'Content-Type' in res.headers.keys( ) and 'application/json' in res.headers[ 'Content-Type']: actual_result = res.json() else: actual_result = res.text #assert rparser.evaluate() is True, "验证失败:%s\nactual response:\n%s"%(element,actual_json_obj) assert rparser.evaluate( ) is True, "验证失败:%s\nactual result:\n%s" % ( element, actual_result) except Exception as e: #self.assertEqual(1,0,"Exception occured: %s"%e) # fails the test self.fail("Exception occured: %s" % e) # fails the test if '结果验证方法名' in casedata.keys() and casedata['结果验证方法名'] != "": # 本地变量无法传递到expression_evaluation模块,需要使用全局变量 glo.set_value('post_data', exec_step.data) #glo.set_value('response', res) glo.set_value('res_json', res.json()) logging.debug("res.json(): %s" % repr(res.json())) #eval_from_string(casedata['结果验证方法名'].rstrip('}') + '(${post_data},${response})}') validation_result = eval_from_string( casedata['结果验证方法名'].rstrip('}') + #'(base.globalvars.getvalue("post_data"),base.globalvars.getvalue("response"))}',return_str=False,json_str=False) '(${post_data},${res_json})}', return_str=False, json_str=False) self.assertTrue(validation_result, '验证不通过') if '设置全局变量' in casedata.keys() and casedata['设置全局变量'] != "": if casedata['设置全局变量'].startswith("text:"): #text:变量名 var_name = casedata['设置全局变量'].replace("text:", "") glo.set_value(var_name, res.text) elif casedata['设置全局变量'].startswith( "json:"): #json:表达式:索引下标:变量名,如json:$.newsId:[0]:newsId values = casedata['设置全局变量'].split(':') var_name = values[-1] jp_exp = values[1] #jsonpath # if values[2]!="": # index = values[2] glo.set_value( var_name, eval("jsonpath(res.json(),jp_exp)" + values[2])) else: self.fail("设置全局变量格式不正确") if 'Post_Case_Action' in casedata.keys( ) and casedata['Post_Case_Action'] != "": # 执行post case action #eval_from_string(casedata['Post_Case_Action'],return_str=False,json_str=True) eval_from_string(casedata['Post_Case_Action']) else: raise unittest.SkipTest( "case set not to run") # case真正跳过,不会被统计为pass
def get_and_set_global_vars(): if cf.has_section('Globals'): '''从配置文件中读取需要设置的全局变量(不同于配置文件中在整个框架使用的其他变量,此处的全局变量只在特定项目中使用,因此不同配置文件做不同设置''' for var in cf['Globals'].keys(): glo.set_value(var, cf.get('Globals', var))