def deal_threadgroup(root, node_path): # 线程组名称, 作为用例名称 thread_group_name = root.get("testname") logger.debug(node_path) sub_elements = root.get_sub_elements() # 初始化导入用例请求 ioc = importOfflineCase(node_path + thread_group_name) # ioc = importOfflineCase(node_path) steps = [] # 获取到所有关键组件 for sub_element in sub_elements: # 组件为禁用状态, 不读取 if not sub_element.isEnabled(): continue if sub_element.tag == "TransactionController": # 一个事务控制器, 作为一条用例 ioc.add_case(sub_element.get("testname"), deal_transaction_controller(sub_element, node_path)) elif sub_element.tag == "JDBCSampler": steps += deal_JDBCSample(sub_element) if steps: ioc.add_case(thread_group_name, steps) resp = post_blade.importOfflineCase(ioc) logger.debug(resp) if resp is not None: logger.error("用例{}添加失败, 原因:{}".format(thread_group_name, resp)) else: logger.info("用例{}添加成功".format(thread_group_name)) global count logger.info(count) count += 1
def deal_threadgroup(root, node_path): # 线程组名称, 作为用例名称 thread_group_name = root.get("testname") logger.debug(node_path) sub_elements = root.get_sub_elements() # 初始化导入用例请求 ioc = importOfflineCase(node_path) steps = [] # 获取到所有关键组件 for sub_element in sub_elements: # 组件为禁用状态, 不读取 if not sub_element.isEnabled(): continue if sub_element.tag == "TransactionController": deal_transaction_controller(sub_element, node_path, steps) elif sub_element.tag == "UserParameters": # 用户参数处理 steps.append(deal_user_parameters(sub_element)) ioc.add_case(thread_group_name, steps) resp = post_blade.importOfflineCase(ioc) logger.debug(resp) if resp is not None: logger.error("用例{}添加失败, 原因:{}".format(thread_group_name, resp)) else: logger.info("用例{}添加成功".format(thread_group_name)) global count logger.info(count) count += 1
def deal_transaction_controller(root, node_path): steps = [] sub_elements = root.get_sub_elements() # 获取到所有关键组件 step_num = len(steps) for sub_element in sub_elements: # 组件为禁用状态, 不读取 if not sub_element.isEnabled(): continue if sub_element.tag == "HTTPSamplerProxy": step_num += 1 path = sub_element.element.find( ".//stringProp[@name='HTTPSampler.path']").text script_name = path.split("/")[-1] logger.debug("script_name:%s" % script_name) # 先添加脚本 ds = dealScriptData(node_path) ds.set_data_with_default(script_name, root_url, path) resp, script_id = post_blade.dealScriptData(ds) # 再添加数据 steps.append( deal_HTTPSampler(sub_element, "步骤-" + str(step_num), script_id)) elif sub_element.tag == "JDBCSampler": steps += deal_JDBCSample(sub_element) return steps
def deal_LoopController(root): step = importOfflineCase_step() step.set_stepname(root.get("testname")) step.set_stepdes(root.get("testname")) steps = [step.get_step()] sub_elements = root.get_sub_elements() for sub_element in sub_elements: if sub_element.tag == "BeanShellPreProcessor": script = sub_element.element.find( ".//stringProp[@name='script']").text csv_file = re.findall( r'new FileInputStream\(vars.get\("(.*?)"\)\);', script)[0] csv_file_path = arguments_local.get(csv_file) csv_file_name = os.path.split(csv_file_path)[-1] logger.debug(csv_file_name) csv_file = open(CSV_FILE_DIR / csv_file_name, encoding="gbk") lines = csv_file.readlines() for line in lines: line_list = line.split(",") after_sqls = line_list[-2] results = line_list[-1] after_sqls_list = after_sqls.split("union ALL") result_list = results.split("|") for i in range(len(after_sqls_list)): check_string = "count(1)={};".format(result_list[i]) step.add_checkcontent(check_string, data_sources["bupps_107_orcl"], after_sqls_list[i]) return steps
def set_ssh_with_default(self, script_name, ssh_connect, script_remark=""): data = { "scriptName": "%s" % script_name, "scriptContent": "ssh|%s,60" % ssh_connect, "scriptRemark": "%s" % script_remark, "scriptJsonData": {"服务器连接": "%s" % ssh_connect, "超时时间": "60"} } logger.debug(data) self.data.append(data)
def set_wait_with_default(self, script_name, wait_time, script_remark=""): data = { "scriptName": "%s" % script_name, "scriptContent": "wait|%s" % wait_time, "scriptRemark": "%s" % script_remark, "scriptJsonData": {"等待时间": "%s" % wait_time} } logger.debug(data) self.data.append(data)
def deal_user_parameters(root): step = importOfflineCase_step() step.set_stepdes(root.get("testname")) params_str = "" names = root.element.findall("collectionProp[@name='UserParameters.names']/stringProp") values = root.element.findall("collectionProp[@name='UserParameters.thread_values']//stringProp") for i in range(len(names)): params_str += check_argument(names[i].text) + "|" + values[i].text + ";" logger.debug(params_str) step.add_presqlcontent(data_sources["default"], params_str) return step.get_step()
def dealScriptData(self, data): if not isinstance(data, dealScriptData): return "data 需要为 dealScriptData 实例" resp = requests.post(util.dealScriptData_url, data=json.dumps(data.__dict__), headers=self.headers) content = resp.content.decode("utf-8") resp_content_json = json.loads(content) logger.debug(resp_content_json) if resp_content_json['msg'] == PostBlade.SUCCESS and resp_content_json['sub_msg'] == "": return None, resp_content_json['result_list'][0]['ID'] else: return resp_content_json['sub_msg'], resp_content_json['result_list'][0]['ID']
def importOfflineCase(self, data): if not isinstance(data, importOfflineCase): return "data需要为importOfflineCase实例" resp = requests.post(util.importOfflineCase_url, data=json.dumps(data.__dict__), headers=self.headers) content = resp.content.decode("utf-8") resp_content_json = json.loads(content) logger.debug(resp_content_json) if resp_content_json['msg'] == PostBlade.SUCCESS and resp_content_json['sub_msg'] == "": return else: return resp_content_json['sub_msg']
def dealVariableData(self, data): if not isinstance(data, VariableData): return "data 需要为VariableData实例" resp = requests.post(util.dealVariableData_url, data=json.dumps(data.__dict__), headers=self.headers) content = resp.content.decode("utf-8") resp_content_json = json.loads(content) logger.debug(resp_content_json) if resp_content_json['msg'] == PostBlade.SUCCESS and resp_content_json['sub_msg'] == "": return else: return resp_content_json['sub_msg']
def set_data_with_default(self, script_name, root_url, path, script_remark=""): data = { "scriptName": "%s" % script_name, "scriptContent": "http|%s,%s,POST,UTF-8,json,Content-Type=application/json;charset=UTF-8,,300" % (root_url, path), "scriptRemark": "%s" % script_remark, "scriptJsonData": {"根URL": "%s" % root_url, "路径": "%s" % path, "请求方式": "POST", "编码类型": "UTF-8", "返回形式": "json", "header配置": "Content-Type=application/json;charset=UTF-8", "精准标签": "", "超时时间": "300"} } logger.debug(data) self.data.append(data)
def set_mq_with_default(self, script_name, mq_message, script_remark=""): data = { "scriptName": "%s" % script_name, "scriptContent": "ibmmq|%s,%s,%s,%s,%s" % (mq_message["connect"], mq_message["manager"], mq_message["queue"], mq_message["channel"], mq_message["ccsid"]), "scriptRemark": "%s" % script_remark, "scriptJsonData": {"ibmmq连接": "%s" % mq_message["connect"], "队列管理器": "%s" % mq_message["manager"], "队列": "%s" % mq_message["queue"], "通道": "%s" % mq_message["channel"], "字符集": "%s" % mq_message["ccsid"]} } logger.debug(data) self.data.append(data)
def deal_HTTPSampler(root, step_name, script_content="", request_body=""): check_string = "" # 初始化 step 数据 step = importOfflineCase_step() step.set_stepname(step_name) step.set_stepdes(root.get("testname")) if script_content: step.set_scriptcontent(script_content) # 没有传入报文内容, 自行获取当前报文内容, 否则使用传入内容,request 特殊处理, 将其中使用的变量替换成blade变量 if not request_body: request_body = root.element.find(".//stringProp[@name='Argument.value']").text request_body = replace_argument(request_body) # HTTP 的子组件处理 sub_elements = root.get_sub_elements() for sub_element in sub_elements: # 组件禁用, 不读取 if not sub_element.isEnabled(): continue # 前置提取 if sub_element.tag == "JDBCPreProcessor": data_source = sub_element.element.find(".//stringProp[@name='dataSource']").text sql_text = sub_element.element.find(".//stringProp[@name='query']").text variable_name = sub_element.element.find(".//stringProp[@name='variableNames']").text # 对sql做提取 sqls = re.findall( r"([delete|insert|update|select|DELETE|INSERT|UPDATE|SELECT|Update|Insert|Select|Delete].*?'.*;)", sql_text) logger.debug("提取的sql:%s" % str(sqls)) for sql in sqls: sql = replace_argument(sql) if "%" in sql: sql = sql.replace("%", "%25") if variable_name: sql = variable_name + "|" + sql step.add_presqlcontent(data_sources[data_source], sql) # 后置提取 # 验证提取 elif sub_element.tag in ("ResponseAssertion", "BeanShellAssertion"): check_elements = sub_element.element.findall("collectionProp/stringProp") check_string = "" for check_element in check_elements: if check_element.text: messages = check_element.text.replace('"', '').split(":") if len(messages) == 1: check_string += check_element.text else: check_string += check_string_root + messages[0] + "=" + messages[1] + ";" logger.debug(check_string) logger.debug(request_body) data_chose_row, data_arr_content = Josn2Blade(eval(request_body), [], 0, check_string) step.set_dataarrcontent(data_chose_row, data_arr_content) logger.debug(step) return step.get_step()
def deal_msg_beanshellsampler(root, step_name): step = importOfflineCase_step() step.set_stepname(step_name) step.set_stepdes(root.get("testname")) sub_elements = root.get_sub_elements() for sub_element in sub_elements: if not sub_element.isEnabled(): continue if sub_element.tag == "JDBCPreProcessor": data_source = sub_element.element.find(".//stringProp[@name='dataSource']").text sql_text = sub_element.element.find(".//stringProp[@name='query']").text # 对sql做提取 sqls = re.findall( r"([delete|insert|update|select|DELETE|INSERT|UPDATE|SELECT|Update|Insert|Select|Delete].*?'.*;)", sql_text) logger.debug("提取的sql:%s" % str(sqls)) for sql in sqls: sql = replace_argument(sql) if "%" in sql: sql = sql.replace("%", "%25") step.add_presqlcontent(data_sources[data_source], sql) script_text = root.element.find(".//stringProp[@name='BeanShellSampler.query']").text body = replace_argument(re.findall(r'String msg_body=[\r\n]?(.*?);', script_text)[0]) body = body.replace("\\r\\n", "\r\n") logger.debug(body) data_content = list() temp = dict() temp["sheet0"] = list() data_chose_row = random_uuid(32) one = [random_uuid(32), "序号", "期望", "body"] two = [random_uuid(32), "参数说明", "", ""] three = [data_chose_row, "", "", body] temp["sheet0"].append(one) temp["sheet0"].append(two) temp["sheet0"].append(three) data_content.append(temp) step.set_dataarrcontent(data_chose_row, data_content) return step
def Josn2Blade(message, result, num=0, check_Message=""): """ 将报文转化为Blade可接收的测试数据格式 :param message: 报文数据 :param num: sheet计数 :param result: Blade 数据格式 :param check_Message: 验证字符串 :return: """ logger.debug("message:{}, num:{}".format(message, num)) temp = dict() temp["sheet" + str(num)] = [] result.append(temp) dict_num = 0 data_chose_row = random_uuid(32) # 传入了验证字段, 则 0 特殊处理 if num == 0: one = [random_uuid(32), "序号", "期望"] two = [random_uuid(32), "参数说明", ""] three = [data_chose_row, "", check_Message] temp["sheet" + str(num)].append(one) temp["sheet" + str(num)].append(two) temp["sheet" + str(num)].append(three) else: one = [random_uuid(32), "GroupID"] two = [random_uuid(32), "1"] temp["sheet" + str(num)].append(one) temp["sheet" + str(num)].append(two) for key, value in message.items(): if isinstance(value, dict): dict_num += 1 temp["sheet" + str(num)][0].append(key + "(Object)") temp["sheet" + str(num)][-1].append("sheet" + str(num + dict_num) + "|1") Josn2Blade(value, result, num + dict_num) else: temp["sheet" + str(num)][0].append(key) temp["sheet" + str(num)][-1].append(value) return data_chose_row, result
def deal_JDBCSample(root): step = importOfflineCase_step() step.set_stepname(root.get("testname")) step.set_stepdes(root.get("testname")) steps = [step.get_step()] sql_text = replace_argument( root.element.find(".//stringProp[@name='query']").text) sqls_list = re.findall( r"((delete|insert|update|select|DELETE|INSERT|UPDATE|SELECT|Update|Insert|Select|Delete|Truncate|truncate|TRUNCATE).+[\s\S].+;)", sql_text) sqls = [sql_list[0] for sql_list in sqls_list] logger.debug(sqls) data_source = root.element.find(".//stringProp[@name='dataSource']").text for sql in sqls: if "%" in sql: sql = sql.replace("%", "%25") logger.debug(sql) step.add_presqlcontent(data_sources[data_source], sql) sub_elements = root.get_sub_elements() # 没有子组件, 纯粹是执行一条sql if not sub_elements: logger.debug("no sub element") return steps for sub_element in sub_elements: if not sub_element.isEnabled(): continue if sub_element.tag == "BeanShellPostProcessor": if "redis" in sub_element.get("testname"): steps.append(deal_redis_beanshellsampler(sub_element)) return steps
def deal_JDBCSample(root): step = importOfflineCase_step() step.set_stepname(root.get("testname")) step.set_stepdes(root.get("testname")) steps = [step.get_step()] sql_text = replace_argument( root.element.find(".//stringProp[@name='query']").text) sqls_list = re.findall( r"((delete|insert|update|select|DELETE|INSERT|UPDATE|SELECT|Update|Insert|Select|Delete|Truncate|truncate|TRUNCATE).+[\s\S])", sql_text) sqls = [sql_list[0] for sql_list in sqls_list] logger.debug(sqls) data_source = root.element.find(".//stringProp[@name='dataSource']").text for sql in sqls: if "%" in sql: sql = sql.replace("%", "%25") logger.debug(sql) step.add_presqlcontent(data_sources[data_source], sql) sub_elements = root.get_sub_elements() # 没有子组件, 纯粹是执行一条sql if not sub_elements: logger.debug("no sub element") return steps for sub_element in sub_elements: if not sub_element.isEnabled(): continue if sub_element.tag == "BeanShellPostProcessor": steps.append(deal_redis_beanshellsampler(sub_element)) elif sub_element.tag == "BeanShellAssertion": check_results = list( sub_element.element.find( ".//stringProp[@name='BeanShellAssertion.parameters']"). text) # 清空presqlcontent, 存在这个子组件,说明JDBC里存放的是验证SQL step.set_presqlcontent(list()) for i in range(len(sqls)): check_string = "count(1)={};".format(check_results[i]) sql = sqls[i] logger.debug("check sql:{}, check:{}".format( sql, check_string)) step.add_checkcontent(check_string, data_sources[data_source], sql) return steps
def deal_csv_threadgroup(root): sub_elements = root.get_sub_elements() http_companents = [] messages = None cases = [] csv_file_name = None for sub_element in sub_elements: if not sub_element.isEnabled(): continue if sub_element.tag == "BeanShellPreProcessor": script = sub_element.element.find( ".//stringProp[@name='script']").text logger.debug( re.findall(r'new FileInputStream\(vars.get\("(.*?)"\)\)', script)) csv_file = re.findall( r'new FileInputStream\(vars.get\("(.*?)"\)\)', script)[0] csv_file_path = arguments_local.get(csv_file) csv_file_name = os.path.split(csv_file_path)[-1] logger.debug(csv_file_name) messages = deal_csv_file(csv_file_name) elif sub_element.tag == "HTTPSamplerProxy": # 在这里改成将 HTTP 组件保存下来, 在后面循环遍历 Message, 重复发送 http_companents.append(sub_element) for sub_sub_element in sub_element.get_sub_elements(): if sub_sub_element.tag == "BeanShellAssertion": assert_text = sub_sub_element.element.find( ".//stringProp[@name='BeanShellAssertion.query']").text results = re.findall(r'vars.get\("(.*?)"\).equals(.*?)', assert_text) stop_list = [result[0] for result in results] messages = deal_csv_file(csv_file_name, stop_list) for message in messages: step_num = 0 steps = [] for http_companent in http_companents: step_num += 1 request_body_half = http_companent.element.find( ".//stringProp[@name='Argument.value']").text requst_body = request_body_half.replace("${req_body}", message["body"]) logger.debug(requst_body) steps.append( deal_HTTPSampler(http_companent, "步骤-" + str(step_num), requst_body, message["check_message"])) cases.append([message["casename"], steps]) return cases
def deal_transaction_controller(root, node_path, steps): sub_elements = root.get_sub_elements() # 获取到所有关键组件 step_num = len(steps) step_object = None for sub_element in sub_elements: # 组件为禁用状态, 不读取 if not sub_element.isEnabled(): continue if sub_element.tag == "HTTPSamplerProxy": step_num += 1 path = sub_element.element.find(".//stringProp[@name='HTTPSampler.path']").text script_name = path.split("/")[-1] logger.debug("script_name:%s" % script_name) # 先添加脚本 ds = dealScriptData(node_path) ds.set_data_with_default(script_name, root_url, path) resp, script_id = post_blade.dealScriptData(ds) # 再添加数据 steps.append(deal_HTTPSampler(sub_element, "步骤-" + str(step_num), script_id)) elif sub_element.tag == "ConstantTimer": wait_time_text = sub_element.element.find(".//stringProp[@name='ConstantTimer.delay']").text wait_time = int(wait_time_text) // 1000 if wait_time == 0: wait_time = 1 script_name = "wait_" + str(wait_time) + "s" # 新增一个定时延迟的脚本 ds = dealScriptData(node_path) ds.set_wait_with_default(script_name, wait_time, sub_element.get("testname")) resp, script_id = post_blade.dealScriptData(ds) # 处理定时器 steps.append(deal_constanttimer(sub_element, "步骤-" + str(step_num), script_id)) elif sub_element.tag == "JDBCSampler": steps.append(deal_JDBCSample(sub_element)) elif sub_element.tag == "BeanShellSampler": # redis beanshell 脚本处理 if "redis" in sub_element.get("testname"): # 添加脚本 script_name = "redis_jmeter" ssh_connect = "redis_jmeter" ds = dealScriptData(node_path) ds.set_ssh_with_default(script_name, ssh_connect, sub_element.get("testname")) resp, script_id = post_blade.dealScriptData(ds) # 添加数据 steps.append(deal_redis_beanshellsampler(sub_element, "步骤-" + str(step_num), script_id)) else: # 其他处理方式, 默认为报文 step_object = deal_msg_beanshellsampler(sub_element, "步骤-" + str(step_num)) elif sub_element.tag == "org.apache.jmeter.protocol.MQComm.sampler.MQPutMessageSampler": if step_object is not None: ibm_mq_message = dict() ibm_mq_message["connect"] = ibm_mq_connect manager = jmeter_get_argument_value(sub_element.element.find( ".//stringProp[@name='MQPutMessageSampler.MQ_MANAGER']").text) logger.debug(manager) ibm_mq_message["manager"] = manager queue = jmeter_get_argument_value(sub_element.element.find( ".//stringProp[@name='MQPutMessageSampler.MQ_QUEUE']").text) logger.debug(queue) ibm_mq_message["queue"] = queue channel = jmeter_get_argument_value(sub_element.element.find( ".//stringProp[@name='MQPutMessageSampler.MQ_CHANNEL']").text) logger.debug(channel) ibm_mq_message["channel"] = channel ccsid = jmeter_get_argument_value(sub_element.element.find( ".//stringProp[@name='MQPutMessageSampler.MQ_CCSID']").text) logger.debug(ccsid) ibm_mq_message["ccsid"] = ccsid # 添加脚本 ds = dealScriptData(node_path) ds.set_mq_with_default(ibm_mq_connect, ibm_mq_message) resp, script_id = post_blade.dealScriptData(ds) # 添加数据 step_object.set_scriptcontent(script_id) step = step_object.get_step() steps.append(step) else: logger.debug("IBM MQ 组件前没有获取到对应的Msg BeanShell 组件")
def deal_JDBCSample(root): step = importOfflineCase_step() step.set_stepname(root.get("testname")) step.set_stepdes(root.get("testname")) sql = replace_argument(root.element.find(".//stringProp[@name='query']").text) if "%" in sql: sql = sql.replace("%", "%25") logger.debug(sql) data_source = root.element.find(".//stringProp[@name='dataSource']").text sub_elements = root.get_sub_elements() # 没有子组件, 纯粹是执行一条sql if not sub_elements: logger.debug("no sub element") step.add_presqlcontent(data_sources[data_source], sql) return step.get_step() for sub_element in sub_elements: if not sub_element.isEnabled(): continue if sub_element.tag == "ResponseAssertion": check_string = "" checks_element = sub_element.element.findall("collectionProp//stringProp") if checks_element is None: checks = "" elif len(checks_element) == 1: checks = checks_element[0].text else: check_keys = re.findall(r'(?:select|SELECT|Select)(.*)(?:FROM|from|From)', sql)[0].replace(' ', '').replace(',', '\t') check_value = "" for check_element_index in range(len(checks_element)): check_value += checks_element[check_element_index].text if check_element_index != len(checks_element) - 1: check_value += "\t" checks = check_keys + "\n" + check_value if checks: checks_list = checks.split("\n") logger.debug(checks_list) check_values = [] for i in range(len(checks_list)): if not checks_list[i]: continue if i == 0: check_keys = checks_list[i].split("\t") else: check_values.append(checks_list[i].split("\t")) else: check_keys = re.findall(r'select(.*?)from', sql)[0].split(",") check_values = [[''] * len(check_keys)] for value_index in range(len(check_values)): for key_index in range(len(check_keys)): if key_index >= len(check_values[value_index]): check_string += check_keys[key_index].strip() + "=null" else: check_string += check_keys[key_index].strip() + "=" + check_values[value_index][key_index] if value_index == len(check_values) - 1 and key_index == len(check_keys) - 1: check_string += ";" else: check_string += "|" step.add_checkcontent(check_string, data_sources[data_source], sql) elif sub_element.tag == "JDBCPreProcessor": pre_sql = replace_argument(sub_element.element.find(".//stringProp[@name='query']").text) logger.debug(pre_sql) data_source = sub_element.element.find(".//stringProp[@name='dataSource']").text variable_name = sub_element.element.find(".//stringProp[@name='variableNames']").text if variable_name: pre_sql = variable_name + "|" + pre_sql step.add_presqlcontent(data_sources[data_source], pre_sql) return step.get_step()
def deal_threadgroup(root, node_path): # HTTP 组件 http_companents = [] # 线程组名称, 作为用例节点的父级目录名称 thread_group_name = root.get("testname") logger.info(node_path) sub_elements = root.get_sub_elements() # 如果是csv格式的,包含了控制器,特殊处理 if sub_elements[0].tag == "TransactionController": sub_elements = sub_elements[0].get_sub_elements() # 初始化导入用例请求 ioc = importOfflineCase(node_path + thread_group_name) messages = [] # 获取到所有关键组件 for sub_element in sub_elements: # 组件为禁用状态, 不读取 if not sub_element.isEnabled(): continue # 从 Beanshell 中将读取的csv文件key取出 if sub_element.tag in ("BeanShellSampler", "BeanShellPreProcessor") and not messages: if sub_element.tag == "BeanShellSampler": java_code = sub_element.element.find( ".//stringProp[@name='BeanShellSampler.query']").text else: java_code = sub_element.element.find( ".//stringProp[@name='script']").text # 获取csv 路径 key csv_re = re.compile(r'FileInputStream[(]vars.get[(]"(.*?)"[)]', re.S) csv_key = re.findall(csv_re, java_code)[0] file_path = arguments_local[csv_key] filename = file_path.split("/")[-1] logger.info(thread_group_name + "的 csv 文件名称" + filename) messages = deal_csv_file(filename) logger.info("读取csv文件内容结束") logger.info(messages) elif sub_element.tag == "Arguments": # copp 自定义变量里直接放的文件名, 直接获取报文内容, 无需将变量上送到blade csv_file_path = sub_element.element.find( ".//stringProp[@name='Argument.value']").text csv_file_name = csv_file_path.split("/")[-1] logger.info(thread_group_name + "的 csv 文件名称" + csv_file_name) messages = deal_csv_file(csv_file_name) logger.info("读取csv文件内容结束") logger.info(messages) elif sub_element.tag == "HTTPSamplerProxy": # 在这里改成将 HTTP 组件保存下来, 在后面循环遍历 Message, 重复发送 http_companents.append(sub_element) elif sub_element.tag == "JDBCSampler": # JDBC 组件处理 step = deal_JDBCSample(sub_element) ioc.add_case(sub_element.get("testname"), [step]) # 改到这里发HTTP请求 if messages: # 不为空 for message in messages: step_num = 0 steps = [] for http_companent in http_companents: step_num += 1 path = http_companent.element.find( ".//stringProp[@name='HTTPSampler.path']").text logger.info(path) # 先添加脚本 ds = dealScriptData(node_path) ds.set_data_with_default(http_companent.get("testname"), root_url, path, thread_group_name) resp, script_id = post_blade.dealScriptData(ds) # 再添加数据 request_body_half = http_companent.element.find( ".//stringProp[@name='Argument.value']").text requst_body = request_body_half.replace( "${req_body}", message["body"]) logger.debug(requst_body) steps.append( deal_HTTPSampler(http_companent, "步骤-" + str(step_num), script_id, requst_body, message["check_message"])) ioc.add_case(message["casename"], steps) elif http_companents: step_num = 0 steps = [] for http_companent in http_companents: step_num += 1 path = http_companent.element.find( ".//stringProp[@name='HTTPSampler.path']").text logger.info(path) # 先添加脚本 ds = dealScriptData(node_path) ds.set_data_with_default(http_companent.get("testname"), root_url, path, thread_group_name) resp, script_id = post_blade.dealScriptData(ds) # 再添加数据 steps.append( deal_HTTPSampler(http_companent, "步骤-" + str(step_num), script_id)) ioc.add_case(thread_group_name, steps) else: pass resp = post_blade.importOfflineCase(ioc) # logger.info(resp) if resp is not None: logger.error(thread_group_name + resp)
def deal_threadgroup(root, node_path): # 线程组名称, 作为用例名称 csv_flag = False thread_group_cases = False thread_group_name = root.get("testname") logger.debug(node_path) sub_elements = root.get_sub_elements() # 初始化导入用例请求 ioc = importOfflineCase(node_path) steps = [] # 检查当前线程组是否使用csv for sub_element in sub_elements: if not sub_element.isEnabled(): continue if sub_element.tag == "CSVDataSet": csv_flag = True break elif sub_element.tag == "HTTPSamplerProxy" and "正例" in sub_element.get( "testname"): thread_group_cases = True break elif sub_element.tag == "CounterConfig": # 有计数器,也是一种读取csv的情况 csv_flag = True break if csv_flag: for sub_element in sub_elements: if not sub_element.isEnabled(): continue # if sub_element.tag == "IfController": # root = sub_element cases = deal_csv_threadgroup(root) for case in cases: ioc.add_case(case[0], case[1]) elif thread_group_cases: # 组件为禁用状态, 不读取 for sub_element in sub_elements: if not sub_element.isEnabled(): continue step = None if sub_element.tag == "JDBCSampler": step = deal_JDBCSample(sub_element) elif sub_element.tag == "HTTPSamplerProxy": step = [deal_HTTPSampler(sub_element, "步骤一")] else: continue ioc.add_case(sub_element.get("testname"), step) else: # 获取到所有关键组件 for sub_element in sub_elements: # 组件为禁用状态, 不读取 if not sub_element.isEnabled(): continue if sub_element.tag == "JDBCSampler": steps += deal_JDBCSample(sub_element) elif sub_element.tag == "org.apache.jmeter.protocol.ssh.sampler.SSHCommandSampler": steps += deal_ssh_command(sub_element) elif sub_element.tag == "HTTPSamplerProxy": steps += [ deal_HTTPSampler(sub_element, sub_element.get("testname")) ] elif sub_element.tag == "LoopController": # 循环控制器检查结果 steps += deal_LoopController(sub_element) pass logger.debug(steps) ioc.add_case(thread_group_name, steps) # resp = None resp = post_blade.importOfflineCase(ioc) logger.debug(resp) if resp is not None: logger.error("用例{}添加失败, 原因:{}".format(thread_group_name, resp)) else: logger.info("用例{}添加成功".format(thread_group_name)) global count logger.info(count) count += 1
def deal_HTTPSampler(root, step_name, request_body="", check_message=""): # 没有传入报文内容, 自行获取当前报文内容, 否则使用传入内容 # 通过获取到的报文参数个数确认是否为json格式或者其他格式 content_type = None if not request_body: arguments = root.element.findall( ".//elementProp[@elementType='HTTPArgument']") if len(arguments) == 1 and arguments[0].find( ".//stringProp[@name='Argument.name']") is None: request_body = arguments[0].find( ".//stringProp[@name='Argument.value']").text else: content_type = "application/x-www-form-urlencoded" body = dict() for argument in arguments: key = argument.find( ".//stringProp[@name='Argument.name']").text value = argument.find( ".//stringProp[@name='Argument.value']").text body[key] = value logger.debug(key) logger.debug(value) request_body = str(body) # 生成脚本 path = root.element.find(".//stringProp[@name='HTTPSampler.path']").text logger.debug(path) # 先添加脚本 ds = dealScriptData(base_name) ds.set_data_with_default(root.get("testname"), root_url, path, content_type=content_type) resp, script_content = post_blade.dealScriptData(ds) check_string = "" # 报文提取 step = dict() step_json = dict() data_content = dict() step["stepName"] = step_name step["stepJson"] = step_json step_json["dataContent"] = data_content step_json["stepDes"] = root.get("testname") # 0—前置,1-后置,2-空 step_json["precisionTest"] = "2" pre_sqls = list() step_json["preSqlContent"] = pre_sqls step_json["scriptContent"] = script_content # request 特殊处理, 将其中使用的变量替换成blade变量 argument_re = re.compile(r'\${(.*?)}', re.S) arguments = re.findall(argument_re, request_body) for argument in arguments: # 不替换 jmeter 自带变量 if argument.startswith("__"): continue # 变量的写法可能是 ${test}, '${test}', "${test}" # 三种都替换 jmeter_argument = '"${' + argument + '}"' blade_argument = '"varc_' + argument + '"' request_body = request_body.replace(jmeter_argument, blade_argument) jmeter_argument = "'${' + argument + '}'" request_body = request_body.replace(jmeter_argument, blade_argument) jmeter_argument = '${' + argument + '}' request_body = request_body.replace(jmeter_argument, blade_argument) sub_elements = root.get_sub_elements() for sub_element in sub_elements: # 前置提取 if sub_element.tag == "JDBCPreProcessor": data_source = sub_element.element.find( ".//stringProp[@name='dataSource']").text sql = sub_element.element.find(".//stringProp[@name='query']").text logger.debug(sql) pre_sql = { # 暂没遇到, 遇到后修改 "connection": data_sources[data_source], "id": "", "type": "2", "content": "%s" % sql } pre_sqls.append(pre_sql) # 后置提取 # 验证提取 elif sub_element.tag == "BeanShellAssertion": if not check_message: assert_text = sub_element.element.find( ".//stringProp[@name='BeanShellAssertion.query']").text results = re.findall(r'"(.*?)".equals\("(.*?)"\)', assert_text) logger.debug(results) for result in results: if not results.index(result) == 0: check_message += ";" if "respcode" in result[1].lower(): if "UNKNOWN" in result[0].upper(): continue check_message += check_msg_head + 'respCode=' + result[ 0] elif "respmsg" in result[1].lower(): check_message += check_msg_head + 'respMsg=' + result[0] elif "servicestatus" in result[1].lower(): check_message += check_msg_head + 'serviceStatus=' + result[ 0] check_string = check_message logger.debug(request_body) data_content["dataChoseRow"], data_content["dataArrContent"] = Josn2Blade( eval(request_body), [], 0, check_string) data_content["id"] = "" data_content["content"] = "" logger.debug(step) return step
def deal_csv_file(filename, stop_list=list()): ''' 读取csv文件, 获取报文内容, 用例名称和验证结果 返回一个包含所有用例数据的列表, 列表格式如下 messages = [ {"casename": , 用例名称 "body": , 报文内容 "case_side_type":, 正反例类型 "check_message": 验证结果字符串 }, {"casename": , 用例名称 "body": , 报文内容 "case_side_type":, 正反例类型 "check_message": 验证结果字符串 } ] :param filename: 待读取的 csv 文件 :return: 包含所有用例数据的列表 ''' if not stop_list: stop_list = ['yq_respcode', 'yq_respmsg'] # stop_list = ['ziduanname'] logger.debug(stop_list) # 给的脚本里文件绝对路径与本机不同 # 所有只需要脚本名称, 直接从项目的路径下取文件 logger.debug(filename) csv_file = open(CSV_FILE_DIR / filename, encoding="gbk") # 数据长度不一定, 通过 yq_respCode 字段定位报文结束位置 titles = csv_file.readline().split(",") message_stop_index = len(titles) for title in titles: if title in stop_list: message_stop_index = titles.index(title) break messages = [] for line in csv_file.readlines(): temp = dict() message = dict() data = line.split(",")[0:message_stop_index] check_data = line.split(",")[message_stop_index:message_stop_index + 3] logger.debug(data) for i in range(1, len(data) - 3): temp[titles[i]] = data[i] message["casename"] = data[0] message["casename"] = message["casename"].replace("<", "").replace(">", "") # 获取正反用例类型 if "正例" in data[0]: message["case_side_type"] = "0" else: message["case_side_type"] = "1" # 考虑下没有结果验证的场景 if len(check_data): message["check_message"] = check_msg_head + 'respCode=' + check_data[-3] + ';' + check_msg_head + 'respMsg=' + \ check_data[ -2] + ';' + check_msg_head + 'serviceStatus=' + check_data[-1] else: message["check_message"] = "" message["body"] = json.dumps(temp) messages.append(message) return messages
def deal_HTTPSampler(root, step_name, script_content, request_body="", check_message=""): check_string = "" # 报文提取 step = dict() step_json = dict() data_content = dict() step["stepName"] = step_name step["stepJson"] = step_json step_json["dataContent"] = data_content step_json["stepDes"] = root.get("testname") # 0—前置,1-后置,2-空 step_json["precisionTest"] = "2" pre_sqls = list() step_json["preSqlContent"] = pre_sqls step_json["scriptContent"] = script_content # 没有传入报文内容, 自行获取当前报文内容, 否则使用传入内容 if not request_body: request_body = root.element.find( ".//stringProp[@name='Argument.value']").text # request 特殊处理, 将其中使用的变量替换成blade变量 argument_re = re.compile(r'\${(.*?)}', re.S) arguments = re.findall(argument_re, request_body) for argument in arguments: # 不替换 jmeter 自带变量 if argument.startswith("__"): continue # 变量的写法可能是 ${test}, '${test}', "${test}" # 三种都替换 jmeter_argument = '"${' + argument + '}"' blade_argument = '"varc_' + argument + '"' request_body = request_body.replace(jmeter_argument, blade_argument) jmeter_argument = "'${' + argument + '}'" request_body = request_body.replace(jmeter_argument, blade_argument) jmeter_argument = '${' + argument + '}' request_body = request_body.replace(jmeter_argument, blade_argument) sub_elements = root.get_sub_elements() for sub_element in sub_elements: # 前置提取 if sub_element.tag == "JDBCPreProcessor": sql = sub_element.element.find(".//stringProp[@name='query']").text logger.info(sql) pre_sql = { "connection": connection, "id": "", "type": "2", "content": "%s" % sql } pre_sqls.append(pre_sql) # 后置提取 # 验证提取 elif sub_element.tag in ("ResponseAssertion", "BeanShellAssertion"): logger.debug(check_message) check_string = check_message logger.debug(request_body) data_content["dataChoseRow"], data_content["dataArrContent"] = Josn2Blade( eval(request_body), [], 0, check_string) data_content["id"] = "" data_content["content"] = "" logger.debug(step) return step