def END_WHILE(command): """ {"desc":"结束条件循环语句","alias":"end while","valueDesc":{},"pattern":"结束条件循环"} """ try: resultMap = command["result"] context = command["context"] while context["control"]["whileFlag"] and eval( ParamUtil.replaceParam(context["control"]["whileEval"], context["value"])): try: controlContext = context["control"] RunService.run_steps(context["control"]["whileSteps"], context) except LoopContinueException as e: continue except LoopBreakException as e: break except Exception as e: raise ExecutionFailException(e) finally: context["control"] = controlContext context["control"]["whileFlag"] = False context["control"]["whileSteps"] = [] resultMap["message"] = "end while" except Exception as e: raise ExecutionFailException(e)
def assertResultTrue(command): """ {"desc":"验证结果满足表达式","alias":"验证结果满足表达式","valueDesc":{"eval":"表达式"},"pattern":"验证结果表达式(?P<eval>.*)为真"} """ valueMap = command["value"] resultMap = command["result"] evalstr = str(valueMap["eval"]).strip() evalstr = ParamUtil.replaceResult(evalstr, resultMap["result"]) if not eval(evalstr): command["error"] = "表达式(%s)不为真" % evalstr raise ExecutionFailException(command["error"]) resultMap["message"] = "表达式(%s)为真" % evalstr
def assertNotTrue(command): """ {"desc":"验证表达式不为真","alias":"验证表达式不为真","valueDesc":{"eval":"表达式"},"pattern":"验证表达式(?P<eval>.*)不为真"} """ valueMap = command["value"] resultMap = command["result"] paramMap = command["params"] evalstr = str(valueMap["eval"]).strip() evalstr = ParamUtil.replaceParam(evalstr, paramMap) if eval(evalstr): command["error"] = "表达式(%s)为真" % evalstr raise ExecutionFailException(command["error"]) resultMap["message"] = "表达式(%s)不为真" % evalstr
def IF(command): """ {"desc":"如果条件语句为真,执行后面的步骤,否则不执行","alias":"if","valueDesc":{"eval":"条件判断语句"},"pattern":"如果(?P<eval>.*)"} """ try: valueMap = command["value"] resultMap = command["result"] context = command["context"] evalStr = valueMap["eval"] context["control"]["ifEval"] = evalStr context["control"]["ifFlag"] = True evalStr = ParamUtil.replaceParam(evalStr, context["value"]) context["control"]["ifResult"] = eval(evalStr) resultMap["message"] = "if(%s)" % evalStr except Exception as e: raise ExecutionFailException(e)
def LOOP(command): """ {"desc":"根据指定的数组循环","alias":"loop","valueDesc":{"array":"json格式循环数组"},"pattern":"循环数组(?P<array>.*)"} """ try: valueMap = command["value"] resultMap = command["result"] context = command["context"] array = json.loads( ParamUtil.replaceParam(valueMap["array"], context["value"]).replace( "'", "\"").replace("None", "null")) context["control"]["loopFlag"] = True context["control"]["loopArray"] = array context["control"]["loopSteps"] = [] resultMap["message"] = "loop(%s)" % array except Exception as e: raise ExecutionFailException(e)
def run_automation(api_type, url, method, headers, content_type, data, env=None, cookies=None): """ 根据接口类型,地址,接口参数调用接口 :param request: :return: 接口返回数据 """ if api_type == "http": if env is not None: url = ParamUtil.replaceParam(url, json.loads(env)) result = run_http(request_type=method, header=headers, url=url, request_parameter_type=content_type, parameter=data, cookies=cookies) else: params = { "url": url, "type": api_type, "method": method, "contentType": content_type, "headers": json.dumps(headers), "data": json.dumps(data) } if env is not None: params["env"] = env result = run_http(request_type="POST", header={ "Content-Type": "application/json; charset=UTF-8", 'Connection': 'close' }, url="%s/api/run_api" % auto_url, request_parameter_type="application/json", parameter=params, cookies=cookies) return result
def run_steps(steps, context, automation=None): from api_test.service.commandService import CommandService context["control"] = { "forFlag": False, "forSteps": [], "whileFlag": False, "whileSteps": [], "loopFlag": False, "loopSteps": [], "ifFlag": False, "ifResult": False } for action in steps: if not action["disable"] == "True": if context["control"][ "forFlag"] and not action["name"] == "END_FOR": context["control"]["forSteps"].append(action) continue if context["control"][ "whileFlag"] and not action["name"] == "END_WHILE": context["control"]["whileSteps"].append(action) continue if context["control"][ "loopFlag"] and not action["name"] == "END_LOOP": context["control"]["loopSteps"].append(action) continue if context["control"]["ifFlag"] and not context["control"][ "ifResult"] and not action[ "name"] == "ELSE" and not action[ "name"] == "END_IF": continue # actionValue=ParamUtil.replaceParam(action["params"],context["stepParams"]) if action["type"] != "control": try: tempValueMap = context["stepParams"] tempValueMap.update(context["value"]) actionValue = ParamUtil.replaceParam( action["params"], tempValueMap) actionValue = json.dumps( ParamUtil.replaceEnvMap(json.loads(actionValue), context["envMap"])) except Exception as e: action_result = str(e) action_status = "FAIL" context["step_details"].append({ "name": action["name"], "type": action["type"], "result": action_result, "status": action_status, "description": action["description"] }) raise e else: actionValue = ParamUtil.replaceParam( action["params"], context["stepParams"]) if action["type"] == "api" and action["actionId"]: if context["env"] == "生产环境": time.sleep( float(getConfigValueByName("api.interval", 0.5))) action_result, action_status = RunService.run_api( action["actionId"], actionValue, context) context["step_details"].append({ "name": action["name"], "type": action["type"], "id": action["actionId"], "url": action_result["url"], "method": action_result["method"], "value": actionValue, "data": action_result["data"], "result": action_result["response"], "status": action_status, "description": action["description"] if not "assertMessage" in action_result else action_result["assertMessage"] }) elif action["type"] == "automation" and action["actionId"]: try: action_result = {} automation = AutomationService.getAutomation( action["actionId"]) if automation.type == "reuse": currentContext = { "project": context["project"], "user": context["user"], "value": json.loads(actionValue), "result": {}, "details": [], "status": "RUNNING", "trace": datetime.now().strftime('%Y%m%d%H%M%S%f'), "env": context["env"], "envMap": context["envMap"], "cookies": context["cookies"] } action_result = run_automation( automation, currentContext) if "storedGlobalVariable" in currentContext[ "result"]: storedGlobalVariableMap = currentContext[ "result"]["storedGlobalVariable"] context["value"].update( storedGlobalVariableMap) action_status = action_result["status"] else: raise ExecutionFailException("调用的用例[%s]不是可复用!" % automation.name) except ExecutionCheckException as e: action["description"] = str(e) action_result["details"] = [] action_status = "FAIL" except ExecutionFailException as e: action["description"] = str(e) action_result["details"] = [] action_status = "FAIL" raise e finally: context["step_details"].append({ "name": automation.name, "type": action["type"], "id": action["actionId"], "value": actionValue, "details": action_result["details"], "status": action_status, "description": action["description"] }) elif action["type"] in ["common", "data", "redis", "control"]: try: action_result = CommandService.run_command( action["type"], action["name"], actionValue, action["description"], context) action_status = "PASS" except ExecutionCheckException as e: action_result = str(e) action_status = "FAIL" except ExecutionFailException as e: action_result = str(e) action_status = "FAIL" raise e except (LoopContinueException, LoopBreakException) as e: raise e except Exception as e: action_result = str(e) action_status = "FAIL" raise e finally: context["step_details"].append({ "name": action["name"], "type": action["type"], "result": action_result, "status": action_status, "description": action["description"] }) if "storedGlobalVariable" in context["result"].keys(): storedGlobalVariableMap = context["result"][ "storedGlobalVariable"] context["value"].update(storedGlobalVariableMap) if "globalValue" in context: context["globalValue"].update(storedGlobalVariableMap) if "storedVariable" in context["result"].keys(): storedVariableMap = context["result"]["storedVariable"] context["value"].update(storedVariableMap) if automation and "storedAutomationVariable" in context[ "result"].keys(): storedAutomationVariableMap = context["result"][ "storedAutomationVariable"] automationParamMap = json.loads(automation.params) automationParamMap.update(storedAutomationVariableMap) automation.params = json.dumps(automationParamMap) automation.save() if action_status == "FAIL": context["step_status"] = "FAIL" break
def run_step(automation, step, context): from api_test.service.commandService import CommandService context["step_details"] = [] context["step_status"] = "RUNNING" step_message = step.description testtime = time.time() try: steps = json.loads(step.steps) if len(steps) == 0: description = step.description lines = description.split('\n') lineNo = 0 for line in lines: if not line.startswith("#"): lineNo += 1 linePre = "%s、" % str(lineNo) lineStartIndex = line.find(linePre) if lineStartIndex >= 0: line = line[lineStartIndex + len(linePre):] command = CommandService.get_command( line, automation.project.id) if command: steps.append({ "type": command["type"], "name": command["name"], "actionId": command["actionId"], "params": command["value"], "description": command["desc"], "disable": "False" }) automationParams = ParamUtil.replaceMap( json.loads(automation.params), context["value"]) stepParams = json.loads( ParamUtil.replaceParam(step.params, context["envMap"])) stepParams = ParamUtil.replaceMap(stepParams, automationParams) context["stepParams"] = stepParams RunService.run_steps(steps, context, automation=automation) if context["step_status"] != "FAIL": context["step_status"] = "PASS" except ExecutionFailException as e: context["step_status"] = "FAIL" step_message = str(e) except Exception as e: logging.error(traceback.format_exc()) context["step_status"] = "FAIL" step_message = str(e) finally: duration = int((time.time() - testtime) * 1000) testtime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(testtime)) AutomationResult(name=step.name, trace=context["trace"], details=json.dumps(context["step_details"]), result=context["step_status"], project=automation.project, automation=automation, step=step, testTime=testtime, duration=duration, description=step_message, env=context["env"], user_id=context["user"]).save() # context["details"].append({"name":step.name,"status":step_status,"details":step_details,"description":step.description}) return { "id": step.id, "name": step.name, "details": context["step_details"], "status": context["step_status"], "testtime": testtime, "duration": duration, "description": step_message }
def run_automation(automation, context): automation_details = [] automation_status = "RUNNING" automation_message = automation.description testtime = time.time() if "cookies" not in context: context["cookies"] = requests.cookies.RequestsCookieJar() result = { "type": "automation", "trace": context["trace"], "name": automation.name, "status": "RUNNING", "testtime": "", "duration": 0, "details": [], "description": automation.description } result["testtime"] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(testtime)) result["details"] = automation_details result["id"] = automation.id # RunService.putRunningResult(context["trace"],result) # logging.info("执行用例: %s" % self.automation.name) try: projectDataMap = getDataMap(automation.project.id) if context["value"]: projectDataMap.update(context["value"]) context["value"] = projectDataMap if automation.type == "monitor": apis = automation.apis.all() paramMap = ParamUtil.replaceMap(context["value"], context["envMap"]) value = json.dumps( ParamUtil.replaceMap(json.loads(automation.params), paramMap)) for api in apis: if not context["ids"] or api.id in context["ids"]: if context["env"] == "生产环境": time.sleep( float(getConfigValueByName("api.interval", 0.5))) current_testtime = time.time() api_result, api_status = RunService.run_api( api.id, value, context) current_duration = int( (time.time() - current_testtime) * 1000) api_detail = { "trace": context["trace"], "name": api.name, "type": "api", "id": api.id, "testtime": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(current_testtime)), "duration": current_duration, "url": api_result["url"], "method": api_result["method"], "data": api_result["data"], "result": api_result["response"], "status": api_status, "description": api.description } if api_status == "FAIL": automation_status = "FAIL" api_detail["description"] = api_result[ "assertMessage"] if "assertMessage" in api_result else "执行失败,异常信息[{message}]".format( message=api_detail["result"]) automation_details.append(api_detail) AutomationResult(name=api.name, trace=context["trace"], value=context["value"], details=json.dumps([api_detail]), result=api_status, project=automation.project, automation=automation, api=api, testTime=time.strftime( '%Y-%m-%d %H:%M:%S', time.localtime(current_testtime)), duration=current_duration, description=api_detail["description"], env=context["env"], user_id=context["user"]).save() else: steps = automation.steps.all().filter( automation2step__status=True).order_by( "automation2step__order") for step in steps: if not "ids" in context or not context[ "ids"] or step.id in context["ids"]: step_result = RunService.run_step(automation, step, context) automation_details.append(step_result) if step_result["status"] == "FAIL": automation_status = "FAIL" automation_message = "步骤[{stepName}]执行失败,异常信息[{message}]".format( stepName=step.name, message=step_result["description"]) break if automation_status != "FAIL": automation_status = "PASS" except Exception as e: logging.error(traceback.format_exc()) automation_message = str(e) automation_status = "FAIL" finally: duration = int((time.time() - testtime) * 1000) AutomationResult( name=automation.name, trace=context["trace"], result=automation_status, project=automation.project, automation=automation, testTime=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(testtime)), duration=duration, description=automation_message if "debug" not in context or not context["debug"] else "调试", env=context["env"], user_id=context["user"]).save() result["status"] = automation_status result["duration"] = duration result["details"] = automation_details result["description"] = automation_message # RunService.removeRunningResult(context["trace"]) return result
def run_api_by_id(id, value, cookies): """ 根据接口ID,接口参数调用接口 :param request: :return: 接口返回数据 """ result = "" try: serialize = ApiInfoSerializer(ApiInfo.objects.get(id=id)) api = serialize.data headers = {} for header in api["headers"]: headers[header["name"]] = header["value"] parameters = {} valueMap = json.loads(value) for parameter in api["requestParameter"]: if parameter["name"] == "postData" and len( api["requestParameter"]) == 1: if parameter["name"] in valueMap: parameters = json.loads2(valueMap[ parameter["name"]]) if parameter["_type"] in ( "Object", "Array") else valueMap[parameter["name"]] else: parameters = json.loads2( parameter["value"]) if parameter["_type"] in ( "Object", "Array") else parameter["value"] else: if parameter["name"] in valueMap: parameterValue = valueMap[parameter["name"]] else: parameterValue = json.loads2( parameter["value"]) if parameter["_type"] in ( "Object", "Array") else parameter["value"] if parameterValue != "NULL": parameters[parameter["name"]] = parameterValue api["apiAddress"] = ParamUtil.replaceParam(api["apiAddress"], json.loads(value)) code, response_data, header_data = ApiService.run_api( api["type"], api["apiAddress"], api["requestType"], headers, api["requestParameterType"], parameters, env=value, cookies=cookies) assertMessage = [] if len(api["response"]) > 0: for response in api["response"]: responseValues = json.get_values(response_data, response["name"]) if responseValues: for value in responseValues: if response["value"] and not match( response["value"], value): assertMessage.append( "接口返回数据参数%s实际值%s,与预期值%s不一致!" % (response["name"], value, response["value"])) actualType = json.get_type(value) if actualType and actualType != response["_type"]: assertMessage.append( "接口返回数据参数%s实际类型%s,与预期类型%s不一致!" % (response["name"], actualType, response["_type"])) elif response["required"]: assertMessage.append("接口返回数据不存在必含参数%s!" % response["name"]) result = { "url": api["apiAddress"], "method": api["requestType"], "data": parameters, "response": response_data, "responseCode": code } if len(assertMessage) > 0: result["assertMessage"] = str(assertMessage) if len( assertMessage) > 1 else assertMessage[0] return result except Exception as e: logging.error(traceback.format_exc()) raise e