addproject
This commit is contained in:
851
base_framework/platform_tools/Testcase_service/case_service.py
Normal file
851
base_framework/platform_tools/Testcase_service/case_service.py
Normal file
@@ -0,0 +1,851 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
import copy
|
||||
import importlib
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import sys
|
||||
import string
|
||||
import time
|
||||
import traceback
|
||||
|
||||
|
||||
def get_project_root_path(path="base_framework"):
|
||||
"""
|
||||
获取项目目录
|
||||
"""
|
||||
o_path = os.getcwd()
|
||||
try:
|
||||
project_path = re.search(r"(.*%s)" % path, o_path).group(1)
|
||||
return os.path.abspath(os.path.join(project_path, os.path.pardir))
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
Project_Path = get_project_root_path()
|
||||
sys.path.append(Project_Path)
|
||||
|
||||
from base_framework.platform_tools.Keywords_service.keyword_service import SetAttr, log
|
||||
|
||||
|
||||
def load_module_from_file(file_path, team):
|
||||
module_file = re.search(r"\\(%s\\.*)\.py" % team, file_path)
|
||||
# if not module_file:
|
||||
# module_file = re.search(r"\\(%s\\.*)\.py" % team.lower(), file_path)
|
||||
temp = module_file.group(1)
|
||||
temp = temp.replace(os.sep, ".")
|
||||
# try:
|
||||
# module = importlib.import_module(temp)
|
||||
# except Exception as err:
|
||||
# temp = re.sub(r"%s\." % team, "%s." % team.lower(), temp)
|
||||
# module = importlib.import_module(temp)
|
||||
return importlib.import_module(temp)
|
||||
|
||||
|
||||
class ITCaseFileOperation(object):
|
||||
def __init__(self, team, kw_instance):
|
||||
self.kw = kw_instance
|
||||
self.all_url = kw_instance.all_url
|
||||
self.kw_class_name = kw_instance.kw_class
|
||||
self.case_dir = os.path.abspath(os.path.join(Project_Path, team, "test_case", "TestCase", "1.接口"))
|
||||
self.env_path = os.path.abspath(
|
||||
os.path.join(Project_Path, team, "test_case", "Resource", "AdapterKws", "env.robot"))
|
||||
|
||||
def _check_case_file_exist(self, file_path):
|
||||
if os.path.exists(file_path) and os.path.isfile(file_path):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def check_case_exist(self, case_path, case_name):
|
||||
if self._check_case_file_exist(case_path):
|
||||
with open(case_path, "r", encoding="utf-8") as f:
|
||||
for line in f.readlines():
|
||||
if line.startswith(case_name):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
def generate_case_file(self, file_path):
|
||||
dirname = file_path[:-len(os.path.basename(file_path))]
|
||||
if not self._check_case_file_exist(file_path):
|
||||
if not os.path.exists(dirname):
|
||||
os.makedirs(dirname)
|
||||
self.write_content_to_case_file(file_path, self.generate_env_releate_path(dirname))
|
||||
else:
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
content = f.readlines()
|
||||
if content:
|
||||
if "\n" != content[-1]:
|
||||
self.write_content_to_case_file(file_path, "\n")
|
||||
else:
|
||||
self.write_content_to_case_file(file_path, self.generate_env_releate_path(dirname))
|
||||
|
||||
def generate_env_releate_path(self, file_path):
|
||||
return "*** Settings ***\nResource " + os.path.relpath(self.env_path,
|
||||
file_path).replace("\\",
|
||||
"/") + "\n\n*** Test Cases ***\n"
|
||||
|
||||
def _check_case_file_resource(self, file_path):
|
||||
"""
|
||||
确定case文件中是否有关键字
|
||||
"""
|
||||
with open(file_path, "a+", encoding="utf-8") as f:
|
||||
content_list = f.readlines()
|
||||
if "*** Keywords ***\n" not in content_list:
|
||||
return True
|
||||
else:
|
||||
kw_index = content_list.rindex("*** Keywords ***\n")
|
||||
for index in range(kw_index, len(content_list) + 1):
|
||||
if "*** Test Cases ***\n" == content_list[index]:
|
||||
status = True
|
||||
if "*** Keywords ***\n" == content_list[index]:
|
||||
status = False
|
||||
return status
|
||||
|
||||
def write_content_to_case_file(self, file_path, content):
|
||||
status = self._check_case_file_resource(file_path)
|
||||
with open(file_path, "a+", encoding="utf-8") as f:
|
||||
if status:
|
||||
f.write(content)
|
||||
else:
|
||||
content = "*** Test Cases ***\n" + content
|
||||
f.write(content)
|
||||
|
||||
|
||||
class ITCaseContentOperation(object):
|
||||
def __init__(self, team, kw_instance):
|
||||
self.team = team
|
||||
self.file = ITCaseFileOperation(team, kw_instance)
|
||||
self.doc_content_row_temp = " ... | {} | {} | {} |"
|
||||
self.normal_1001 = None
|
||||
self.un_expect_list = None
|
||||
self.case_string = None
|
||||
|
||||
def _generate_case_name(self, interface_name, case_type, case_des):
|
||||
return "-".join([interface_name, case_type, case_des])
|
||||
|
||||
def _check_interface_confirm(self, interface_info):
|
||||
if not interface_info.confirmed:
|
||||
raise Exception("接口%s未确认,请先确认接口参数。" % interface_info.name)
|
||||
|
||||
def generate_case_body_all_1001_array(self, request_demo, parameters):
|
||||
temp_list = list()
|
||||
demo_copy = copy.deepcopy(request_demo)
|
||||
for key, value in request_demo.items():
|
||||
if not value:
|
||||
demo_copy.pop(key)
|
||||
if len(demo_copy.keys()) == 1:
|
||||
demo_copy = demo_copy.pop(list(demo_copy.keys())[0])
|
||||
dict_para, self.un_expect_list, _, _ = self._analysis_case_parameters_to_dict(parameters)
|
||||
demo_add_values = self._analysis_case_parameters_to_value(demo_copy, dict_para)
|
||||
data_list = self._analysis_dict_to_body_value(demo_copy, demo_add_values)
|
||||
if isinstance(demo_copy, list):
|
||||
for item in data_list:
|
||||
temp_list.append([item])
|
||||
data_list = temp_list
|
||||
return data_list
|
||||
|
||||
def _generate_parameter_to_dict(self, parameters):
|
||||
dict_temp = dict()
|
||||
for parameter in parameters:
|
||||
parameter_attr = SetAttr(parameter)
|
||||
dict_temp[parameter_attr.name] = parameter_attr
|
||||
return dict_temp
|
||||
|
||||
def _analysis_case_parameters_to_value_empty_dict(self, request_demo, parameters, type=None):
|
||||
"""
|
||||
循环生成缺少某个参数的值,其它正确的参数组合列表
|
||||
"""
|
||||
parameter_expect_list = list()
|
||||
expect_lenth = 0
|
||||
un_expect_lenth = 0
|
||||
parameter_expect_dict = dict()
|
||||
parameter_un_expect_dict = dict()
|
||||
for key, parameter_attr in parameters.items():
|
||||
if parameter_attr.normal_values:
|
||||
parameter_expect_dict[parameter_attr.name] = parameter_attr.normal_values.split(",")
|
||||
else:
|
||||
parameter_expect_dict[parameter_attr.name] = [
|
||||
self._generate_body_expect_type_value(parameter_attr.type)]
|
||||
|
||||
if len(parameter_expect_dict[parameter_attr.name]) > expect_lenth:
|
||||
expect_lenth = len(parameter_expect_dict[parameter_attr.name])
|
||||
|
||||
if parameter_attr.exception_values:
|
||||
parameter_un_expect_dict[parameter_attr.name] = parameter_attr.exception_values.split(",")
|
||||
else:
|
||||
parameter_un_expect_dict[parameter_attr.name] = [
|
||||
self._generate_body_un_expect_type_value(parameter_attr.type)]
|
||||
|
||||
if len(parameter_un_expect_dict[parameter_attr.name]) > un_expect_lenth:
|
||||
un_expect_lenth = len(parameter_un_expect_dict[parameter_attr.name])
|
||||
|
||||
for key in parameter_expect_dict.keys():
|
||||
if key not in json.dumps(request_demo):
|
||||
continue
|
||||
value = copy.copy(parameter_expect_dict)
|
||||
value[key] = ['NULL']
|
||||
if parameters.get(key).is_need == 1:
|
||||
status = "FAIL"
|
||||
else:
|
||||
status = "PASS"
|
||||
if type == "1102":
|
||||
name = "缺少参数%s" % key
|
||||
else:
|
||||
name = "缺少参数%s的值" % key
|
||||
parameter_expect_list.append([value, status, name])
|
||||
return parameter_expect_list
|
||||
|
||||
def _distinguish_parameters_by_is_needed(self, parameters):
|
||||
"""
|
||||
将必填参数和非必须参数分开成2个列表
|
||||
"""
|
||||
need_parameters = list()
|
||||
no_need_parameters = list()
|
||||
for parameter in parameters:
|
||||
parameter_attr = SetAttr(parameter)
|
||||
if parameter_attr.is_need != 0:
|
||||
need_parameters.append(parameter_attr)
|
||||
else:
|
||||
no_need_parameters.append(parameter_attr)
|
||||
return need_parameters, no_need_parameters
|
||||
|
||||
def _replace_null_value_no_need_parameters(self, demo, no_need_parameter_attrs):
|
||||
"""
|
||||
将所有非必填参数置空
|
||||
"""
|
||||
really_body = copy.deepcopy(demo)
|
||||
for parameter_attr in no_need_parameter_attrs:
|
||||
if re.search(r"\"%s\"" % parameter_attr.name, demo):
|
||||
check_para = r"\"%s\":\s[\[\{]" % parameter_attr.name
|
||||
if re.search(check_para, demo):
|
||||
continue
|
||||
try:
|
||||
expect_value = parameter_attr.normal_values.split(",")[0]
|
||||
except Exception as err:
|
||||
log.error(err)
|
||||
raise Exception("接口参数%s无正常值,请先确认接口参数。" % parameter_attr.name)
|
||||
patten1 = r"\"%s\":\s\"%s\"" % (parameter_attr.name, expect_value)
|
||||
replace1 = "\"%s\": \"NULL\"" % parameter_attr.name
|
||||
really_body = re.sub(patten1, replace1, really_body)
|
||||
return really_body
|
||||
|
||||
def generate_case_body_all_1101_array(self, request_demo, parameters):
|
||||
"""
|
||||
生成1101用例对应的所有请求参数组合
|
||||
"""
|
||||
body_array = list()
|
||||
need, no_need = self._distinguish_parameters_by_is_needed(parameters)
|
||||
demo_json = json.dumps(request_demo, ensure_ascii=False)
|
||||
if no_need:
|
||||
no_need_demo_json = self._replace_null_value_no_need_parameters(demo_json, no_need)
|
||||
body_array.append([json.loads(no_need_demo_json), "PASS", "所有非必填参数为空"])
|
||||
for item in need:
|
||||
parameter_attr = copy.copy(item)
|
||||
demo_json_copy = copy.copy(demo_json)
|
||||
if re.search("\"%s\"" % parameter_attr.name, demo_json_copy):
|
||||
check_para = r"\"%s\":\s\{|\"%s\":\s\[\{" % (parameter_attr.name, parameter_attr.name)
|
||||
if re.search(check_para, demo_json_copy):
|
||||
continue
|
||||
name = "缺少参数%s" % parameter_attr.name
|
||||
log.info("1101:%s" % name)
|
||||
try:
|
||||
expect_value = parameter_attr.normal_values.split(",")[0]
|
||||
except Exception as err:
|
||||
log.error(err)
|
||||
raise Exception("接口参数%s无正常值,请先确认接口参数。" % parameter_attr.name)
|
||||
if parameter_attr.type == "array":
|
||||
patten1 = r"\"%s\":\s\[\"%s\"\]" % (parameter_attr.name, expect_value)
|
||||
replace1 = "\"%s\": []" % parameter_attr.name
|
||||
else:
|
||||
patten1 = r"\"%s\":\s\"%s\"" % (parameter_attr.name, expect_value)
|
||||
patten1 = patten1.replace("{", r"\{")
|
||||
patten1 = patten1.replace("}", r"\}")
|
||||
patten1 = patten1.replace("[", r"\[")
|
||||
patten1 = patten1.replace("]", r"\]")
|
||||
patten1 = patten1.replace("$", r"\$")
|
||||
replace1 = "\"%s\": \"NULL\"" % parameter_attr.name
|
||||
really_body = re.sub(patten1, replace1, demo_json_copy)
|
||||
if parameter_attr.is_need == 1:
|
||||
status = "FAIL"
|
||||
else:
|
||||
status = "PASS"
|
||||
body_array.append([json.loads(really_body), status, name])
|
||||
return body_array
|
||||
|
||||
def _clean_all_none_json_char(self, really_body):
|
||||
"""
|
||||
清除1102场景删除缺少参数后不规则的字符串内容
|
||||
"""
|
||||
really_body = re.sub(",\s,", ",", really_body)
|
||||
really_body = re.sub("\[\s?,", "[", really_body)
|
||||
really_body = re.sub("\{\s?,", "{", really_body)
|
||||
really_body = re.sub(",\s\]", "]", really_body)
|
||||
really_body = re.sub(",\s\}", "}", really_body)
|
||||
really_body = re.sub("\s,", "", really_body)
|
||||
return really_body
|
||||
|
||||
def _replace_null_all_no_need_parameters(self, demo, no_need_parameter_attrs):
|
||||
"""
|
||||
将所有非必填参数置空
|
||||
"""
|
||||
really_body = copy.deepcopy(demo)
|
||||
for parameter_attr in no_need_parameter_attrs:
|
||||
if re.search(r"\"%s\"" % parameter_attr.name, demo):
|
||||
check_para = r"\"%s\":\s\{|\"%s\":\s\[\{" % (parameter_attr.name, parameter_attr.name)
|
||||
if re.search(check_para, demo):
|
||||
continue
|
||||
try:
|
||||
expect_value = parameter_attr.normal_values.split(",")[0]
|
||||
except Exception as err:
|
||||
log.error(err)
|
||||
raise Exception("接口参数%s无正常值,请先确认接口参数。" % parameter_attr.name)
|
||||
if parameter_attr.type == "array":
|
||||
patten1 = r"\"%s\":\s\[\"%s\"\]" % (parameter_attr.name, expect_value)
|
||||
else:
|
||||
patten1 = r"\"%s\":\s\"%s\"" % (parameter_attr.name, expect_value)
|
||||
replace1 = ""
|
||||
really_body = re.sub(patten1, replace1, really_body)
|
||||
really_body = self._clean_all_none_json_char(really_body)
|
||||
return really_body
|
||||
|
||||
def generate_case_body_all_1102_array(self, request_demo, parameters):
|
||||
"""
|
||||
生成1102用例对应的所有参数组合
|
||||
"""
|
||||
body_array = list()
|
||||
need, no_need = self._distinguish_parameters_by_is_needed(parameters)
|
||||
demo_json = json.dumps(request_demo, ensure_ascii=False)
|
||||
if no_need:
|
||||
no_need_demo_json = self._replace_null_all_no_need_parameters(demo_json, no_need)
|
||||
body_array.append([json.loads(no_need_demo_json), "PASS", "所有非必填参数均缺失"])
|
||||
for item in need:
|
||||
parameter_attr = copy.copy(item)
|
||||
demo_json_copy = copy.copy(demo_json)
|
||||
if re.search(r"\"%s\"" % parameter_attr.name, demo_json_copy):
|
||||
check_para = r"\"%s\":\s\{|\"%s\":\s\[\{" % (parameter_attr.name, parameter_attr.name)
|
||||
if re.search(check_para, demo_json_copy):
|
||||
continue
|
||||
name = "缺少参数%s" % parameter_attr.name
|
||||
log.info("1102:%s" % name)
|
||||
expect_value = parameter_attr.normal_values.split(",")[0]
|
||||
if parameter_attr.type == "array":
|
||||
patten1 = r"\"%s\":\s\[\"%s\"\]" % (parameter_attr.name, expect_value)
|
||||
else:
|
||||
patten1 = r"\"%s\":\s\"%s\"" % (parameter_attr.name, expect_value)
|
||||
patten1 = patten1.replace("{", r"\{")
|
||||
patten1 = patten1.replace("}", r"\}")
|
||||
patten1 = patten1.replace("[", r"\[")
|
||||
patten1 = patten1.replace("]", r"\]")
|
||||
patten1 = patten1.replace("$", r"\$")
|
||||
replace1 = ""
|
||||
really_body = re.sub(patten1, replace1, demo_json_copy)
|
||||
really_body = self._clean_all_none_json_char(really_body)
|
||||
if parameter_attr.is_need == 1:
|
||||
status = "FAIL"
|
||||
else:
|
||||
status = "PASS"
|
||||
body_array.append([json.loads(really_body), status, name])
|
||||
return body_array
|
||||
|
||||
def generate_case_body_all_1201_array(self, request_demo, parameters):
|
||||
"""
|
||||
生成1201用例对应的所有参数组合
|
||||
"""
|
||||
body_array = list()
|
||||
demo_json = json.dumps(request_demo, ensure_ascii=False)
|
||||
for item in parameters:
|
||||
parameter_attr = SetAttr(item)
|
||||
if re.search(r"\"%s\"" % parameter_attr.name, demo_json):
|
||||
check_para = r"\"%s\":\s\{|\"%s\":\s\[\{" % (parameter_attr.name, parameter_attr.name)
|
||||
if re.search(check_para, demo_json):
|
||||
continue
|
||||
log.info("参数%s开始替换异常值" % parameter_attr.name)
|
||||
for un_expect_item in self.un_expect_list.get(parameter_attr.name, []):
|
||||
name = "参数%s使用异常值%s" % (parameter_attr.name, un_expect_item)
|
||||
demo_json_copy = copy.copy(demo_json)
|
||||
expect_value = parameter_attr.normal_values.split(",")[0]
|
||||
if parameter_attr.type == "array":
|
||||
patten1 = r"\"%s\":\s\[\"%s\"\]" % (parameter_attr.name, expect_value)
|
||||
replace1 = '"%s": ["%s"]' % (parameter_attr.name, un_expect_item)
|
||||
else:
|
||||
patten1 = r"\"%s\":\s\"%s\"" % (parameter_attr.name, expect_value)
|
||||
patten1 = patten1.replace("{", r"\{")
|
||||
patten1 = patten1.replace("}", r"\}")
|
||||
patten1 = patten1.replace("[", r"\[")
|
||||
patten1 = patten1.replace("]", r"\]")
|
||||
patten1 = patten1.replace("$", r"\$")
|
||||
replace1 = '"%s": "%s"' % (parameter_attr.name, un_expect_item)
|
||||
really_body = re.sub(patten1, replace1, demo_json_copy)
|
||||
status = "FAIL"
|
||||
|
||||
body_array.append([json.loads(really_body), status, name])
|
||||
return body_array
|
||||
|
||||
def create_case_content(self, result_path, interface_info, parameters, demo, case_type, tags=None):
|
||||
"""
|
||||
生成用例的所有内容
|
||||
"""
|
||||
self._check_interface_confirm(interface_info)
|
||||
body_content = list()
|
||||
doc = self.generate_case_doc(interface_info, tags=tags, demo=demo)
|
||||
case_file, _ = self.generate_case_file_path(interface_info)
|
||||
interface_name = interface_info.name
|
||||
if not parameters:
|
||||
body = self.generate_case_body_content(interface_info.in_url, doc, interface_name, case_type,
|
||||
interface_info.interface_describe, None, status="PASS")
|
||||
|
||||
else:
|
||||
try:
|
||||
body_array = self.generate_case_body_all_1001_array(demo, parameters)
|
||||
self.normal_1001 = body_array[0]
|
||||
except TypeError:
|
||||
log.warning(traceback.print_exc())
|
||||
body_array = []
|
||||
self.normal_1001 = {}
|
||||
if case_type == "1001":
|
||||
try:
|
||||
body = self.generate_case_body_content(interface_info.in_url, doc, interface_name, case_type,
|
||||
interface_info.interface_describe, body_array, status="PASS")
|
||||
except Exception as err:
|
||||
msg = "生成用例%s,%s失败原因如下:%s" % (interface_info.type, interface_info.in_url, traceback.print_exc())
|
||||
log.error(msg)
|
||||
self.file.write_content_to_case_file(result_path, msg + "\n")
|
||||
|
||||
elif case_type == "1101" or case_type == "1102" or case_type == "1201":
|
||||
body_temp_list = []
|
||||
# parameters_temp = self._generate_parameter_to_dict(parameters)
|
||||
try:
|
||||
body_array = eval(
|
||||
"self.generate_case_body_all_%s_array(self.normal_1001, parameters)" % case_type)
|
||||
if case_type == "1101":
|
||||
name = "缺少参数值"
|
||||
elif case_type == "1102":
|
||||
name = "缺少参数key和值"
|
||||
elif case_type == "1201":
|
||||
name = "参数使用异常值"
|
||||
else:
|
||||
name = ""
|
||||
body_tmp = self.generate_case_body_content(interface_info.in_url, doc, interface_name,
|
||||
case_type,
|
||||
name, body_array, status="PASS")
|
||||
body_temp_list.append(body_tmp)
|
||||
body = "".join(body_temp_list)
|
||||
except Exception as err:
|
||||
msg = "生成用例%s,%s失败原因如下:%s" % (interface_info.type, interface_info.in_url, traceback.print_exc())
|
||||
log.error(msg)
|
||||
self.file.write_content_to_case_file(result_path, msg + "\n")
|
||||
raise err
|
||||
body_content.append(body)
|
||||
self.file.write_content_to_case_file(case_file, "\n".join(body_content))
|
||||
msg = "接口url:%s,%s,生成case%s成功!路径为:%s" % (interface_info.type, interface_info.in_url, case_type, case_file)
|
||||
log.info(msg)
|
||||
self.file.write_content_to_case_file(result_path, msg + "\n")
|
||||
return msg
|
||||
|
||||
def generate_case_body_content(self, url, doc, interface_name, case_type, description, body_para, status="PASS"):
|
||||
body_content = list()
|
||||
case_name = self._generate_case_name(interface_name, case_type, description)
|
||||
body_content.append(case_name)
|
||||
body_content.append(doc)
|
||||
# 如何需要自动生成1001类型用例的请求body数据,请将304/305行放开,并把306~310注释
|
||||
request = self._generate_case_body_content(url, body_content=body_para, status=status)
|
||||
body_content.append(request)
|
||||
# if case_type != "1001":
|
||||
# request = self._generate_case_body_content(url, body_content=body_para, status=status)
|
||||
# body_content.append(request)
|
||||
# else:
|
||||
# body_content.append(" #请自行添加用例请求数据!\n")
|
||||
return "\n".join(body_content)
|
||||
|
||||
def _generate_case_body_content(self, url, body_content=None, status="PASS"):
|
||||
body_list = []
|
||||
if body_content is None:
|
||||
try:
|
||||
body_request = " ${resp} %s" % (self.file.all_url.get(url)[1])
|
||||
except Exception as err:
|
||||
log.error(traceback.print_exc())
|
||||
body_request = " #url: %s 无法找到对应的关键字,请检查并更新!" % url
|
||||
body_list.append(body_request)
|
||||
body_list.append(" Log ${resp}")
|
||||
if self.team.upper() in ["TMO"]:
|
||||
body_validate_success = " should be equal as json ${resp} %s" % '请自行添加检查结果'
|
||||
else:
|
||||
body_validate_code = " Should Be Equal ${resp['code']} ${200}"
|
||||
body_validate_success = " Should Be True ${resp['success']}"
|
||||
body_list.append(body_validate_code)
|
||||
body_list.append(body_validate_success)
|
||||
else:
|
||||
if not body_content:
|
||||
body_create = " #request_demo无内容或者parameters在数据表中不全,请先检查再生成 \n ${body} Evaluate %s" % body_content
|
||||
body_list.append(body_create)
|
||||
count = 0
|
||||
for real_body in body_content:
|
||||
body_error = None
|
||||
result = {"message": "", "code": 200, "success": True}
|
||||
temp = copy.copy(real_body)
|
||||
if len(real_body) == 3 and isinstance(real_body, list):
|
||||
if real_body[1] == "PASS" or real_body[1] == "FAIL":
|
||||
real_body = temp[0]
|
||||
status = temp[1]
|
||||
case_description = temp[2]
|
||||
body_list.append(" #%s" % case_description)
|
||||
try:
|
||||
module = load_module_from_file(self.file.kw.kw_file_path, self.team)
|
||||
importlib.reload(module)
|
||||
if isinstance(real_body, list):
|
||||
temp_type = "*"
|
||||
else:
|
||||
temp_type = "**"
|
||||
result = eval(
|
||||
"%s.%s().%s(%sreal_body)" % (
|
||||
"module", self.file.kw_class_name, self.file.all_url.get(url)[1], temp_type))
|
||||
except:
|
||||
msg = "#url: %s 无法通过参数得到请求结果!" % url
|
||||
log.warning(real_body)
|
||||
log.warning(msg)
|
||||
log.warning(traceback.print_exc())
|
||||
if "${time}" in str(real_body):
|
||||
body_list.append(" ${time} get time epoch")
|
||||
body_create = " ${body_%s} Evaluate %s" % (count, real_body)
|
||||
try:
|
||||
if isinstance(real_body, list):
|
||||
body_request = " ${resp_%s} %s %s" % (
|
||||
count, self.file.all_url.get(url)[1], "@{body_%s}" % count)
|
||||
elif isinstance(real_body, dict):
|
||||
body_request = " ${resp_%s} %s %s" % (
|
||||
count, self.file.all_url.get(url)[1], "&{body_%s}" % count)
|
||||
except Exception as err:
|
||||
log.error(traceback.print_exc())
|
||||
body_request = " #url: %s 无法找到对应的关键字,请检查并更新!" % url
|
||||
body_list.append(body_create)
|
||||
body_list.append(body_request)
|
||||
body_list.append(" Log ${resp_%s}" % count)
|
||||
if self.team.upper() in ["TMO"]:
|
||||
body_validate_resp = " Should Be Equal as json ${resp_%s} %s" % (count, result)
|
||||
else:
|
||||
try:
|
||||
body_validate_code = " Should Be Equal as strings ${resp_%s['code']} ${%s}"
|
||||
# body_validate_success = " %s ${resp_%s['success']}"
|
||||
body_validate_success = " %s ${resp_%s['success']} %s"
|
||||
body_validate_resp = " %s ${resp_%s[\"message\"]} %s"
|
||||
if isinstance(result, str):
|
||||
body_validate_code = " #特殊接口返回!"
|
||||
body_validate_success = " #返回为bytes类型的字符码。仅检查结果是否相等!"
|
||||
body_validate_resp = " Should Be Equal as strings ${resp_%s} %s" % (count, result)
|
||||
|
||||
elif status == "PASS":
|
||||
body_validate_code = body_validate_code % (count, result['code'])
|
||||
body_validate_success = body_validate_success % ("Should Be True", count, "")
|
||||
try:
|
||||
if result["message"]:
|
||||
body_validate_resp = body_validate_resp % (
|
||||
"Should Be Equal as strings", count, result["message"])
|
||||
else:
|
||||
body_validate_resp = body_validate_resp % (
|
||||
"Should Be Equal as strings", count, '${EMPTY}')
|
||||
except KeyError as err:
|
||||
body_validate_resp = " #resp中没有message,请后续自行添加!"
|
||||
log.warning(err)
|
||||
log.warning("resp中没有message,请后续自行添加!")
|
||||
else:
|
||||
try:
|
||||
body_validate_code = body_validate_code % (count, result['code'])
|
||||
except Exception as e:
|
||||
if "status" in result:
|
||||
body_validate_code = body_validate_code % (count, result['status'])
|
||||
body_validate_code = body_validate_code.replace("code", "status")
|
||||
else:
|
||||
raise KeyError("接口不中无code返回,请与开发确认!!!")
|
||||
try:
|
||||
body_validate_success = body_validate_success % (
|
||||
"Should Be Equal As Strings", count, result["success"])
|
||||
except Exception as err:
|
||||
if "error" in result:
|
||||
body_validate_success = body_validate_success % (
|
||||
"Should Be Equal As Strings", count, result["error"])
|
||||
body_validate_success = body_validate_success.replace("success", "error")
|
||||
else:
|
||||
raise KeyError("接口不中无success返回,请与开发确认!!!")
|
||||
try:
|
||||
if result.get("message"):
|
||||
if re.search("[a-zA-Z0-9]{32}", result.get("message", "")):
|
||||
body_validate_resp = body_validate_resp % ("should contain", count,
|
||||
re.sub("[a-zA-Z0-9]{32}", "", result["message"]))
|
||||
else:
|
||||
body_validate_resp = body_validate_resp % (
|
||||
"should be equal as strings", count, result["message"])
|
||||
else:
|
||||
body_validate_resp = body_validate_resp % (
|
||||
"Should Be Equal as strings", count, '${EMPTY}')
|
||||
except KeyError as err:
|
||||
body_validate_resp = " #resp中没有message,请后续自行添加!"
|
||||
log.warning(err)
|
||||
log.warning("resp中没有message,请后续自行添加!")
|
||||
except Exception as error:
|
||||
log.error(error)
|
||||
body_validate_code = None
|
||||
body_validate_success = None
|
||||
body_validate_resp = None
|
||||
body_error = " #无法正确生成异常用例返回值,请检查并手动生成!"
|
||||
if body_validate_code:
|
||||
body_list.append(body_validate_code)
|
||||
if body_validate_success:
|
||||
body_list.append(body_validate_success)
|
||||
if body_validate_resp:
|
||||
body_list.append(body_validate_resp)
|
||||
if body_error:
|
||||
body_list.append(body_error)
|
||||
# body_list.append(" #请自行添加data校验!")
|
||||
count += 1
|
||||
body_list.append("\n")
|
||||
return "\n".join(body_list)
|
||||
|
||||
def _generate_body_expect_type_value(self, type):
|
||||
if type.lower() == 'integer':
|
||||
value = random.randint(0, 100)
|
||||
elif type.lower() == "string":
|
||||
value = "".join([random.choice(string.digits + string.ascii_letters) for i in range(5)])
|
||||
elif type.lower() == "date":
|
||||
value = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
||||
elif type.lower() == "boolean":
|
||||
value = True
|
||||
elif type.lower() == "array":
|
||||
value = [1]
|
||||
else:
|
||||
value = "123"
|
||||
return value
|
||||
|
||||
def _generate_body_un_expect_type_value(self, type):
|
||||
value = ""
|
||||
if type.lower() == 'integer':
|
||||
value = "".join([random.choice(string.digits + string.ascii_letters) for i in range(5)])
|
||||
elif type.lower() == "string":
|
||||
value = random.randint(0, 10000)
|
||||
else:
|
||||
value = False
|
||||
return value
|
||||
|
||||
def _analysis_dict_to_body_value(self, dict_none, dict_data):
|
||||
"""
|
||||
生成所有请求参数的组合列表
|
||||
"""
|
||||
data_list = []
|
||||
if isinstance(dict_none, list):
|
||||
if dict_none:
|
||||
for index in range(len(dict_none)):
|
||||
data = self._analysis_dict_to_body_value(dict_none[index], dict_data[index])
|
||||
data_list.extend(data)
|
||||
else:
|
||||
data_list = dict_data
|
||||
elif isinstance(dict_none, dict):
|
||||
try:
|
||||
len_num = self._get_nums(dict_data)
|
||||
except Exception as e:
|
||||
# log.error(e)
|
||||
log.error("数据表request_parameters中参数不全,请使用interface_hunter补全参数")
|
||||
raise e
|
||||
for i in range(0, len_num):
|
||||
copy_dict = copy.copy(dict_none)
|
||||
for key, value in copy_dict.items():
|
||||
data = self._analysis_dict_to_body_value(copy_dict[key], dict_data[key])
|
||||
if not data:
|
||||
copy_dict[key] = None
|
||||
elif i >= len(data):
|
||||
copy_dict[key] = data[0]
|
||||
if isinstance(value, list):
|
||||
copy_dict[key] = [data[0]]
|
||||
else:
|
||||
copy_dict[key] = data[i]
|
||||
if isinstance(value, list):
|
||||
copy_dict[key] = [data[i]]
|
||||
|
||||
data_list.append(copy_dict)
|
||||
|
||||
else:
|
||||
data_list = dict_data
|
||||
|
||||
return data_list
|
||||
|
||||
def _get_nums(self, dict_data):
|
||||
"""
|
||||
获取所有参数对应值的最大长度
|
||||
"""
|
||||
nums_list = [0]
|
||||
if isinstance(dict_data, list):
|
||||
for item in dict_data:
|
||||
if isinstance(item, dict):
|
||||
data = self._get_nums(dict_data[0])
|
||||
nums_list.append(data)
|
||||
else:
|
||||
nums_list.append(len(dict_data))
|
||||
|
||||
elif isinstance(dict_data, dict):
|
||||
for value in dict_data.values():
|
||||
data = self._get_nums(value)
|
||||
nums_list.append(data)
|
||||
elif dict_data == None:
|
||||
nums_list.append(0)
|
||||
else:
|
||||
nums_list.append(len(dict_data))
|
||||
return max(nums_list)
|
||||
|
||||
def _analysis_case_parameters_to_value(self, interface_demo, parameters):
|
||||
"""
|
||||
根据demo将每个参数的对应值的列表写回demo
|
||||
"""
|
||||
body = copy.copy(interface_demo)
|
||||
if isinstance(body, list):
|
||||
for index in range(len(body)):
|
||||
item = body[index]
|
||||
body[index] = self._analysis_case_parameters_to_value(item, parameters)
|
||||
|
||||
elif isinstance(body, dict):
|
||||
for key, value in body.items():
|
||||
if isinstance(value, dict) or isinstance(value, list):
|
||||
if value:
|
||||
body[key] = self._analysis_case_parameters_to_value(body.get(key), parameters)
|
||||
else:
|
||||
body[key] = parameters.get(key)
|
||||
else:
|
||||
body[key] = parameters.get(key)
|
||||
return body
|
||||
|
||||
def _analysis_case_parameters_to_dict(self, parameters):
|
||||
"""
|
||||
根据所有参数生成正常值 和异常值的列表
|
||||
"""
|
||||
expect_lenth = 0
|
||||
un_expect_lenth = 0
|
||||
parameter_expect_dict = dict()
|
||||
parameter_un_expect_dict = dict()
|
||||
for parameter in parameters:
|
||||
parameter_attr = SetAttr(parameter)
|
||||
if parameter_attr.normal_values:
|
||||
if parameter_attr.normal_values.startswith("["):
|
||||
parameter_expect_dict[parameter_attr.name] = parameter_attr.normal_values.split(",")
|
||||
else:
|
||||
if parameter_attr.type == "array":
|
||||
parameter_expect_dict[parameter_attr.name] = [[x] for x in parameter_attr.normal_values.split(",")]
|
||||
else:
|
||||
parameter_expect_dict[parameter_attr.name] = parameter_attr.normal_values.split(",")
|
||||
else:
|
||||
continue
|
||||
if len(parameter_expect_dict[parameter_attr.name]) > expect_lenth:
|
||||
expect_lenth = len(parameter_expect_dict[parameter_attr.name])
|
||||
|
||||
if parameter_attr.exception_values:
|
||||
parameter_un_expect_dict[parameter_attr.name] = parameter_attr.exception_values.split(",")
|
||||
else:
|
||||
# raise Exception("接口参数%s无异常值,请先确认接口参数。" % parameter_attr.name)
|
||||
parameter_un_expect_dict[parameter_attr.name] = []
|
||||
|
||||
if len(parameter_un_expect_dict[parameter_attr.name]) > un_expect_lenth:
|
||||
un_expect_lenth = len(parameter_un_expect_dict[parameter_attr.name])
|
||||
|
||||
return parameter_expect_dict, parameter_un_expect_dict, expect_lenth, un_expect_lenth
|
||||
|
||||
def generate_case_doc(self, interface_info, tags=None, demo=None):
|
||||
if demo:
|
||||
lenth, demo_json, paras_d = self.file.kw._clean_demo_to_less_key(demo)
|
||||
doc_list = list()
|
||||
doc_list.append(
|
||||
" [Documentation] {} 接口路径:{}, {}".format(interface_info.interface_describe,
|
||||
interface_info.type, interface_info.in_url))
|
||||
# doc_list.append(self.doc_content_row_temp.format("输入参数名", "参数类型", "说明"))
|
||||
# for parameters_info in parameters:
|
||||
# sub_doc = self._generate_case_doc(parameters_info)
|
||||
# doc_list.append(sub_doc)
|
||||
if tags:
|
||||
tag_list = tags.split(",")
|
||||
tag = " [Tags]"
|
||||
for tag_ in tag_list:
|
||||
tag += " %s" % tag_
|
||||
doc_list.append(tag)
|
||||
if lenth > 1:
|
||||
doc_list.append(
|
||||
" # 请求参数说明 h:放header里的参数 u:放url路径节点中的参数 d:不放在url中在请求参数 p:放在url问号后在key-value结构参数")
|
||||
return "\n".join(doc_list)
|
||||
|
||||
def _generate_case_doc(self, request_parameter):
|
||||
doc_content = list()
|
||||
parameter_attr = SetAttr(request_parameter)
|
||||
row = self.doc_content_row_temp.format(parameter_attr.name, parameter_attr.type, parameter_attr.note)
|
||||
doc_content.append(row)
|
||||
return "\n".join(doc_content)
|
||||
|
||||
def generate_case_file_path(self, interface_info):
|
||||
path_cell_list = self._generate_case_file_path_info(interface_info.in_url)
|
||||
path_cell_list.insert(0, self.file.case_dir)
|
||||
return os.path.abspath(os.path.join(*path_cell_list[:-1]) + ".robot"), path_cell_list[-1]
|
||||
|
||||
def _generate_case_file_path_info(self, url):
|
||||
head_list = []
|
||||
para_list = []
|
||||
host, url_last = re.search(r"(\S+\.cn|\S+\.com)(\S+)", url).groups()
|
||||
path_first = re.search("//([\w+\-]+)\.", host).group(1)
|
||||
head_list.append(path_first)
|
||||
search = re.findall("[\w+\-_]+|[\{\w+\-_\}]+", url_last)
|
||||
for item in search:
|
||||
if "{" in item:
|
||||
temp = item.replace("{", "").replace("}", "")
|
||||
para_list.append(temp)
|
||||
else:
|
||||
head_list.append(item)
|
||||
return head_list
|
||||
|
||||
|
||||
def run_interface_case_generate(result_path, interface, demo_info, parameters, case_instance, tags=None, normal=None):
|
||||
case_type_list = ["1001", "1101", "1102", "1201"]
|
||||
not_exist_case_type = list()
|
||||
exist_case_name = list()
|
||||
case_path, _ = case_instance.generate_case_file_path(interface)
|
||||
case_name_head = interface.name
|
||||
if parameters:
|
||||
for case_type in case_type_list:
|
||||
case_name = "-".join([case_name_head, case_type])
|
||||
if not case_instance.file.check_case_exist(case_path, case_name):
|
||||
not_exist_case_type.append(case_type)
|
||||
else:
|
||||
exist_case_name.append(case_name)
|
||||
else:
|
||||
case_name = "-".join([case_name_head, "1001"])
|
||||
if not case_instance.file.check_case_exist(case_path, case_name):
|
||||
not_exist_case_type.append("1001")
|
||||
else:
|
||||
exist_case_name.append(case_name)
|
||||
for item in exist_case_name:
|
||||
msg = "接口url:%s,%s,已存在用例%s,请确认!" % (interface.type, interface.in_url, item)
|
||||
log.warning(msg)
|
||||
case_instance.file.write_content_to_case_file(result_path, msg + "\n")
|
||||
if not_exist_case_type:
|
||||
if normal:
|
||||
not_exist_case_type = ["1001"]
|
||||
case_instance.file.generate_case_file(case_path)
|
||||
try:
|
||||
demo = json.loads(demo_info.request_demo)
|
||||
except Exception as err:
|
||||
log.error(traceback.print_exc())
|
||||
log.warning("the demo of interface(%s) is empty,please check." % interface.id)
|
||||
demo = dict()
|
||||
try:
|
||||
result = list()
|
||||
result.append("")
|
||||
result.append("-" * 60)
|
||||
result.append("用例生成成功!")
|
||||
for case_type in not_exist_case_type:
|
||||
body = case_instance.create_case_content(result_path, interface, parameters, demo, case_type, tags=tags)
|
||||
# result.append(body)
|
||||
result.append(body.split("!")[1])
|
||||
log.info("\n".join(result))
|
||||
except:
|
||||
log.error("could not generate case for interface id: %s, url: %s" % (interface.id, interface.in_url))
|
||||
log.error(traceback.print_exc())
|
||||
else:
|
||||
msg = "接口url:%s,%s,已存在用例,请确认!" % (interface.type, interface.in_url)
|
||||
log.warning(msg)
|
||||
case_instance.file.write_content_to_case_file(result_path, msg + "\n")
|
||||
833
base_framework/platform_tools/Testcase_service/case_service1.py
Normal file
833
base_framework/platform_tools/Testcase_service/case_service1.py
Normal file
@@ -0,0 +1,833 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
import copy
|
||||
import importlib
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import sys
|
||||
import string
|
||||
import time
|
||||
import traceback
|
||||
|
||||
|
||||
def get_project_root_path(path="base_framework"):
|
||||
"""
|
||||
获取项目目录
|
||||
"""
|
||||
o_path = os.getcwd()
|
||||
try:
|
||||
project_path = re.search(r"(.*%s)" % path, o_path).group(1)
|
||||
return os.path.abspath(os.path.join(project_path, os.path.pardir))
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
Project_Path = get_project_root_path()
|
||||
sys.path.append(Project_Path)
|
||||
|
||||
from base_framework.platform_tools.Keywords_service.keyword_service1 import SetAttr, log
|
||||
|
||||
|
||||
def load_module_from_file(file_path, team):
|
||||
module_file = re.search(r"(%s\\.*)\.py" % team, file_path)
|
||||
if not module_file:
|
||||
module_file = re.search(r"(%s.*)\.py" % team.lower(), file_path)
|
||||
temp = module_file.group(1)
|
||||
temp = temp.replace(os.sep, ".")
|
||||
# try:
|
||||
# module = importlib.import_module(temp)
|
||||
# except Exception as err:
|
||||
# temp = re.sub(r"%s\." % team, "%s." % team.lower(), temp)
|
||||
# module = importlib.import_module(temp)
|
||||
return importlib.import_module(temp)
|
||||
|
||||
|
||||
class ITCaseFileOperation(object):
|
||||
def __init__(self, team, kw_instance):
|
||||
self.kw = kw_instance
|
||||
self.all_url = kw_instance.all_url
|
||||
self.kw_class_name = kw_instance.kw_class
|
||||
self.case_dir = os.path.abspath(os.path.join(Project_Path, team, "test_case", "TestCase", "1.接口"))
|
||||
self.env_path = os.path.abspath(
|
||||
os.path.join(Project_Path, team, "test_case", "Resource", "AdapterKws", "env.robot"))
|
||||
|
||||
def _check_case_file_exist(self, file_path):
|
||||
if os.path.exists(file_path) and os.path.isfile(file_path):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def check_case_exist(self, case_path, case_name):
|
||||
if self._check_case_file_exist(case_path):
|
||||
with open(case_path, "r", encoding="utf-8") as f:
|
||||
for line in f.readlines():
|
||||
if line.startswith(case_name):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
def generate_case_file(self, file_path):
|
||||
if not self._check_case_file_exist(file_path):
|
||||
dirname = file_path[:-len(os.path.basename(file_path))]
|
||||
if not os.path.exists(dirname):
|
||||
os.makedirs(dirname)
|
||||
self.write_content_to_case_file(file_path, self.generate_env_releate_path(dirname))
|
||||
else:
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
if f.readlines():
|
||||
if "\n" != f.readlines()[-1]:
|
||||
self.write_content_to_case_file(file_path, "\n")
|
||||
|
||||
def generate_env_releate_path(self, file_path):
|
||||
return "*** Settings ***\nResource " + os.path.relpath(self.env_path,
|
||||
file_path).replace("\\",
|
||||
"/") + "\n\n*** Test Cases ***\n"
|
||||
|
||||
def _check_case_file_resource(self, file_path):
|
||||
"""
|
||||
确定case文件中是否有关键字
|
||||
"""
|
||||
with open(file_path, "a+", encoding="utf-8") as f:
|
||||
content_list = f.readlines()
|
||||
if "*** Keywords ***\n" not in content_list:
|
||||
return True
|
||||
else:
|
||||
kw_index = content_list.rindex("*** Keywords ***\n")
|
||||
for index in range(kw_index, len(content_list) + 1):
|
||||
if "*** Test Cases ***\n" == content_list[index]:
|
||||
status = True
|
||||
if "*** Keywords ***\n" == content_list[index]:
|
||||
status = False
|
||||
return status
|
||||
|
||||
def write_content_to_case_file(self, file_path, content):
|
||||
status = self._check_case_file_resource(file_path)
|
||||
with open(file_path, "a+", encoding="utf-8") as f:
|
||||
if status:
|
||||
f.write(content)
|
||||
else:
|
||||
content = "*** Test Cases ***\n" + content
|
||||
f.write(content)
|
||||
|
||||
|
||||
class ITCaseContentOperation(object):
|
||||
def __init__(self, team, kw_instance):
|
||||
self.team = team
|
||||
self.file = ITCaseFileOperation(team, kw_instance)
|
||||
self.doc_content_row_temp = " ... | {} | {} | {} |"
|
||||
self.normal_1001 = None
|
||||
self.un_expect_list = None
|
||||
self.case_string = None
|
||||
|
||||
def _generate_case_name(self, interface_name, case_type, case_des):
|
||||
return "-".join([interface_name, case_type, case_des])
|
||||
|
||||
def _check_interface_confirm(self, interface_info):
|
||||
if not interface_info.confirmed:
|
||||
raise Exception("接口%s未确认,请先确认接口参数。" % interface_info.name)
|
||||
|
||||
def generate_case_body_all_1001_array(self, request_demo, parameters):
|
||||
temp_list = list()
|
||||
demo_copy = copy.deepcopy(request_demo)
|
||||
for key, value in request_demo.items():
|
||||
if not value:
|
||||
demo_copy.pop(key)
|
||||
if len(demo_copy.keys()) == 1:
|
||||
demo_copy = demo_copy.pop(list(demo_copy.keys())[0])
|
||||
dict_para, self.un_expect_list, _, _ = self._analysis_case_parameters_to_dict(parameters)
|
||||
demo_add_values = self._analysis_case_parameters_to_value(demo_copy, dict_para)
|
||||
data_list = self._analysis_dict_to_body_value(demo_copy, demo_add_values)
|
||||
if isinstance(demo_copy, list):
|
||||
for item in data_list:
|
||||
temp_list.append([item])
|
||||
data_list = temp_list
|
||||
return data_list
|
||||
|
||||
def _generate_parameter_to_dict(self, parameters):
|
||||
dict_temp = dict()
|
||||
for parameter in parameters:
|
||||
parameter_attr = SetAttr(parameter)
|
||||
dict_temp[parameter_attr.name] = parameter_attr
|
||||
return dict_temp
|
||||
|
||||
def _analysis_case_parameters_to_value_empty_dict(self, request_demo, parameters, type=None):
|
||||
"""
|
||||
循环生成缺少某个参数的值,其它正确的参数组合列表
|
||||
"""
|
||||
parameter_expect_list = list()
|
||||
expect_lenth = 0
|
||||
un_expect_lenth = 0
|
||||
parameter_expect_dict = dict()
|
||||
parameter_un_expect_dict = dict()
|
||||
for key, parameter_attr in parameters.items():
|
||||
if parameter_attr.normal_values:
|
||||
parameter_expect_dict[parameter_attr.name] = parameter_attr.normal_values.split(",")
|
||||
else:
|
||||
parameter_expect_dict[parameter_attr.name] = [
|
||||
self._generate_body_expect_type_value(parameter_attr.type)]
|
||||
|
||||
if len(parameter_expect_dict[parameter_attr.name]) > expect_lenth:
|
||||
expect_lenth = len(parameter_expect_dict[parameter_attr.name])
|
||||
|
||||
if parameter_attr.exception_values:
|
||||
parameter_un_expect_dict[parameter_attr.name] = parameter_attr.exception_values.split(",")
|
||||
else:
|
||||
parameter_un_expect_dict[parameter_attr.name] = [
|
||||
self._generate_body_un_expect_type_value(parameter_attr.type)]
|
||||
|
||||
if len(parameter_un_expect_dict[parameter_attr.name]) > un_expect_lenth:
|
||||
un_expect_lenth = len(parameter_un_expect_dict[parameter_attr.name])
|
||||
|
||||
for key in parameter_expect_dict.keys():
|
||||
if key not in json.dumps(request_demo):
|
||||
continue
|
||||
value = copy.copy(parameter_expect_dict)
|
||||
value[key] = ['NULL']
|
||||
if parameters.get(key).is_need == 1:
|
||||
status = "FAIL"
|
||||
else:
|
||||
status = "PASS"
|
||||
if type == "1102":
|
||||
name = "缺少参数%s" % key
|
||||
else:
|
||||
name = "缺少参数%s的值" % key
|
||||
parameter_expect_list.append([value, status, name])
|
||||
return parameter_expect_list
|
||||
|
||||
def _distinguish_parameters_by_is_needed(self, parameters):
|
||||
"""
|
||||
将必填参数和非必须参数分开成2个列表
|
||||
"""
|
||||
need_parameters = list()
|
||||
no_need_parameters = list()
|
||||
for parameter in parameters:
|
||||
parameter_attr = SetAttr(parameter)
|
||||
if parameter_attr.is_need != 0:
|
||||
need_parameters.append(parameter_attr)
|
||||
else:
|
||||
no_need_parameters.append(parameter_attr)
|
||||
return need_parameters, no_need_parameters
|
||||
|
||||
def _replace_null_value_no_need_parameters(self, demo, no_need_parameter_attrs):
|
||||
"""
|
||||
将所有非必填参数置空
|
||||
"""
|
||||
really_body = copy.deepcopy(demo)
|
||||
for parameter_attr in no_need_parameter_attrs:
|
||||
if re.search(r"\"%s\"" % parameter_attr.name, demo):
|
||||
check_para = r"\"%s\":\s[\[\{]" % parameter_attr.name
|
||||
if re.search(check_para, demo):
|
||||
continue
|
||||
try:
|
||||
expect_value = parameter_attr.normal_values.split(",")[0]
|
||||
except Exception as err:
|
||||
log.error(err)
|
||||
raise Exception("接口参数%s无正常值,请先确认接口参数。" % parameter_attr.name)
|
||||
patten1 = r"\"%s\":\s\"%s\"" % (parameter_attr.name, expect_value)
|
||||
replace1 = "\"%s\": \"NULL\"" % parameter_attr.name
|
||||
really_body = re.sub(patten1, replace1, really_body)
|
||||
return really_body
|
||||
|
||||
def generate_case_body_all_1101_array(self, request_demo, parameters):
|
||||
"""
|
||||
生成1101用例对应的所有请求参数组合
|
||||
"""
|
||||
body_array = list()
|
||||
need, no_need = self._distinguish_parameters_by_is_needed(parameters)
|
||||
demo_json = json.dumps(request_demo, ensure_ascii=False)
|
||||
if no_need:
|
||||
no_need_demo_json = self._replace_null_value_no_need_parameters(demo_json, no_need)
|
||||
body_array.append([json.loads(no_need_demo_json), "PASS", "所有非必填参数为空"])
|
||||
for item in need:
|
||||
parameter_attr = copy.copy(item)
|
||||
demo_json_copy = copy.copy(demo_json)
|
||||
if re.search("\"%s\"" % parameter_attr.name, demo_json_copy):
|
||||
check_para = r"\"%s\":\s\{|\"%s\":\s\[\{" % (parameter_attr.name, parameter_attr.name)
|
||||
if re.search(check_para, demo_json_copy):
|
||||
continue
|
||||
name = "缺少参数%s" % parameter_attr.name
|
||||
try:
|
||||
expect_value = parameter_attr.normal_values.split(",")[0]
|
||||
except Exception as err:
|
||||
log.error(err)
|
||||
raise Exception("接口参数%s无正常值,请先确认接口参数。" % parameter_attr.name)
|
||||
if parameter_attr.type == "array":
|
||||
patten1 = r"\"%s\":\s\[\"%s\"\]" % (parameter_attr.name, expect_value)
|
||||
replace1 = "\"%s\": []" % parameter_attr.name
|
||||
else:
|
||||
patten1 = r"\"%s\":\s\"%s\"" % (parameter_attr.name, expect_value)
|
||||
patten1 = patten1.replace("{", r"\{")
|
||||
patten1 = patten1.replace("}", r"\}")
|
||||
patten1 = patten1.replace("[", r"\[")
|
||||
patten1 = patten1.replace("]", r"\]")
|
||||
patten1 = patten1.replace("$", r"\$")
|
||||
replace1 = "\"%s\": \"NULL\"" % parameter_attr.name
|
||||
really_body = re.sub(patten1, replace1, demo_json_copy)
|
||||
if parameter_attr.is_need == 1:
|
||||
status = "FAIL"
|
||||
else:
|
||||
status = "PASS"
|
||||
body_array.append([json.loads(really_body), status, name])
|
||||
return body_array
|
||||
|
||||
def _clean_all_none_json_char(self, really_body):
|
||||
"""
|
||||
清除1102场景删除缺少参数后不规则的字符串内容
|
||||
"""
|
||||
really_body = re.sub(",\s,", ",", really_body)
|
||||
really_body = re.sub("\[\s?,", "[", really_body)
|
||||
really_body = re.sub("\{\s?,", "{", really_body)
|
||||
really_body = re.sub(",\s\]", "]", really_body)
|
||||
really_body = re.sub(",\s\}", "}", really_body)
|
||||
really_body = re.sub("\s,", "", really_body)
|
||||
return really_body
|
||||
|
||||
def _replace_null_all_no_need_parameters(self, demo, no_need_parameter_attrs):
|
||||
"""
|
||||
将所有非必填参数置空
|
||||
"""
|
||||
really_body = copy.deepcopy(demo)
|
||||
for parameter_attr in no_need_parameter_attrs:
|
||||
if re.search(r"\"%s\"" % parameter_attr.name, demo):
|
||||
check_para = r"\"%s\":\s\{|\"%s\":\s\[\{" % (parameter_attr.name, parameter_attr.name)
|
||||
if re.search(check_para, demo):
|
||||
continue
|
||||
try:
|
||||
expect_value = parameter_attr.normal_values.split(",")[0]
|
||||
except Exception as err:
|
||||
log.error(err)
|
||||
raise Exception("接口参数%s无正常值,请先确认接口参数。" % parameter_attr.name)
|
||||
if parameter_attr.type == "array":
|
||||
patten1 = r"\"%s\":\s\[\"%s\"\]" % (parameter_attr.name, expect_value)
|
||||
else:
|
||||
patten1 = r"\"%s\":\s\"%s\"" % (parameter_attr.name, expect_value)
|
||||
replace1 = ""
|
||||
really_body = re.sub(patten1, replace1, really_body)
|
||||
really_body = self._clean_all_none_json_char(really_body)
|
||||
return really_body
|
||||
|
||||
def generate_case_body_all_1102_array(self, request_demo, parameters):
|
||||
"""
|
||||
生成1102用例对应的所有参数组合
|
||||
"""
|
||||
body_array = list()
|
||||
need, no_need = self._distinguish_parameters_by_is_needed(parameters)
|
||||
demo_json = json.dumps(request_demo, ensure_ascii=False)
|
||||
if no_need:
|
||||
no_need_demo_json = self._replace_null_all_no_need_parameters(demo_json, no_need)
|
||||
body_array.append([json.loads(no_need_demo_json), "PASS", "所有非必填参数均缺失"])
|
||||
for item in need:
|
||||
parameter_attr = copy.copy(item)
|
||||
demo_json_copy = copy.copy(demo_json)
|
||||
if re.search(r"\"%s\"" % parameter_attr.name, demo_json_copy):
|
||||
check_para = r"\"%s\":\s\{|\"%s\":\s\[\{" % (parameter_attr.name, parameter_attr.name)
|
||||
if re.search(check_para, demo_json_copy):
|
||||
continue
|
||||
name = "缺少参数%s" % parameter_attr.name
|
||||
expect_value = parameter_attr.normal_values.split(",")[0]
|
||||
if parameter_attr.type == "array":
|
||||
patten1 = r"\"%s\":\s\[\"%s\"\]" % (parameter_attr.name, expect_value)
|
||||
else:
|
||||
patten1 = r"\"%s\":\s\"%s\"" % (parameter_attr.name, expect_value)
|
||||
patten1 = patten1.replace("{", r"\{")
|
||||
patten1 = patten1.replace("}", r"\}")
|
||||
patten1 = patten1.replace("[", r"\[")
|
||||
patten1 = patten1.replace("]", r"\]")
|
||||
patten1 = patten1.replace("$", r"\$")
|
||||
replace1 = ""
|
||||
really_body = re.sub(patten1, replace1, demo_json_copy)
|
||||
really_body = self._clean_all_none_json_char(really_body)
|
||||
if parameter_attr.is_need == 1:
|
||||
status = "FAIL"
|
||||
else:
|
||||
status = "PASS"
|
||||
body_array.append([json.loads(really_body), status, name])
|
||||
return body_array
|
||||
|
||||
def generate_case_body_all_1201_array(self, request_demo, parameters):
|
||||
"""
|
||||
生成1201用例对应的所有参数组合
|
||||
"""
|
||||
body_array = list()
|
||||
demo_json = json.dumps(request_demo, ensure_ascii=False)
|
||||
for item in parameters:
|
||||
parameter_attr = SetAttr(item)
|
||||
if re.search(r"\"%s\"" % parameter_attr.name, demo_json):
|
||||
check_para = r"\"%s\":\s\{|\"%s\":\s\[\{" % (parameter_attr.name, parameter_attr.name)
|
||||
if re.search(check_para, demo_json):
|
||||
continue
|
||||
for un_expect_item in self.un_expect_list.get(parameter_attr.name):
|
||||
name = "参数%s使用异常值%s" % (parameter_attr.name, un_expect_item)
|
||||
demo_json_copy = copy.copy(demo_json)
|
||||
expect_value = parameter_attr.normal_values.split(",")[0]
|
||||
if parameter_attr.type == "array":
|
||||
patten1 = r"\"%s\":\s\[\"%s\"\]" % (parameter_attr.name, expect_value)
|
||||
replace1 = '"%s": ["%s"]' % (parameter_attr.name, un_expect_item)
|
||||
else:
|
||||
patten1 = r"\"%s\":\s\"%s\"" % (parameter_attr.name, expect_value)
|
||||
patten1 = patten1.replace("{", r"\{")
|
||||
patten1 = patten1.replace("}", r"\}")
|
||||
patten1 = patten1.replace("[", r"\[")
|
||||
patten1 = patten1.replace("]", r"\]")
|
||||
patten1 = patten1.replace("$", r"\$")
|
||||
replace1 = '"%s": "%s"' % (parameter_attr.name, un_expect_item)
|
||||
really_body = re.sub(patten1, replace1, demo_json_copy)
|
||||
status = "FAIL"
|
||||
|
||||
body_array.append([json.loads(really_body), status, name])
|
||||
return body_array
|
||||
|
||||
def create_case_content(self, result_path, interface_info, parameters, demo, case_type, tags=None):
|
||||
"""
|
||||
生成用例的所有内容
|
||||
"""
|
||||
self._check_interface_confirm(interface_info)
|
||||
body_content = list()
|
||||
doc = self.generate_case_doc(interface_info, tags=tags, demo=demo)
|
||||
case_file, _ = self.generate_case_file_path(interface_info)
|
||||
interface_name = interface_info.name
|
||||
if not parameters:
|
||||
body = self.generate_case_body_content(interface_info.in_url, doc, interface_name, case_type,
|
||||
interface_info.interface_describe, None, status="PASS")
|
||||
|
||||
else:
|
||||
try:
|
||||
body_array = self.generate_case_body_all_1001_array(demo, parameters)
|
||||
self.normal_1001 = body_array[0]
|
||||
except TypeError:
|
||||
log.warning(traceback.print_exc())
|
||||
body_array = []
|
||||
self.normal_1001 = {}
|
||||
if case_type == "1001":
|
||||
try:
|
||||
body = self.generate_case_body_content(interface_info.in_url, doc, interface_name, case_type,
|
||||
interface_info.interface_describe, body_array, status="PASS")
|
||||
except Exception as err:
|
||||
msg = "生成用例%s,%s失败原因如下:%s" % (interface_info.type, interface_info.in_url, traceback.print_exc())
|
||||
log.error(msg)
|
||||
self.file.write_content_to_case_file(result_path, msg + "\n")
|
||||
|
||||
elif case_type == "1101" or case_type == "1102" or case_type == "1201":
|
||||
body_temp_list = []
|
||||
# parameters_temp = self._generate_parameter_to_dict(parameters)
|
||||
try:
|
||||
body_array = eval(
|
||||
"self.generate_case_body_all_%s_array(self.normal_1001, parameters)" % case_type)
|
||||
if case_type == "1101":
|
||||
name = "缺少参数值"
|
||||
elif case_type == "1102":
|
||||
name = "缺少参数key和值"
|
||||
elif case_type == "1201":
|
||||
name = "参数使用异常值"
|
||||
else:
|
||||
name = ""
|
||||
body_tmp = self.generate_case_body_content(interface_info.in_url, doc, interface_name,
|
||||
case_type,
|
||||
name, body_array, status="PASS")
|
||||
body_temp_list.append(body_tmp)
|
||||
body = "".join(body_temp_list)
|
||||
except Exception as err:
|
||||
msg = "生成用例%s,%s失败原因如下:%s" % (interface_info.type, interface_info.in_url, traceback.print_exc())
|
||||
log.error(msg)
|
||||
self.file.write_content_to_case_file(result_path, msg + "\n")
|
||||
raise err
|
||||
body_content.append(body)
|
||||
self.file.write_content_to_case_file(case_file, "\n".join(body_content))
|
||||
msg = "接口url:%s,%s,生成case%s成功!路径为:%s" % (interface_info.type, interface_info.in_url, case_type, case_file)
|
||||
log.info(msg)
|
||||
self.file.write_content_to_case_file(result_path, msg + "\n")
|
||||
return msg
|
||||
|
||||
def generate_case_body_content(self, url, doc, interface_name, case_type, description, body_para, status="PASS"):
|
||||
body_content = list()
|
||||
case_name = self._generate_case_name(interface_name, case_type, description)
|
||||
body_content.append(case_name)
|
||||
body_content.append(doc)
|
||||
# 如何需要自动生成1001类型用例的请求body数据,请将304/305行放开,并把306~310注释
|
||||
request = self._generate_case_body_content(url, body_content=body_para, status=status)
|
||||
body_content.append(request)
|
||||
# if case_type != "1001":
|
||||
# request = self._generate_case_body_content(url, body_content=body_para, status=status)
|
||||
# body_content.append(request)
|
||||
# else:
|
||||
# body_content.append(" #请自行添加用例请求数据!\n")
|
||||
return "\n".join(body_content)
|
||||
|
||||
def _generate_case_body_content(self, url, body_content=None, status="PASS"):
|
||||
body_list = []
|
||||
if body_content is None:
|
||||
try:
|
||||
body_request = " ${resp} %s" % (self.file.all_url.get(url)[1])
|
||||
except Exception as err:
|
||||
log.error(traceback.print_exc())
|
||||
body_request = " #url: %s 无法找到对应的关键字,请检查并更新!" % url
|
||||
body_list.append(body_request)
|
||||
body_list.append(" Log ${resp}")
|
||||
if self.team.upper() in ["TMO"]:
|
||||
body_validate_success = " check_rf ${resp} %s" % '请自行添加检查结果'
|
||||
else:
|
||||
body_validate_code = " Should Be Equal ${resp['code']} ${200}"
|
||||
body_validate_success = " Should Be True ${resp['success']}"
|
||||
body_list.append(body_validate_code)
|
||||
body_list.append(body_validate_success)
|
||||
else:
|
||||
if not body_content:
|
||||
body_create = " #request_demo无内容或者parameters在数据表中不全,请先检查再生成 \n ${body} Evaluate %s" % body_content
|
||||
body_list.append(body_create)
|
||||
count = 0
|
||||
for real_body in body_content:
|
||||
result = {"message": "", "code": 200, "success": True}
|
||||
temp = copy.copy(real_body)
|
||||
if len(real_body) == 3 and isinstance(real_body, list):
|
||||
if real_body[1] == "PASS" or real_body[1] == "FAIL":
|
||||
real_body = temp[0]
|
||||
status = temp[1]
|
||||
case_description = temp[2]
|
||||
body_list.append(" #%s" % case_description)
|
||||
try:
|
||||
module = load_module_from_file(self.file.kw.kw_file_path, self.team)
|
||||
importlib.reload(module)
|
||||
if isinstance(real_body, list):
|
||||
temp_type = "*"
|
||||
else:
|
||||
temp_type = "**"
|
||||
result = eval(
|
||||
"%s.%s().%s(%sreal_body)" % (
|
||||
"module", self.file.kw_class_name, self.file.all_url.get(url)[1], temp_type))
|
||||
except:
|
||||
msg = "#url: %s 无法通过参数得到请求结果!" % url
|
||||
log.warning(real_body)
|
||||
log.warning(msg)
|
||||
log.warning(traceback.print_exc())
|
||||
if "${time}" in str(real_body):
|
||||
body_list.append(" ${time} get time epoch")
|
||||
body_create = " ${body_%s} Evaluate %s" % (count, real_body)
|
||||
try:
|
||||
if isinstance(real_body, list):
|
||||
body_request = " ${resp_%s} %s %s" % (
|
||||
count, self.file.all_url.get(url)[1], "@{body_%s}" % count)
|
||||
elif isinstance(real_body, dict):
|
||||
body_request = " ${resp_%s} %s %s" % (
|
||||
count, self.file.all_url.get(url)[1], "&{body_%s}" % count)
|
||||
except Exception as err:
|
||||
log.error(traceback.print_exc())
|
||||
body_request = " #url: %s 无法找到对应的关键字,请检查并更新!" % url
|
||||
body_list.append(body_create)
|
||||
body_list.append(body_request)
|
||||
body_list.append(" Log ${resp_%s}" % count)
|
||||
if self.team.upper() in ["TMO"]:
|
||||
body_validate_resp = " check_rf ${resp_%s} %s" % (count, result)
|
||||
else:
|
||||
body_validate_code = " Should Be Equal as strings ${resp_%s['code']} ${%s}"
|
||||
# body_validate_success = " %s ${resp_%s['success']}"
|
||||
body_validate_success = " %s ${resp_%s['success']} %s"
|
||||
body_validate_resp = " %s ${resp_%s[\"message\"]} %s"
|
||||
if isinstance(result, str):
|
||||
body_validate_code = " #特殊接口返回!"
|
||||
body_validate_success = " #返回为bytes类型的字符码。仅检查结果是否相等!"
|
||||
body_validate_resp = " Should Be Equal as strings ${resp_%s} %s" % (count, result)
|
||||
|
||||
elif status == "PASS":
|
||||
body_validate_code = body_validate_code % (count, result['code'])
|
||||
body_validate_success = body_validate_success % ("Should Be True", count, "")
|
||||
try:
|
||||
if result["message"]:
|
||||
body_validate_resp = body_validate_resp % (
|
||||
"Should Be Equal as strings", count, result["message"])
|
||||
else:
|
||||
body_validate_resp = body_validate_resp % (
|
||||
"Should Be Equal as strings", count, '${EMPTY}')
|
||||
except KeyError as err:
|
||||
body_validate_resp = " #resp中没有message,请后续自行添加!"
|
||||
log.warning(err)
|
||||
log.warning("resp中没有message,请后续自行添加!")
|
||||
else:
|
||||
try:
|
||||
body_validate_code = body_validate_code % (count, result['code'])
|
||||
except Exception as e:
|
||||
if "status" in result:
|
||||
body_validate_code = body_validate_code % (count, result['status'])
|
||||
body_validate_code = body_validate_code.replace("code", "status")
|
||||
else:
|
||||
raise KeyError("接口不中无code返回,请与开发确认!!!")
|
||||
try:
|
||||
body_validate_success = body_validate_success % (
|
||||
"Should Be Equal As Strings", count, result["success"])
|
||||
except Exception as err:
|
||||
if "error" in result:
|
||||
body_validate_success = body_validate_success % (
|
||||
"Should Be Equal As Strings", count, result["error"])
|
||||
body_validate_success = body_validate_success.replace("success", "error")
|
||||
else:
|
||||
raise KeyError("接口不中无success返回,请与开发确认!!!")
|
||||
try:
|
||||
if result.get("message"):
|
||||
if re.search("[a-zA-Z0-9]{32}", result.get("message", "")):
|
||||
body_validate_resp = body_validate_resp % ("should contain", count,
|
||||
re.sub("[a-zA-Z0-9]{32}", "", result["message"]))
|
||||
else:
|
||||
body_validate_resp = body_validate_resp % (
|
||||
"should be equal as strings", count, result["message"])
|
||||
else:
|
||||
body_validate_resp = body_validate_resp % (
|
||||
"Should Be Equal as strings", count, '${EMPTY}')
|
||||
except KeyError as err:
|
||||
body_validate_resp = " #resp中没有message,请后续自行添加!"
|
||||
log.warning(err)
|
||||
log.warning("resp中没有message,请后续自行添加!")
|
||||
|
||||
body_list.append(body_validate_code)
|
||||
body_list.append(body_validate_success)
|
||||
body_list.append(body_validate_resp)
|
||||
# body_list.append(" #请自行添加data校验!")
|
||||
count += 1
|
||||
body_list.append("\n")
|
||||
return "\n".join(body_list)
|
||||
|
||||
def _generate_body_expect_type_value(self, type):
|
||||
if type.lower() == 'integer':
|
||||
value = random.randint(0, 100)
|
||||
elif type.lower() == "string":
|
||||
value = "".join([random.choice(string.digits + string.ascii_letters) for i in range(5)])
|
||||
elif type.lower() == "date":
|
||||
value = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
||||
elif type.lower() == "boolean":
|
||||
value = True
|
||||
elif type.lower() == "array":
|
||||
value = [1]
|
||||
else:
|
||||
value = "123"
|
||||
return value
|
||||
|
||||
def _generate_body_un_expect_type_value(self, type):
|
||||
value = ""
|
||||
if type.lower() == 'integer':
|
||||
value = "".join([random.choice(string.digits + string.ascii_letters) for i in range(5)])
|
||||
elif type.lower() == "string":
|
||||
value = random.randint(0, 10000)
|
||||
else:
|
||||
value = False
|
||||
return value
|
||||
|
||||
def _analysis_dict_to_body_value(self, dict_none, dict_data):
|
||||
"""
|
||||
生成所有请求参数的组合列表
|
||||
"""
|
||||
data_list = []
|
||||
if isinstance(dict_none, list):
|
||||
if dict_none:
|
||||
for index in range(len(dict_none)):
|
||||
data = self._analysis_dict_to_body_value(dict_none[index], dict_data[index])
|
||||
data_list.extend(data)
|
||||
else:
|
||||
data_list = dict_data
|
||||
elif isinstance(dict_none, dict):
|
||||
try:
|
||||
len_num = self._get_nums(dict_data)
|
||||
except Exception as e:
|
||||
# log.error(e)
|
||||
log.error("数据表request_parameters中参数不全,请使用interface_hunter补全参数")
|
||||
raise e
|
||||
for i in range(0, len_num):
|
||||
copy_dict = copy.copy(dict_none)
|
||||
for key, value in copy_dict.items():
|
||||
data = self._analysis_dict_to_body_value(copy_dict[key], dict_data[key])
|
||||
if not data:
|
||||
copy_dict[key] = None
|
||||
elif i >= len(data):
|
||||
copy_dict[key] = data[0]
|
||||
if isinstance(value, list):
|
||||
copy_dict[key] = [data[0]]
|
||||
else:
|
||||
copy_dict[key] = data[i]
|
||||
if isinstance(value, list):
|
||||
copy_dict[key] = [data[i]]
|
||||
|
||||
data_list.append(copy_dict)
|
||||
|
||||
else:
|
||||
data_list = dict_data
|
||||
|
||||
return data_list
|
||||
|
||||
def _get_nums(self, dict_data):
|
||||
"""
|
||||
获取所有参数对应值的最大长度
|
||||
"""
|
||||
nums_list = [0]
|
||||
if isinstance(dict_data, list):
|
||||
for item in dict_data:
|
||||
if isinstance(item, dict):
|
||||
data = self._get_nums(dict_data[0])
|
||||
nums_list.append(data)
|
||||
else:
|
||||
nums_list.append(len(dict_data))
|
||||
|
||||
elif isinstance(dict_data, dict):
|
||||
for value in dict_data.values():
|
||||
data = self._get_nums(value)
|
||||
nums_list.append(data)
|
||||
elif dict_data == None:
|
||||
nums_list.append(0)
|
||||
else:
|
||||
nums_list.append(len(dict_data))
|
||||
return max(nums_list)
|
||||
|
||||
def _analysis_case_parameters_to_value(self, interface_demo, parameters):
|
||||
"""
|
||||
根据demo将每个参数的对应值的列表写回demo
|
||||
"""
|
||||
body = copy.copy(interface_demo)
|
||||
if isinstance(body, list):
|
||||
for index in range(len(body)):
|
||||
item = body[index]
|
||||
body[index] = self._analysis_case_parameters_to_value(item, parameters)
|
||||
|
||||
elif isinstance(body, dict):
|
||||
for key, value in body.items():
|
||||
if isinstance(value, dict) or isinstance(value, list):
|
||||
if value:
|
||||
body[key] = self._analysis_case_parameters_to_value(body.get(key), parameters)
|
||||
else:
|
||||
body[key] = parameters.get(key)
|
||||
else:
|
||||
body[key] = parameters.get(key)
|
||||
return body
|
||||
|
||||
def _analysis_case_parameters_to_dict(self, parameters):
|
||||
"""
|
||||
根据所有参数生成正常值 和异常值的列表
|
||||
"""
|
||||
expect_lenth = 0
|
||||
un_expect_lenth = 0
|
||||
parameter_expect_dict = dict()
|
||||
parameter_un_expect_dict = dict()
|
||||
for parameter in parameters:
|
||||
parameter_attr = SetAttr(parameter)
|
||||
if parameter_attr.normal_values:
|
||||
if parameter_attr.normal_values.startswith("["):
|
||||
parameter_expect_dict[parameter_attr.name] = parameter_attr.normal_values.split(",")
|
||||
else:
|
||||
if parameter_attr.type == "array":
|
||||
parameter_expect_dict[parameter_attr.name] = [[x] for x in parameter_attr.normal_values.split(",")]
|
||||
else:
|
||||
parameter_expect_dict[parameter_attr.name] = parameter_attr.normal_values.split(",")
|
||||
else:
|
||||
continue
|
||||
if len(parameter_expect_dict[parameter_attr.name]) > expect_lenth:
|
||||
expect_lenth = len(parameter_expect_dict[parameter_attr.name])
|
||||
|
||||
if parameter_attr.exception_values:
|
||||
parameter_un_expect_dict[parameter_attr.name] = parameter_attr.exception_values.split(",")
|
||||
else:
|
||||
# raise Exception("接口参数%s无异常值,请先确认接口参数。" % parameter_attr.name)
|
||||
parameter_un_expect_dict[parameter_attr.name] = []
|
||||
|
||||
if len(parameter_un_expect_dict[parameter_attr.name]) > un_expect_lenth:
|
||||
un_expect_lenth = len(parameter_un_expect_dict[parameter_attr.name])
|
||||
|
||||
return parameter_expect_dict, parameter_un_expect_dict, expect_lenth, un_expect_lenth
|
||||
|
||||
def generate_case_doc(self, interface_info, tags=None, demo=None):
|
||||
if demo:
|
||||
lenth, demo_json, paras_d = self.file.kw._clean_demo_to_less_key(demo)
|
||||
doc_list = list()
|
||||
doc_list.append(
|
||||
" [Documentation] {} 接口路径:{}, {}".format(interface_info.interface_describe,
|
||||
interface_info.type, interface_info.in_url))
|
||||
# doc_list.append(self.doc_content_row_temp.format("输入参数名", "参数类型", "说明"))
|
||||
# for parameters_info in parameters:
|
||||
# sub_doc = self._generate_case_doc(parameters_info)
|
||||
# doc_list.append(sub_doc)
|
||||
if tags:
|
||||
tag_list = tags.split(",")
|
||||
tag = " [Tags]"
|
||||
for tag_ in tag_list:
|
||||
tag += " %s" % tag_
|
||||
doc_list.append(tag)
|
||||
if lenth > 1:
|
||||
doc_list.append(
|
||||
" # 请求参数说明 h:放header里的参数 u:放url路径节点中的参数 d:不放在url中在请求参数 p:放在url问号后在key-value结构参数")
|
||||
return "\n".join(doc_list)
|
||||
|
||||
def _generate_case_doc(self, request_parameter):
|
||||
doc_content = list()
|
||||
parameter_attr = SetAttr(request_parameter)
|
||||
row = self.doc_content_row_temp.format(parameter_attr.name, parameter_attr.type, parameter_attr.note)
|
||||
doc_content.append(row)
|
||||
return "\n".join(doc_content)
|
||||
|
||||
def generate_case_file_path(self, interface_info):
|
||||
path_cell_list = self._generate_case_file_path_info(interface_info.in_url)
|
||||
path_cell_list.insert(0, self.file.case_dir)
|
||||
return os.path.abspath(os.path.join(*path_cell_list[:-1]) + ".robot"), path_cell_list[-1]
|
||||
|
||||
def _generate_case_file_path_info(self, url):
|
||||
head_list = []
|
||||
para_list = []
|
||||
host, url_last = re.search(r"(\S+\.cn|\S+\.com)(\S+)", url).groups()
|
||||
path_first = re.search("//([\w+\-]+)\.", host).group(1)
|
||||
head_list.append(path_first)
|
||||
search = re.findall("[\w+\-_]+|[\{\w+\-_\}]+", url_last)
|
||||
for item in search:
|
||||
if "{" in item:
|
||||
temp = item.replace("{", "").replace("}", "")
|
||||
para_list.append(temp)
|
||||
else:
|
||||
head_list.append(item)
|
||||
return head_list
|
||||
|
||||
|
||||
def run_interface_case_generate(result_path, interface, demo_info, parameters, case_instance, tags=None, normal=None):
|
||||
case_type_list = ["1001", "1101", "1102", "1201"]
|
||||
not_exist_case_type = list()
|
||||
exist_case_name = list()
|
||||
case_path, _ = case_instance.generate_case_file_path(interface)
|
||||
case_name_head = interface.name
|
||||
if parameters:
|
||||
for case_type in case_type_list:
|
||||
case_name = "-".join([case_name_head, case_type])
|
||||
if not case_instance.file.check_case_exist(case_path, case_name):
|
||||
not_exist_case_type.append(case_type)
|
||||
else:
|
||||
exist_case_name.append(case_name)
|
||||
else:
|
||||
case_name = "-".join([case_name_head, "1001"])
|
||||
if not case_instance.file.check_case_exist(case_path, case_name):
|
||||
not_exist_case_type.append("1001")
|
||||
else:
|
||||
exist_case_name.append(case_name)
|
||||
for item in exist_case_name:
|
||||
msg = "接口url:%s,%s,已存在用例%s,请确认!" % (interface.type, interface.in_url, item)
|
||||
log.warning(msg)
|
||||
case_instance.file.write_content_to_case_file(result_path, msg + "\n")
|
||||
if not_exist_case_type:
|
||||
if normal:
|
||||
not_exist_case_type = ["1001"]
|
||||
case_instance.file.generate_case_file(case_path)
|
||||
try:
|
||||
demo = json.loads(demo_info.request_demo)
|
||||
except Exception as err:
|
||||
log.error(traceback.print_exc())
|
||||
log.warning("the demo of interface(%s) is empty,please check." % interface.id)
|
||||
demo = dict()
|
||||
try:
|
||||
result = list()
|
||||
result.append("")
|
||||
result.append("-" * 60)
|
||||
result.append("用例生成成功!")
|
||||
for case_type in not_exist_case_type:
|
||||
body = case_instance.create_case_content(result_path, interface, parameters, demo, case_type, tags=tags)
|
||||
# result.append(body)
|
||||
result.append(body.split("!")[1])
|
||||
log.info("\n".join(result))
|
||||
except:
|
||||
log.error("could not generate case for interface id: %s, url: %s" % (interface.id, interface.in_url))
|
||||
log.error(traceback.print_exc())
|
||||
else:
|
||||
msg = "接口url:%s,%s,已存在用例,请确认!" % (interface.type, interface.in_url)
|
||||
log.warning(msg)
|
||||
case_instance.file.write_content_to_case_file(result_path, msg + "\n")
|
||||
3
base_framework/platform_tools/Testcase_service/readme
Normal file
3
base_framework/platform_tools/Testcase_service/readme
Normal file
@@ -0,0 +1,3 @@
|
||||
目录结构说明:
|
||||
使用者:王刚
|
||||
用途:存放自动生成RF层用例的脚本
|
||||
Reference in New Issue
Block a user