class CaseDetail: def __init__(self, filename=None, sheetid=0): try: if filename: self.filename = filename else: self.filename = "../data_file/TestCase_zh.xlsx" self.op_excel = OperationExcel(self.filename, 0) except Exception as e: log.error("获取中文用例表类初始化信息出现异常,异常原因:{}".format(e)) def get_case_detail(self, caseid, col): ''' 获取用例描述信息 :return: ''' try: row_num = self.op_excel.get_row_num_for_value(caseid) case_detail = self.op_excel.get_cell_value(row_num, col) return case_detail except Exception as e: log.error("获取中文用例表信息方法出现异常,异常原因:{}".format(e)) def is_pass(self, exp, res, re): pass
def setUp(self): self.interface_run = InterfaceRun() self.deal_res_data = DealResData() self.op_excel = OperationExcel(**option_dict) self.method_req = "post" self.crr = CmpReqRes(**option_dict) self.cp = CaseIsPass(**option_dict)
def __init__(self, filename=None, sheetid=0): try: if filename: self.filename = filename else: self.filename = "../data_file/TestCase_zh.xlsx" self.op_excel = OperationExcel(self.filename, 0) except Exception as e: log.error("获取中文用例表类初始化信息出现异常,异常原因:{}".format(e))
def __init__(self, excel_filename=None, json_filanme=None, excel_sheetid=0): self.excel_filename = excel_filename self.excel_sheetid = excel_sheetid self.json_filename = json_filanme self.ope_excel = OperationExcel(self.excel_filename, self.excel_sheetid) self.ope_json = OperationJson(self.json_filename)
def __init__(self, **kargs): try: self.kargs = kargs #实例化操作Excel表格类 self.op_excel = OperationExcel(**self.kargs) #获取参数名所在行返回参数名列表 self.param_name_list = self.op_excel.get_row_col_list_param_name( **self.kargs) #实例参数名处理类-根据上面的参数名列表 self.param = ParamGlobal(self.param_name_list) # 获取参数英文名列表 self.name_list = self.param.get_param_en_name_list() #获取参数值列表(仅获取从开始行到结束行的数所在,如果都为0表示所有记录) self.name_value_list = self.op_excel.get_row_col_list(**self.kargs) # 获取不在接口请求中传入的参数列表 self.param_no_req = self.param.get_param_no_request_list() # 获取文件类型参数列表 self.param_file = self.param.get_param_file_list() except Exception as e: log.error("接口参数处理类初始化异常,异常原因:{}".format(e))
def write_excel_value(self, dep_res): ''' 将依赖数据结果写回到excel表格指定的单元格中 :param dep_res: :return: ''' write_flag = False ope_excel = OperationExcel(**self.case_config) case_param_name_start = self.case_config.get("case_param_name_start", 0) #测试用例参数名开始行 case_row_value = ope_excel.get_sheet().row_values( case_param_name_start) row_num = self.case_rownum dep_res_dict = self.deal_req_res(dep_res) for update_param in dep_res_dict.keys(): for index, update_value in enumerate(case_row_value): if update_param in str(update_value).split("-")[1]: col_num = index ope_excel.writer_data(row_num, col_num, update_value) write_flag = True return write_flag
def __init__(self, case_dict, case_config): self.case_dict = case_dict # 获取的用例中的参数值,不是配置文件中的参数值 self.case_config = case_config # 获取执行接口用例配置文件内容,写回值时获取正确的sheetid self.ope_excel_case = OperationExcel(**self.case_dict) self.ope_excel_config = OperationExcel(**self.case_config) self.interface_run = InterfaceRun() self.case_rownum = int( self.ope_excel_config.get_row_num_for_value( self.case_dict.get("CaseID", 0), )) # 获取测试用例参数名所在行 self.param_name_rownum = int(self.case_dict.get("DepParamName", 0)) #获取依赖的参数名所在行 self.case_id = self.case_dict.get("DepCaseID", "") #获取依赖的测试用例ID self.case_value_rownum = self.ope_excel_case.get_row_num_for_value( self.case_id) #根据依赖caseid获取依赖测试用例执行行号 self.case_row_value = self.ope_excel_case.get_sheet().row_values( self.param_name_rownum) #根据参数名所在行号获取整行内容 self.hash_orders = self.case_dict.get("hash_orders", []) #获取依赖的测试用例ID的参数顺序列表,用于生成salt self.DepGetDataForm = self.case_dict.get("DepGetDataForm", "") #依赖提取数据格式 try: self.DepParamList = eval(case_dict.get("DepParamList", [])) except Exception as e: self.DepParamList = case_dict.get("DepParamList", [])
class GetData: def __init__(self, excel_filename=None, json_filanme=None, excel_sheetid=0): self.excel_filename = excel_filename self.excel_sheetid = excel_sheetid self.json_filename = json_filanme self.ope_excel = OperationExcel(self.excel_filename, self.excel_sheetid) self.ope_json = OperationJson(self.json_filename) #获取excel表格行数 def excel_rows(self): return self.ope_excel.get_sheet_rows() #获取是否运行 def is_run(self, row): col = get_is_run_col() is_run = self.ope_excel.get_cell_value(row, col) if str(is_run).strip().lower() == 'yes': run_flag = True else: run_flag = False return run_flag #获取headers def is_header(self, row): col = get_is_header_col() is_header = self.ope_excel.get_cell_value(row, col) if str(is_header).strip().lower() == 'yes': headers = get_header() else: headers = None return headers #获取请求路径 def get_url(self, row): col = get_url_col() return self.ope_excel.get_cell_value(row, col) #获取请求方法 def get_req_method(self, row): col = get_request_method_col() return self.ope_excel.get_cell_value(row, col) #获取请求数据 def get_req_data(self, row): col = get_request_data_col() req_data_key = self.ope_excel.get_cell_value(row, col) res = self.ope_json.get_data_for_key(req_data_key) if res == '': #防止在excel用例里面直接写入的请求数据 res = req_data_key return res # 获取case数据依赖 def get_case_dep(self, row): col = get_case_dep_col() res = self.ope_excel.get_cell_value(row, col) return res # 获取依赖的返回值规则 def get_dep_ret_data_re(self, row): col = get_dep_ret_value_re_col() return self.ope_excel.get_cell_value(row, col) # 获取依赖的返回值 def get_dep_ret_data(self, row): col = get_dep_ret_value_col() return self.ope_excel.get_cell_value(row, col) # 获取依赖字段 def get_data_dep_key(self, row): col = get_data_dep_col() return self.ope_excel.get_cell_value(row, col) # 获取预期结果 def get_expect_res(self, row): col = get_expect_col() return self.ope_excel.get_cell_value(row, col) # 往excel表中写入按规则获取的依赖返回数据 def writer_dep_res_data(self, row, data): col = get_dep_ret_value_col() return self.ope_excel.writer_data(row, col, data) # 往excel表中写入实际运行结果 def writer_real_data(self, row, data): col = get_real_result_col() return self.ope_excel.writer_data(row, col, data) # 往excel表中写入用例通过状态 def writer_status(self, row, data): col = get_status_col() return self.ope_excel.writer_data(row, col, data)
class CommonParamDict: def __init__(self, **kargs): try: self.kargs = kargs #实例化操作Excel表格类 self.op_excel = OperationExcel(**self.kargs) #获取参数名所在行返回参数名列表 self.param_name_list = self.op_excel.get_row_col_list_param_name( **self.kargs) #实例参数名处理类-根据上面的参数名列表 self.param = ParamGlobal(self.param_name_list) # 获取参数英文名列表 self.name_list = self.param.get_param_en_name_list() #获取参数值列表(仅获取从开始行到结束行的数所在,如果都为0表示所有记录) self.name_value_list = self.op_excel.get_row_col_list(**self.kargs) # 获取不在接口请求中传入的参数列表 self.param_no_req = self.param.get_param_no_request_list() # 获取文件类型参数列表 self.param_file = self.param.get_param_file_list() except Exception as e: log.error("接口参数处理类初始化异常,异常原因:{}".format(e)) def deal_param(self, **kwargs): ''' 处理后的参数数据即 参数值不填代表传参此参数不填 参数值为N代表参数不传 参数值为NN表示参数为空 :return: ''' if kwargs: self.kargs = kwargs #获取配置文件字段,如是方法中未传,直接使用初始化方法中传入的 no_param = self.param_no_req #获取不在请求里进行传入的参数列表 file_stream_list = self.kargs.get("file_stream_list", []) #获取配置文件里参数为文件类型需要转文件流的参数列表 param_file = self.param_file try: case_list = self.get_param_name_value() case_remove = [] if len(case_list) > 0: count = 0 for param_dict in case_list: if str(param_dict.get("IsRun")).lower() != "yes": case_remove.append(param_dict) continue salt_N = False for key in list(param_dict.keys()): try: key_value = param_dict.get(key) except Exception as e: key_value = param_dict.get(key) if not key_value and key not in no_param: del param_dict[key] if str(key_value).upper() == 'N' or str( key_value).upper() == 'NN': #参数值为N表示此参数不传 if key == "salt": salt_N = True param_dict.pop(key) elif str(key_value).upper() == 'NN': #参数值为NN表示此参数为空 param_dict[key] = "" elif ((key in param_file) or (key in file_stream_list)) and key_value != "": param_dict[key] = self.encry( key_value) # 根据获取的key_value进行上传前数据处理 if not param_dict.get("salt", None) and not salt_N: salt = self.get_salt(param_dict) param_dict["salt"] = salt count += 1 if len(case_remove) > 0: for case in case_remove: case_list.remove(case) return case_list except Exception as e: log.error("接口参数处理类处理后的参数数据方法异常,异常原因:{}".format(e)) return None def get_param_name(self): ''' 获取参数名列表 :return: ''' try: param_name_list = None param_name_list = [] for pname in self.name_value_list[0]: param_name = pname.split("-")[1] param_name_list.append(param_name) except Exception as e: log.error("接口参数处理参数名方法异常,异常原因:{}".format(e)) return param_name_list def get_param_name_value(self): ''' 获取参数名与参数值对应的字典列表 :return: 参数列表 ''' name_value_row_list = None try: name_value_row_list = [] for i in range(0, len(self.name_value_list)): name_value_row_list.append( dict(zip(self.name_list, self.name_value_list[i]))) except Exception as e: log.error("接口参数处理类处理参数名与参数值方法异常,异常原因:{}".format(e)) return name_value_row_list def encry(self, file_path): ''' 把文件转为文件流 :param file_path:文件全路径(路径+文件名) :return:b64encode编码后的文件流 ''' file_stream = "" try: with open(file_path, 'rb') as f: # 以二进制读取图片 data = f.read() encodestr = base64.b64encode(data) # 得到 byte 编码的数据 #print(str(encodestr,'utf-8')) # 重新编码数据 file_stream = str(encodestr, 'utf-8') except Exception as e: log.error("接口参数处理类将文件转为文件流方法异常,异常原因:{}".format(e)) return file_stream def decry(self, **kwargs): ''' 将文件流转为指定格式的文件 :return:True or False ,True表示存储成功,False表示失败 ''' is_download = False try: CaseID = kwargs.get("CaseID", "") #测试用例ID file_stream = kwargs.get("file_stream", "") #获取文件流 file_flag = kwargs.get("file_flag", "") #获取文件标识,用于显示在文件名最前面,如serialNo码 file_type = kwargs.get("file_type", "pdf") #获取文件后缀类型 如:jpg/pdf download_path = kwargs.get("download_path", "../download/") #获取下载文件存入路径 file_str = base64.b64decode(file_stream) #把文件流进行base64解码 data_str = datetime.datetime.now().strftime( '%Y%m%d%H%M%S') #将当前时间转为字符串 #rand_str = ''.join(random.sample((string.ascii_letters + string.digits),5)) #5位随机数(数字+字母) file_name = "{}_{}_{}.{}".format( CaseID, file_flag, data_str, file_type) #生成文件名:文件标识+当前时间字符串+文件后缀 if not os.path.exists(download_path): #判断文件存储路径是否存在 os.makedirs(download_path) #如果不存在就在创建对应路径 file_name = download_path + "/{}".format(file_name) #存储路径+文件全称 file = open(file_name, "wb") #以二进制读的方式打开文件 file.write(file_str) #写入文件流解码后的内容 file.close() #关闭文件 is_download = True except Exception as e: log.error("下载并存储文件出现异常,异常原类:{}".format(e)) return is_download def get_salt(self, case_dict=None): ''' 获取哈希加盐处理后的salt值 :param case_dict: 用例字典 :return: salt值 ''' xn_case = [] try: hash_order = eval(self.kargs.get("hash_orders", None)) except Exception as e: hash_order = self.kargs.get("hash_orders", None) value_order_list = [] for param_name in hash_order: xn_case.append(case_dict.get(param_name, "")) if param_name in case_dict.keys(): value_order_list.append(case_dict[param_name]) partnerKey = case_dict.get("partnerKey") if case_dict.get( "partnerKey") else "" salt = self.make_salt(value_order_list, partnerKey) return salt def make_salt(self, value_list=None, partnerKey=""): ''' 针对参数值列表进行salt加盐处理 :param value_list: 按传入顺序处理后的参数值列表 :param partnerKey: partnerKey值 :return: ''' deal_value_list = [] #进行处理后的参数值列表 for value in value_list: try: value_str = str(value) except Exception as e: value_str = value deal_value_list.append(value_str) value_str = "".join(deal_value_list) #将列表转为字符串,待加密信息 m = hashlib.md5() # 创建md5对象 # 此处必须encode # 若写法为m.update(str) 报错为: Unicode-objects must be encoded before hashing # 因为python3里默认的str是unicode # 或者 b = bytes(str, encoding='utf-8'),作用相同,都是encode为bytes b = value_str.encode(encoding='utf-8') #将字符串进行utf-8编码 m.update(b) #进行md5加密 value_str_md5 = m.hexdigest( ) #md5加密后的值为32位-hexdigest()默认是32位(bytes),16位值调用对象的digest() salt = value_str_md5 + partnerKey return salt def case_deal_param(self, case_dict): pass def get_sha256(self, filename): with open(filename, 'rb') as f: data = f.read() encodestr = base64.b64encode(data) s = hashlib.md5(data).hexdigest() return s
class CaseRun(unittest.TestCase): @classmethod def setUpClass(self): pass @classmethod def tearDownClass(self): pass def setUp(self): self.interface_run = InterfaceRun() self.deal_res_data = DealResData() self.op_excel = OperationExcel(**option_dict) self.method_req = "post" self.crr = CmpReqRes(**option_dict) self.cp = CaseIsPass(**option_dict) def tearDown(self): pass @ddt.data(*data_http) def test_apply_community(self, data_dict): ''' 测试数据={0} :param data_dict: :return: ''' pp = pprint.PrettyPrinter(indent=4) #获取请求不传入参数列表 no_request_list = cpd.param.get_param_no_request_list() no_request_dict = {} #存放不参数请求的参数 #深拷贝参数字典 req_data_dict = deepcopy(data_dict) if str(req_data_dict.get("IsDepend", "")).lower() == "yes": #是否需要先执行依赖测试用例 dep_case = DependCase(req_data_dict, option_dict) update_data = dep_case.get_dep_data() for data in update_data.keys(): req_data_dict[data] = update_data[data] if req_data_dict.get("Requrl", None): url = req_data_dict.pop("Requrl") else: url = option_dict["Requrl"] for param in no_request_list: no_request_dict[param] = req_data_dict.pop(param) req_s_time = time.time() ori_res = self.interface_run.main_request(self.method_req, url, req_data_dict) req_e_time = time.time() hs = req_e_time - req_s_time row_num = self.op_excel.get_row_num_for_value( no_request_dict.get("CaseID")) try: res = ori_res.json() except Exception as e: res = ori_res.text pp.pprint("{}用例执行详情如下:".format(option_dict.get("interface_name", ""))) pp.pprint("{}执行测试用例编号:[{}]".format( option_dict.get("interface_name", ""), no_request_dict["CaseID"])) pp.pprint("{}测试目的:{}".format(option_dict.get("interface_name", ""), no_request_dict["TestTarget"])) pp.pprint("{}用例描述:{}".format(option_dict.get("interface_name", ""), no_request_dict["CaseDesc"])) pp.pprint("{}地址:{}".format(option_dict.get("interface_name", ""), url)) pp.pprint("{}预期返回值={}".format(option_dict.get("interface_name", ""), no_request_dict["ExpectValue"])) pp.pprint("{}预期回调状态值={}".format(option_dict.get("interface_name", ""), no_request_dict["ExpCallbackFlag"])) pp.pprint( "******************************************************************************" ) pp.pprint("请求参数={}".format( json.dumps(req_data_dict, ensure_ascii=False))) pp.pprint( "******************************************************************************" ) pp.pprint("{}响应返回数据共<{}>条".format( option_dict.get("interface_name", ""), len(res.get("data", "")))) pp.pprint("{}响应结果={}".format(option_dict.get("interface_name", ""), res)) pp.pprint("{}响应耗时:{}".format(option_dict.get("interface_name", ""), hs)) kargs = { "no_request_dict": no_request_dict, "option_dict": option_dict, "expect": no_request_dict["ExpectValue"], "res": ori_res, "req": req_data_dict, "partnerID": req_data_dict.get("partnerID"), "partnerKey": req_data_dict.get("partnerKey"), "expCallbackFlag": no_request_dict["ExpCallbackFlag"], "no_verify_filed": option_dict.get("no_verify_filed", None) #数据库中无需验证字段 } start = time.time() verify_res = self.crr.verify_is_pass(**kargs) end = time.time() hs = end - start pp.pprint("{}响应结果验证耗时:{}".format(option_dict.get("interface_name", ""), hs)) is_pass = self.cp.case_is_pass(**verify_res) try: evidenceNo = res.get("evidenceNo") except: evidenceNo = "" #self.op_excel.writer_data(row_num, 15, evidenceNo) self.assertTrue(is_pass, "测试用例执行未通过")
class DependCase: def __init__(self, case_dict, case_config): self.case_dict = case_dict # 获取的用例中的参数值,不是配置文件中的参数值 self.case_config = case_config # 获取执行接口用例配置文件内容,写回值时获取正确的sheetid self.ope_excel_case = OperationExcel(**self.case_dict) self.ope_excel_config = OperationExcel(**self.case_config) self.interface_run = InterfaceRun() self.case_rownum = int( self.ope_excel_config.get_row_num_for_value( self.case_dict.get("CaseID", 0), )) # 获取测试用例参数名所在行 self.param_name_rownum = int(self.case_dict.get("DepParamName", 0)) #获取依赖的参数名所在行 self.case_id = self.case_dict.get("DepCaseID", "") #获取依赖的测试用例ID self.case_value_rownum = self.ope_excel_case.get_row_num_for_value( self.case_id) #根据依赖caseid获取依赖测试用例执行行号 self.case_row_value = self.ope_excel_case.get_sheet().row_values( self.param_name_rownum) #根据参数名所在行号获取整行内容 self.hash_orders = self.case_dict.get("hash_orders", []) #获取依赖的测试用例ID的参数顺序列表,用于生成salt self.DepGetDataForm = self.case_dict.get("DepGetDataForm", "") #依赖提取数据格式 try: self.DepParamList = eval(case_dict.get("DepParamList", [])) except Exception as e: self.DepParamList = case_dict.get("DepParamList", []) #获取运行依赖case需要的各项请求数据 def get_dep_data(self): ''' :return: 依赖测试用例执行结果 ''' # 获取参数名所在行返回参数名列表 self.case_dict[ "case_param_name_start"] = self.param_name_rownum #用例参数名开始行号 self.case_dict[ "case_start_rownum"] = self.case_value_rownum # 用例参数值开始行号 # self.case_dict["hash_orders"] = self.hash_orders # 用例参数顺序列表 # self.case_dict["DepGetDataForm"] = self.hash_orders # 用例参数顺序列表 cpd = CommonParamDict(**self.case_dict) case_data = cpd.deal_param() #[[]] no_request_list = cpd.param.get_param_no_request_list() dep_res = self.deal_dep_param(no_request_list, case_data[0]) #获取依赖测试用列响应结果 dep_res_dict = self.deal_req_res(dep_res) write_flag = self.write_excel_value(dep_res) count = 1 while True: if not write_flag: write_flag = self.write_excel_value(dep_res) count = count + 1 if count > 3: break else: break print("依赖用例执行测试的结果={}".format(dep_res)) return dep_res_dict def deal_dep_param(self, no_request_list, case_data): ''' 接口用例发送请求之前去除掉非接口传输参数 :param no_request_list: 获取请求接口不传入参数列表 :param case_data: 测试用例 :return: ''' deal_param_list = [] no_request_dict = {} # 存放不参数请求的参数 req_data_dict = deepcopy(case_data) #深拷贝参数字典 for param in no_request_list: no_request_dict[param] = req_data_dict.pop(param) deal_param_list.append(req_data_dict) deal_param_list.append(no_request_dict) req_s_time = time.time() url = no_request_dict.get("Requrl", "") ori_res = self.interface_run.main_request("post", url, req_data_dict) req_e_time = time.time() hs = req_e_time - req_s_time try: res = ori_res.json() except Exception as e: res = ori_res.text print("依赖测试用执请求接口用时:{}".format(hs)) return res def deal_req_res(self, res_json): ''' 将依赖测试用例执行结果按提取规则及参数处理后转为字段的形式 :case_dict :param res_json: 依赖测试用例响应结果转为json形式 :return: ''' res = jsonpath(res_json, self.DepGetDataForm)[0][0] dep_res_dict = {} for dep_res in res: if dep_res in self.DepParamList: dep_res_dict[dep_res] = res.get(dep_res, "") return dep_res_dict def write_excel_value(self, dep_res): ''' 将依赖数据结果写回到excel表格指定的单元格中 :param dep_res: :return: ''' write_flag = False ope_excel = OperationExcel(**self.case_config) case_param_name_start = self.case_config.get("case_param_name_start", 0) #测试用例参数名开始行 case_row_value = ope_excel.get_sheet().row_values( case_param_name_start) row_num = self.case_rownum dep_res_dict = self.deal_req_res(dep_res) for update_param in dep_res_dict.keys(): for index, update_value in enumerate(case_row_value): if update_param in str(update_value).split("-")[1]: col_num = index ope_excel.writer_data(row_num, col_num, update_value) write_flag = True return write_flag