def __init__(self): tlk_helper = TestLinkHelper() try: self.testlink = tlk_helper.connect(TestlinkAPIClient) # 连接TestLink except Exception as e: logger.error('连接testlink失败:%s' % e) exit()
def run_testcase_by_id(testcase_id, httpobj=None, testplan='无计划'): try: testcase_info = mytestlink.getTestCase(testcase_id) # 获取测试用例基本信息 logger.info('获取测试用例信息 %s' % testcase_info) except Exception as e: logger.error('获取用例信息失败 %s,,暂停执行该用例' % e) return ('Fail',[('global_funtion_module','获取用例信息失败 %s' % e)]) # 获取用例所在套件和项目名称 response = mytestlink.getFullPath([int(testcase_id)]) response = response[str(testcase_id)] testsuite_name = '' for suit in response[1:]: testsuite_name = testsuite_name + '-' + suit testsuite_name = testsuite_name.lstrip('-') project_name = response[0] # 构造测试用例对象 testcase_name = testcase_info[0]['name'] testcase_steps = testcase_info[0]['steps'] testcase_isactive = int(testcase_info[0]['active']) testsuite_id = int(testcase_info[0]['testsuite_id']) preconditions = testcase_info[0]['preconditions'] tc_external_id = testcase_info[0]['full_tc_external_id'] testcase_obj = TestCase(testcase_id, testcase_name, testcase_steps, testcase_isactive, project_name, testsuite_id, tc_external_id, preconditions) if httpobj: myhttp = httpobj else: myhttp = get_http_conf_of_project(project_name) if not myhttp: logger.critical('用例所在项目配置存在问题,停止执行该用例') return ('Block',[('golbal_function_module', '用例所在项目配置存在问题,停止执行该用例')]) try: sql_insert = 'INSERT INTO '+testcase_report_tb +'(executed_history_id, testcase_id, testcase_name, testsuit, testplan, project, runresult, runtime, tc_external_id)' \ ' VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s)' data = (executed_history_id, testcase_id, testcase_name, testsuite_name, testplan, project_name, 'Block','0000-00-00 00:00:00', tc_external_id) logger.info('记录测试用例到测试用例报表') testdb.execute_insert(sql_insert, data) logger.info('开始执行测试用例[id=%s,name=%s]' % (testcase_id, testcase_name)) run_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) # 记录运行时间 case_executed_history_id = time.strftime('%Y%m%d%H%M%S', time.localtime()) # 流水记录编号 testcase_run_result = testcase_obj.run_testcase(myhttp, testplan, case_executed_history_id) logger.info('正在更新用例执行结果') sql_update = 'UPDATE '+testcase_report_tb +' SET runresult=\"%s\", runtime=\"%s\",' \ ' case_exec_history_id=\"%s\"' \ ' WHERE executed_history_id = %s and testcase_id = %s' \ ' AND project=\'%s\' AND testplan=\'%s\'' data = (testcase_run_result[0], run_time, str(case_executed_history_id), executed_history_id, testcase_id, project_name, testplan) testdb.execute_update(sql_update, data) logger.info('指定用例[%s]已执行完' % testcase_name) return testcase_run_result except Exception as e: logger.error('运行用例出错 %s' % e) return ('Fail',[('golbal_function_module', '%s' % e)])
def __init__(self): tlk_helper = TestLinkHelper( server_url= 'http://192.168.202.174/testlink-1.9.17/lib/api/xmlrpc/v1/xmlrpc.php', devkey='0b839ca6b6a4d8b78139e5f5f93c38f1') try: self.testlink = tlk_helper.connect(TestlinkAPIClient) # 连接TestLink except Exception as e: logger.error('连接testlink失败:%s' % e) exit()
def __init__(self): tlk_helper = TestLinkHelper() url = "http://192.168.199.13:81/testlink/lib/api/xmlrpc/v1/xmlrpc.php" key = "68194d618ccb4ce674f3935d73bf77ac" try: self.testlink = testlink.TestlinkAPIClient(url, key) # 连接TestLink except Exception as e: logger.error('连接testlink失败:%s' % e) exit()
def run_step(self, http=None): if '步骤类型' in self.action and (self.action['步骤类型']).lower() == '执行sql': # 执行sql脚本 step_run_result = self.run_sql_in_action() logger.debug('step_run_result:error, %s' % step_run_result[1]) return (step_run_result[0], [('CaseStep', step_run_result[1])]) else: try: if '类名' in self.action.keys(): class_name = self.action['类名'] else: class_name = 'InterfaceUnittestTestCase' if '函数' in self.action.keys(): function = self.action['函数'] else: function = 'test_interface_of_urlencode' logger.info('调用的方法为:%s.%s' % (class_name, function)) except Exception as e: logger.error('步骤[%s]信息填写不正确: %e,执行失败' % (self.step_number, e)) return ('Error', [('CaseStep', '%s' % e)]) # 替换动态参数 self.action['参数'] = self.__repalce_value_of_parmas_in_quest( self.action['参数']) self.action['url'] = self.__repalce_value_of_parmas_in_quest( self.action['url']) if self.expected_result != '' and '条件' in self.expected_result.keys( ): self.expected_result[ '条件'] = self.__repalce_value_of_parmas_in_quest( self.expected_result['条件']) if '请求头' in self.action.keys(): self.action['请求头'] = self.__repalce_value_of_parmas_in_quest( self.action['请求头']) self.action['请求头'] = json.dumps(self.action['请求头']) self.action['请求头'] = json.loads(self.action['请求头']) runner = unittest.TextTestRunner() test_step_action = unittest.TestSuite() test_step_action.addTest((globals()[class_name])(function, http, self)) step_run_result = runner.run(test_step_action) logger.debug('step_run_result:%s, errors:%s,failures:%s' % (step_run_result, step_run_result.errors, step_run_result.failures)) if 0 != len(step_run_result.errors): return ('Error', step_run_result.errors) elif 0 != len(step_run_result.failures): return ('Fail', step_run_result.failures) else: return ('Pass', '')
def get(self, url, params=''): url = self.protocol + '://' + self.host + ':' + str( self.port) + url + params logger.info('发起的请求为:%s' % url) request = urllib.request.Request(url, headers=self.headers) try: response = urllib.request.urlopen(request) response = response.read() return response except Exception as e: logger.error('发送请求失败,原因:%s' % e) return None
def post(self, url, data=''): url = self.protocol + '://' + self.host + ':' + str(self.port) + url logger.info('发起的请求为:%s' % url) request = urllib.request.Request(url, headers=self.headers) try: response = urllib.request.urlopen(request, data) # response = response.read().decode('utf-8') response = response.read() return response except Exception as e: logger.error('发送请求失败,原因:%s' % e) return None
def extrator(self,extrator,response_to_check=''): if type(extrator) == type({}): # 获取键值 # 获取list方式标识的key,value层级值 dict_level_list = other_tools.get_dict_level_list(extrator) other_tools.set_dict_level_list([]) logger.info('要提取的字典key,value层级为:%s' % dict_level_list) if type(response_to_check) == type(''): # 字符串类型的字典、json串 try: response_to_check = json.loads(response_to_check) # //转字符串为json except Exception as e: logger.error('转换服务器返回内容为字典失败:%s' % e) return [] if type(response_to_check) != type({}): logger.error('服务器返回内容不为字典、字符串类型的字典') return [] value_get = other_tools.find_dict_last_leve_value(dict_level_list, response_to_check) logger.info('找到的对应字典层级的key的值为:%s' % value_get) other_tools.set_key_index(0) return value_get elif type(extrator) == type(''): # 获取正则表达式匹配的内容 if type(response_to_check) in [type({}), type(set()), type(()), type([]), type(1), type(0.01)]: response_to_check = str(response_to_check) elif type(response_to_check) != type(''): logger.error('服务器返回内容不为字符串类型') return [] result = re.findall(extrator, response_to_check) return result else: logger.error('提取器不为字典或者字符串类型的正则表达式') return []
def __init__(self, run_mode_conf): config = configparser.ConfigParser() # 从配置文件中读取运行模式 config.read(run_mode_conf, encoding='utf-8-sig') try: self.run_mode = config['RUNMODE']['runmode'] self.project_mode = int(config['PROJECTS']['project_mode']) self.projects = config['PROJECTS']['projects'] self.testplans = config['PLANS']['plans'] self.project_of_plans = config['PLANS']['project'] self.testsuites = config['TESTSUITES']['testsuites'] except Exception as e: logger.error('读取运行模式配置失败:%s' % e) exit()
def get(self, url, params=''): url = self.protocol + '://' + self.host + ':' + str(self.port) + url + params logger.info('发起的请求为:%s' % url) logger.info('请求头为:%s' % self.headers) request = urllib.request.Request(url, headers=self.headers) try: response = urllib.request.urlopen(request) response_body = response.read() response_header = response.getheaders() response_status_code = response.status response = [response_body, response_header, response_status_code] return response except Exception as e: logger.error('发送请求失败,原因:%s' % e) return None
def __init__(self, run_mode_conf): config = configparser.ConfigParser() # 从配置文件中读取运行模式 config.read(run_mode_conf, encoding='gbk') try: self.run_mode = config['RUNMODE']['runmode'] self.project_mode = int(config['PROJECTS']['project_mode']) self.projects = config['PROJECTS']['projects'] self.testplans = config['PLANS']['plans'] self.project_of_plans = config['PLANS']['project'] self.testsuites = config['TESTSUITES']['testsuites'] self.case_id_list = eval(config['TESTCASES']['case_id_list']) self.global_cases_str = config['GLOBALCASES']['global_cases_str'] self.global_cases = [] except Exception as e: logger.error('读取运行模式配置失败:%s' % e) exit()
def get_http_conf_of_project(project_name): try: testproject = mytestlink.getTestProjectByName(project_name) except Exception as e: logger.error('测试项目[project:%s]获取失败,暂时无法执行:%s' % (project_name, e)) return None project_notes = other_tools.conver_date_from_testlink(testproject['notes']) logger.info('正在读取测项目[project:%s]的协议,host,端口配置...' % project_name) testproject_conf = project_notes logger.info('成功读取配置信息:%s' % testproject_conf) if '' == testproject_conf: logger.error('测试项目[project:%s]未配置协议,host,端口信息,暂时无法执行' % project_name) return None try: notes = json.loads(testproject_conf) protocol = notes['protocol'] host = notes['host'] port = notes['port'] except Exception as e: logger.error('测试项目[project:%s]协议,host,端口信息配置错误,暂时无法执行:%s' % (project_name, e)) return None logger.info('正在构建项目的http对象') myhttp = MyHttp(protocol, host, port) return myhttp
def find_autocase(self, testcase_summary): platform_dir = other_tools.get_platform_dir() testdir = platform_dir + '/testcases/' logger.info('sion::Will find test cases: %s' % testcase_summary) discover = unittest.defaultTestLoader.discover(testdir, pattern=testcase_summary) #testsuite1 = unittest.TestSuite() #testsuite1.addTest(TestLogin("test_LoginLogout")) logger.info('sion:discover testcases number:::%s' % discover.countTestCases()) report_dir = platform_dir + '/testreport' now = time.strftime("%Y-%m-%d_%H_%M_%S") report_name = report_dir + '/' + self.testproject + '_' + self.testplan + '_' + self.testcase_name + '_' + now + '_' + 'result.html' logger.info('sion::steps' % self.steps) logger.info('sion::start selenium test cases') with open(report_name, 'wb') as f: runner = BSTestRunner(stream=f, title="Test report", description="Test run result") logger.info('start BSTestRunner') try: runner.run(discover) #runner.run(testsuite1) except Exception as e: logger.error('test case error %s' % e) f.close()
def run_step(self, http): try: class_name = self.action['class'] function = self.action['function'] logger.info('调用的方法为:%s.%s' % (class_name, function)) except Exception as e: logger.error('步骤[%s]信息填写不正确: %e,执行失败' % (self.step_number, e)) return ('Error', ('%s' % e)) runner = unittest.TextTestRunner() test_step_action = unittest.TestSuite() test_step_action.addTest((globals()[class_name])(function, http, self)) step_run_result = runner.run(test_step_action) logger.debug('step_run_result:%s, errors:%s,failures:%s' % (step_run_result, step_run_result.errors, step_run_result.failures)) if 0 != len(step_run_result.errors): return ('Error', step_run_result.errors) elif 0 != len(step_run_result.failures): return ('Fail', step_run_result.failures) else: return ('Pass', '')
def __repalce_value_of_parmas_in_quest(self, params): str_dic = '{"key":"value"}' temp_re = json.loads(str_dic, object_pairs_hook=OrderedDict) is_ordered_dict = 0 if type(params) == type(temp_re): # step_action为OrderdDict params = json.dumps(params) is_ordered_dict = 1 if type(params) == type({}): # json串 # 遍历查找动态参数 for key, value in params.items(): if type(value) == type(''): # 值为动态参数的前提 if value.find('[') == 0 and value.find( ']') == len(value) - 1 and value.find( 'global_') == -1: # 非全局参数 logger.info('从json字典串中找到待替换的非全局动态参数:%s' % value) value = value.lstrip('[') value = value.rstrip(']') if value.find('.') == -1: class_name = 'InterfaceUnittestTestCase' param_name = value else: class_name, param_name = value.split('.') output_list = (globals()[class_name]).outputs_list for item in output_list: if param_name in item.keys(): # 替换参数 params[key] = item.get(param_name) elif value.find('[') == 0 and value.find(']') == len( value) - 1 and value.find('global_') != -1: # 全局参数 logger.info('从json字典串中找到待替换的全局动态参数:%s' % value) param_name = value.lstrip('[') param_name = param_name.rstrip(']') try: params[key] = globals()[param_name] except Exception as e: logger.error('转换全局动态参数出错 %s' % e) logger.info('转换后的参数体为:%s' % params) return params elif type(params) == type(''): # 字符串类型的参数 # 遍历查找动态参数 var_params = re.findall('\[.+?\]', params) if var_params == []: logger.info('没找到需要替换的动态参数') if is_ordered_dict == 1: params = json.loads(params, object_pairs_hook=OrderedDict) return params new_params = params for item in var_params: if item.find('global_') == -1: logger.info('从字符串中找到待替换的非全局动态参数:%s' % item) value = item.lstrip('[') value = value.rstrip(']') if value.find('.') != -1: class_name, param_name = value.split('.') else: class_name = 'InterfaceUnittestTestCase' param_name = value output_list = (globals()[class_name]).outputs_list for output in output_list: if param_name in output.keys(): # 替换参数 new_params = new_params.replace( item, str(output.get(param_name))) elif item.find('global_') != -1: logger.info('从字符串中找到待替换的全局动态参数:%s' % item) param_name = item.lstrip('[') param_name = param_name.rstrip(']') try: new_params = new_params.replace( item, str(globals()[param_name])) except Exception as e: logger.error('转换全局动态参数出错 %s' % e) if is_ordered_dict == 1: new_params = json.loads(new_params, object_pairs_hook=OrderedDict) logger.info('转换后的参数体为:%s' % new_params) return new_params else: logger.info('没找到需要替换的动态参数') return params
def __repalce_value_of_parmas_in_quest(self, params): is_list_params = 0 str_dic = '{"key":"value"}' temp_re = json.loads(str_dic, object_pairs_hook=OrderedDict) is_ordered_dict = 0 if type([]) == type(params): # params为预期结果中的“条件” params = str(params).lstrip('[') params = params.rstrip(']') is_list_params = 1 elif type(params) == type(temp_re): # step_action为OrderdDict params = json.dumps(params) is_ordered_dict = 1 if type(params) == type({}): # json串 # 遍历查找动态参数 for key, value in params.items(): if type(value) == type(''): # 值为动态参数的前提 if value[0:1] == '[' and value[0:2] not in ( '[@', '[{') and value[-1:] == ']' and value[ 1:8] != 'global_' and not value[1:-1].isdigit( ): # 参数名不能为纯数字,[@、[{打头: # 非全局参数 logger.info('从json字典串中找到待替换的非全局动态参数:%s' % value) value = value.lstrip('[') value = value.rstrip(']') if value.find('.') == -1: class_name = 'InterfaceUnittestTestCase' param_name = value else: class_name, param_name = value.split('.') output_dict = (globals()[class_name]).outputs_dict if param_name in output_dict.keys(): params[key] = output_dict[param_name] # 替换参数 elif value[0:1] == '[' and value[-1:] == ']' and value[ 1:8] == 'global_': # 全局参数 logger.info('从json字典串中找到待替换的全局动态参数:%s' % value) param_name = value.lstrip('[') param_name = param_name.rstrip(']') try: params[key] = globals()[param_name] except Exception as e: logger.error('转换全局动态参数出错 %s' % e) logger.info('转换后的参数体为:%s' % params) return params elif type(params) == type(''): # 字符串类型的参数 # 遍历查找动态参数 var_params = re.findall('\[.+?\]', params) if var_params == []: logger.info('没找到需要替换的动态参数') if is_ordered_dict == 1: params = json.loads(params, object_pairs_hook=OrderedDict) elif is_list_params == 1: params = '[' + params + ']' params = eval(params) return params new_params = params for item in var_params: if item[1:8] != 'global_' and not item[1:-1].isdigit( ) and item[0:2] not in ('[@', '[{'): # 参数名不能为纯数字,不能以[@、[{打头 logger.info('从字符串中找到待替换的非全局动态参数:%s' % item) value = item.lstrip('[') value = value.rstrip(']') if value.find('.') != -1: class_name, param_name = value.split('.') else: class_name = 'InterfaceUnittestTestCase' param_name = value output_dict = (globals()[class_name]).outputs_dict if param_name in output_dict.keys(): if type(output_dict[param_name]) != type( ''): # 参数值不为字符串类型,"key":"[var]",转为"key":var item = "'" + item + "'" old_params = new_params new_params = new_params.replace( item, str(output_dict[param_name])) # 替换参数 if new_params == old_params: # 说明参数类似这样的:"参数":"([CaseStep.branch_id],)" item = item.strip("'") new_params = new_params.replace( item, str(output_dict[param_name])) # 替换参数 elif item[1:8] == 'global_': logger.info('从字符串中找到待替换的全局动态参数:%s' % item) param_name = item.lstrip('[') param_name = param_name.rstrip(']') try: new_params = new_params.replace( item, str(globals()[param_name])) except Exception as e: logger.error('转换全局动态参数出错 %s' % e) if is_ordered_dict == 1: new_params = json.loads(new_params, object_pairs_hook=OrderedDict) elif is_list_params == 1: new_params = '[' + new_params + ']' new_params = eval(new_params) logger.info('转换后的参数体为:%s' % new_params) return new_params else: logger.info('没找到需要替换的动态参数') return params
def run_testcase(self, http, testplan): if 0 == self.active_status: logger.warning('用例[name=%s]处于禁用状态[active=0],不执行' % self.testcase_name) return 'Block' protocol_all = http.get_protocol() host_all = http.get_host() port_all = http.get_port() for step in self.steps: # 构造测试步骤对象 step_id = int(step['id']) step_number = int(step['step_number']) step_action = other_tools.conver_date_from_testlink(step['actions']) expected_results = other_tools.conver_date_from_testlink(step['expected_results']) logger.debug('step_action: %s' % step_action) sql_insert = 'INSERT INTO '+ case_step_report_tb +'(executed_history_id, testcase_id, testcase_name, testplan, project, step_id, step_num, protocol_method, protocol, host, port, ' \ 'step_action, expected_results, runresult, reason, runtime)' \ ' VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)' if step_action.find('style') != -1: data = (executed_history_id, self.testcase_id, self.testcase_name, testplan, self.testproject, step_id, step_number, '无', '无', '无', '无', step_action, expected_results, 'Block', '', '') else: data = (executed_history_id, self.testcase_id, self.testcase_name, testplan, self.testproject, step_id, step_number, '', protocol_all, host_all, port_all, step_action, expected_results, 'Block', '', '') logger.info('记录测试步骤到测试步骤报告表') testdb.execute_insert(sql_insert, data) try: step_action = json.loads(step_action) if 'style' not in step_action: protocol_method = step_action['method'] else: protocol_method = '无' if expected_results != '': expected_results = json.loads(expected_results) step_obj = CaseStep(step_id, step_number, expected_results, step_action, self.testcase_id) except Exception as e: logger.error('步骤[%s]信息填写错误: %s,停止执行用例[id=%s, name=%s]' % (step_number, e, self.testcase_id, self.testcase_name)) return 'Error' logger.info('开始执行步骤操作[第%s步]'% step_number) run_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) # 记录运行时间 if 'style' in step_action: step_run_result = globalpkg.global_function.run_testcase_by_id(step_action['testcase_id'], testplan) else: step_run_result = step_obj.run_step(http) try:# 转换 “ 为 ‘ ,防止数据库存储出错 action_of_step = step_obj.get_action() if type(action_of_step) == type(b''): action_of_step = action_of_step.decode('utf-8') elif type(action_of_step) == type({}): action_of_step = str(action_of_step) action_of_step = action_of_step.replace('"', "'") result_of_step = step_obj.get_expected_result() if type(result_of_step) == type(b''): result_of_step = result_of_step.decode('utf-8') elif type(result_of_step) == type({}): result_of_step = str(result_of_step) result_of_step = result_of_step.replace('"', "'") # except Exception as e: # logger.error('获取step action、expected_result出错 %s' % e) # action_of_step = '' # result_of_step = '' finally: if step_run_result[0] == 'Error': fail_or_error_reason = step_run_result[1][0][1] fail_or_error_reason = fail_or_error_reason.replace('\n', '') fail_or_error_reason = fail_or_error_reason.replace('\"', '') fail_or_error_reason = fail_or_error_reason.replace('\'', '') logger.error('步骤[%s]执行出错,停止执行用例[id=%s, name=%s]' % (step_number, self.testcase_id, self.testcase_name)) sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\",' \ 'step_action=\"%s\", expected_results=\"%s\"' \ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s' \ ' AND project=\'%s\' AND testplan=\'%s\'' % \ (step_run_result[0], fail_or_error_reason, protocol_method, run_time, action_of_step, result_of_step, str(executed_history_id),self.testcase_id, step_id, self.testproject, testplan) logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update) return 'Error' elif step_run_result[0] == 'Fail': fail_or_error_reason = step_run_result[1][0][1] fail_or_error_reason = fail_or_error_reason.replace('\n', '') fail_or_error_reason = fail_or_error_reason.replace('\"', '') fail_or_error_reason = fail_or_error_reason.replace('\'', '') logger.info('步骤[%s]执行失败,停止执行用例[id=%s, name=%s]' % (step_number, self.testcase_id, self.testcase_name)) sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\",' \ 'step_action=\"%s\", expected_results=\"%s\"' \ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s' \ ' AND project=\'%s\' AND testplan=\'%s\'' % \ (step_run_result[0], fail_or_error_reason, protocol_method, run_time, action_of_step, result_of_step, str(executed_history_id),self.testcase_id, step_id, self.testproject, testplan) logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update) return 'Fail' elif step_run_result[0] == 'Block': fail_or_error_reason = step_run_result[1] logger.info('步骤[%s]执行失败,停止执行用例[id=%s, name=%s]' % (step_number, self.testcase_id, self.testcase_name)) sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\"' \ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s' \ ' AND project=\'%s\' AND testplan=\'%s\'' % \ (step_run_result[0], fail_or_error_reason, '无', run_time, str(executed_history_id), self.testcase_id, step_id, self.testproject, testplan) logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update) return 'Fail' else: fail_or_error_reason = '' # sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\"' \ # ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s'\ # ' AND project=\'%s\' AND testplan=\'%s\'' % \ # (step_run_result[0], fail_or_error_reason, protocol_method, run_time, str(executed_history_id), self.testcase_id, step_id, # self.testproject, testplan) sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\",' \ 'step_action=\"%s\", expected_results=\"%s\"'\ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s'\ ' AND project=\'%s\' AND testplan=\'%s\'' % \ (step_run_result[0], fail_or_error_reason, protocol_method, run_time, action_of_step, result_of_step, str(executed_history_id),self.testcase_id, step_id, self.testproject, testplan) logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update) logger.info('测试用例[id=%s, name=%s]执行成功' % (self.testcase_id, self.testcase_name)) return 'Pass'
from sendmail import MyMail run_mode_conf = RunModeConfig('./config/runmodeconfig.conf') run_mode = int(run_mode_conf.get_run_mode()) if 1: logger.info('按套件运行测试') testsuits_id_list = run_mode_conf.get_testsuits() logger.info('已获取配置的套件id列表:%s' % testsuits_id_list) testsuits_id_list = eval(testsuits_id_list) for testsuite_id in testsuits_id_list: # 构造测试套件对象 try: testsuite_info = mytestlink.getTestSuiteByID(testsuite_id) except Exception as e: logger.error('测试套件[id=%s]不存在,暂时无法执行' % testsuite_id) continue testsuite_name = testsuite_info['name'] print("testsuitename=%s"%testsuite_name) testsuite_details = other_tools.conver_date_from_testlink(testsuite_info['details']) print ("testsuite_details=%s"%testsuite_details) project = mytestlink.getFullPath(testsuite_id) print("project1=%s"%project) project = project[str(testsuite_id)][0] print("project2=%s" % project) testsuite_obj = TestSuite(testsuite_id, testsuite_name, testsuite_details, project) print("testsuite_obj=%s"%testsuite_obj) logger.info('正在读取套件[id=%s,name=%s]的协议,host,端口配置...' % (testsuite_id, testsuite_name)) testsuite_conf = testsuite_obj.get_testsuite_conf() # 获取套件基本信息 print ("testsuite_conf=%s"%testsuite_conf)
def run_testcase(self, http, testplan): if 0 == self.active_status: logger.warning('用例[name=%s]处于禁用状态[active=0],不执行' % self.testcase_name) return 'Block' protocol_all = http.get_protocol() host_all = http.get_host() port_all = http.get_port() for step in self.steps: # 构造测试步骤对象 step_id = int(step['id']) step_number = int(step['step_number']) step_action = other_tools.conver_date_from_testlink(step['actions']) expected_results = other_tools.conver_date_from_testlink(step['expected_results']) logger.debug('step_action: %s' % step_action) sql_insert = 'INSERT INTO '+ case_step_report_tb +'(executed_history_id, testcase_id, testcase_name, testplan, project, step_id, step_num, protocol_method, protocol, host, port, ' \ 'step_action, expected_results, runresult, reason, runtime)' \ ' VALUES' data = "('{}','{}','{}','{}','{}','{}','{}', '','{}','{}','{}','{}','{}', 'Block', '', '{}')".format(executed_history_id,self.testcase_id,self.testcase_name,testplan,self.testproject,step_id,step_number,protocol_all,host_all,port_all,step_action,expected_results,time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) logger.info('记录测试步骤到测试步骤报告表') sql = str(sql_insert) + str(data) testdb.execute_insert(sql) try: expected_results = json.loads(expected_results) step_action = json.loads(step_action) step_obj = CaseStep(step_id, step_number, expected_results, step_action, self.testcase_id) protocol_method = step_action['method'] except Exception as e: logger.error('步骤[%s]信息填写错误: %s,停止执行用例[id=%s, name=%s]' % (step_number, e, self.testcase_id, self.testcase_name)) return 'Error' logger.info('开始执行步骤操作[第%s步]'% step_number) run_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) # 记录运行时间 step_run_result = step_obj.run_step(http) if step_run_result[0] == 'Error': fail_or_error_reason = step_run_result[1][0][1] fail_or_error_reason = fail_or_error_reason.replace('\n', '') fail_or_error_reason = fail_or_error_reason.replace('\"', '') fail_or_error_reason = fail_or_error_reason.replace('\'', '') logger.error('步骤[%s]执行出错,停止执行用例[id=%s, name=%s]' % (step_number, self.testcase_id, self.testcase_name)) sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\"' \ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s'\ ' AND project=\'%s\' AND testplan=\'%s\'' % \ (step_run_result[0], fail_or_error_reason, protocol_method, run_time, str(executed_history_id), self.testcase_id, step_id, self.testproject, testplan) logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update) return 'Error' elif step_run_result[0] == 'Fail': fail_or_error_reason = step_run_result[1][0][1] fail_or_error_reason = fail_or_error_reason.replace('\n', '') fail_or_error_reason = fail_or_error_reason.replace('\"', '') fail_or_error_reason = fail_or_error_reason.replace('\'', '') logger.info('步骤[%s]执行失败,停止执行用例[id=%s, name=%s]' % (step_number, self.testcase_id, self.testcase_name)) sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\"' \ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s'\ ' AND project=\'%s\' AND testplan=\'%s\'' % \ (step_run_result[0], fail_or_error_reason, protocol_method, run_time, str(executed_history_id), self.testcase_id, step_id, self.testproject, testplan) testdb.execute_update(sql_update) return 'Fail' else: fail_or_error_reason = '' sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\"' \ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s'\ ' AND project=\'%s\' AND testplan=\'%s\'' % \ (step_run_result[0], fail_or_error_reason, protocol_method, run_time, str(executed_history_id), self.testcase_id, step_id, self.testproject, testplan) logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update) logger.info('测试用例[id=%s, name=%s]执行成功' % (self.testcase_id, self.testcase_name)) return 'Pass'
def assert_result(self, response_to_check): ''' 执行预期结果 :param response_to_check: 服务器返回的响应 :return: 用户没有设置匹配规则,返回程序 ''' if self.expected_result != '': if re.findall('匹配规则', str(self.expected_result)) == []: logger.info('用户没有设置匹配规则,返回程序') self.assertEqual(1, 1, msg='用户没有设置匹配规则') return if self.expected_result != '': if self.expected_result['匹配规则'] == '包含成员': if type(response_to_check) not in [type(''), type([]), type(()), type(set()), type({})]: logger.error('服务器返回内容为不可迭代对象') self.assertEqual(1, 0, msg='服务器返回内容为不可迭代对象') # 遍历条件列表, 形如 "条件":[{"模式":"\"success\"", "消息":"创建储值卡支付订单失败,返回json串不包含key - success"},{"模式":"\"attach\"", "消息":"创建储值卡支付订单失败,返回json串不包含key - attach"}] for item in self.expected_result['条件']: member = item['模式'] logger.info('要匹配的模式(成员)为:%s' % member) self.assertIn(member, response_to_check, msg=item['消息']) elif self.expected_result['匹配规则'] == '不包含成员': if type(response_to_check) not in [type(''), type([]), type(()), type(set()), type({})]: logger.error('服务器返回内容为不可迭代对象') self.assertEqual(1, 0, msg='服务器返回内容为不可迭代对象') # 遍历条件列表,形如 "条件":[{"模式":"\"success\"", "消息":"创建储值卡支付订单失败,返回json串包含key - success"},{"模式":"\"attach\"", "消息":"创建储值卡支付订单失败,返回json串包含key - attach"}] for item in self.expected_result['条件']: member = item['模式'] logger.info('要匹配的模式(成员)为:%s' % member) self.assertNotIn(member, response_to_check, msg=item['消息']) elif self.expected_result['匹配规则'] == '包含字符串': if type(response_to_check) in [type({}), type(set()), type(()), type([]), type(1), type(0.01)]: response_to_check = str(response_to_check) elif type(response_to_check) != type(''): logger.error('服务器返回内容不为字符串类型') self.assertEqual(1, 0, msg='服务器返回内容不为字符串类型') # 遍历条件列表, 形如:"条件":[{"模式":"\"success\":true", "消息":"创建储值卡支付订单失败,success不为True"},{"模式":"\"success\":false", "消息":"创建储值卡支付订单失败,success不为false"}] for item in self.expected_result['条件']: pattern_str = item['模式'] logger.info('要匹配的模式(子字符串)为:%s' % pattern_str) self.assertIn(pattern_str, response_to_check, item['消息']) elif self.expected_result['匹配规则'] == '不包含字符串': if type(response_to_check) in [type({}), type(set()), type(()), type([]), type(1), type(0.01)]: response_to_check = str(response_to_check) elif type(response_to_check) != type(''): logger.error('服务器返回内容不为字符串类型') self.assertEqual(1, 0, msg='服务器返回内容不为字符串类型') # 遍历条件列表, 形如:"条件":[{"模式":"\"success\":true", "消息":"创建储值卡支付订单失败,success不为True"},{"模式":"\"success\":false", "消息":"创建储值卡支付订单失败,success不为false"}] for item in self.expected_result['条件']: pattern_str = item['模式'] logger.info('要匹配的模式(子字符串)为:%s' % pattern_str) self.assertNotIn(pattern_str, response_to_check, item['消息']) elif self.expected_result['匹配规则'] == '键值相等': if type(response_to_check) == type(''): # 字符串类型的字典、json串 try: response_to_check = json.loads(response_to_check) # //转字符串为json except Exception as e: logger.error('转换服务器返回内容为字典失败') self.assertEqual(1, 0, msg='转换服务器返回内容为字典失败') if type(response_to_check) == type([]): # 格式[{}]的json串 try: response_to_check = response_to_check[0] response_to_check = json.loads(response_to_check) # //转字符串为json except Exception as e: logger.error('转换服务器返回内容为字典失败') self.assertEqual(1, 0, msg='转换服务器返回内容为字典失败') if type(response_to_check) != type({}): logger.error('服务器返回内容不为字典、字符串类型的字典') self.assertEqual(1, 0, msg='服务器返回内容不为字典、字符串类型的字典') # 遍历条件列表, 形如:"条件":[{"模式":{"success":true}, "消息":"创建储值卡支付订单失败,success不为True"},{"模式":{"success":false}, "消息":"创建储值卡支付订单失败,success不为false"}] for item in self.expected_result['条件']: pattern_dic = item['模式'] # 获取list方式标识的key,value层级值 dict_level_list = other_tools.get_dict_level_list(pattern_dic) other_tools.set_dict_level_list([]) logger.info('要匹配的字典key,value层级为:%s' % dict_level_list) last_value = other_tools.find_dict_last_leve_value(dict_level_list, response_to_check) logger.info('找到的对应字典层级的最后值为:%s' % last_value) other_tools.set_key_index(0) # 比较同层级,相同key对应的value值 self.assertEqual(dict_level_list[len(dict_level_list) - 1], last_value, item['消息']) elif self.expected_result['匹配规则'] == '匹配正则表达式': if type(response_to_check) in [type({}), type(set()), type(()), type([]), type(1), type(0.01)]: response_to_check = str(response_to_check) elif type(response_to_check) != type(''): logger.error('服务器返回内容不为字符串类型') self.assertEqual(1, 0, msg='服务器返回内容不为字符串类型') # 遍历条件列表, 形如( "条件":[{"模式":"\"success\":true", "消息":"创建储值卡支付订单失败,success不为True"},{"模式":"\"success\":false", "消息":"创建储值卡支付订单失败,success不为false"}] for item in self.expected_result['条件']: pattern_str = item['模式'] logger.info('要匹配的模式(正则表达式)为:%s' % pattern_str) self.assertRegex(response_to_check, pattern_str, msg=item['消息']) elif self.expected_result['匹配规则'] == '不匹配正则表达式': if type(response_to_check) in [type({}), type(set()), type(()), type([]), type(1), type(0.01)]: response_to_check = str(response_to_check) elif type(response_to_check) != type(''): logger.error('服务器返回内容不为字符串类型') self.assertEqual(1, 0, msg='服务器返回内容不为字符串类型') # 遍历条件列表,形如 "条件":[{"模式":"\"success\":true", "消息":"创建储值卡支付订单失败,success为True"},{"模式":"\"success\":false", "消息":"创建储值卡支付订单失败,success为false"}] for item in self.expected_result['条件']: pattern_str = item['模式'] logger.info('要匹配的模式(正则表达式)为:%s' % pattern_str) self.assertNotRegex(response_to_check, pattern_str, msg=item['消息']) elif self.expected_result['匹配规则'] == '完全匹配字典': if type(response_to_check) == type(''): # 字符串类型的字典、json串 try: response_to_check = json.loads(response_to_check) # //转字符串为json except Exception as e: logger.info('转换服务器返回内容为字典失败') self.assertEqual(1, 0, msg='转换服务器返回内容为字典失败') elif type(response_to_check) != type({}): logger.error('服务器返回内容不为字典') self.assertEqual(1, 0, msg='服务器返回内容不为字典') # 遍历条件列表 "条件":[{"模式":{"success":true}, "消息":"创建储值卡支付订单失败,返回结果和字典模式不匹配"}] for item in self.expected_result['条件']: pattern_dic = item['模式'] logger.info('要匹配的模式(字典)为:%s' % pattern_dic) self.assertDictEqual(response_to_check, pattern_dic, msg=item['消息']) elif self.expected_result['匹配规则'] == '完全匹配列表': if type(response_to_check) == type(''): # 字符串类型的列表 try: response_to_check = eval(response_to_check) except Exception as e: logger.info('转换服务器返回内容为列表失败') self.assertEqual(1, 0, msg='转换服务器返回内容为列表失败') if type(response_to_check) != type([]): logger.info('服务器返回内容不为列表或列表的字符串表示') self.assertEqual(1, 0, msg='服务器返回内容不为列表或列表的字符串表示') # 遍历条件列表,形如 "条件":[{"模式":"[\"success\",\"shouke\",2016]", "消息":"创建储值卡支付订单失败,返回结果和列表模式不匹配"}] for item in self.expected_result['条件']: pattern_list = eval(item['模式']) logger.info('要匹配的模式(列表)为:%s' % pattern_list) self.assertListEqual(response_to_check, pattern_list, msg=item['消息']) elif self.expected_result['匹配规则'] == '完全匹配集合': if type(response_to_check) == type(''): # 字符串类型的集合 try: response_to_check = eval(response_to_check) except Exception as e: logger.error('转换服务器返回内容为集合失败') self.assertEqual(1, 0, msg='转换服务器返回内容为集合失败') if type(response_to_check) != type(set()): logger.error('服务器返回内容不为集合或集合的字符串表示') self.assertEqual(1, 0, msg='服务器返回内容不为集合或集合的字符串表示') # 遍历条件列表,形如 "条件":[{"模式":"[\"success\",\"shouke\",2016]", "消息":"创建储值卡支付订单失败,返回结果和列表模式不匹配"}] for item in self.expected_result['条件']: pattern_set = eval(item['模式']) logger.info('要匹配的模式(集合)为:%s' % pattern_set) self.assertSetEqual(response_to_check, pattern_set, msg=item['消息']) elif self.expected_result['匹配规则'] == '完全匹配元组': if type(response_to_check) == type(''): # 字符串类型的元组 try: response_to_check = eval(response_to_check) except Exception as e: logger.error('转换服务器返回内容为元组失败') self.assertEqual(1, 0, msg='转换服务器返回内容为元组失败') if type(response_to_check) != type(()): logger.error('服务器返回内容不为元组或元组的字符串表示') self.assertEqual(1, 0, msg='服务器返回内容不为元组或元组的字符串表示') # 遍历条件列表,形如 "条件":[{"模式":"[\"success\",\"shouke\",2016]", "消息":"创建储值卡支付订单失败,返回结果和列表模式不匹配"}] for item in self.expected_result['条件']: pattern_tuple = eval(item['模式']) logger.info('要匹配的模式(元组)为:%s' % str(pattern_tuple)) self.assertTupleEqual(response_to_check, pattern_tuple, msg=item['消息']) elif (self.expected_result['匹配规则']).lower() == 'xpath断言': try: root = ET.fromstring(response_to_check) except ET.ParseError as e: self.assertEqual(1, 0, '%s' % e) for item in self.expected_result['条件']: pattern_dic = item['模式'] logger.info('要检测的模式为:%s' % pattern_dic) for key in pattern_dic.keys(): if key == '.': content_to_check = root.text expect_value = pattern_dic[key] else: xmlnsnamespace_dic = {} # 存放 前缀:对应uri logger.info('正在获取xmlns定义') match_result_list = re.findall('xmlns[^:]?=(.+?)[ |\>|\\\>]', response_to_check, re.MULTILINE) if match_result_list: xmlns = match_result_list[len(match_result_list) - 1] xmlns = xmlns.strip(' ') xmlns = '{' + xmlns + '}' logger.info('xmlns定义为:%s' % xmlns) xmlnsnamespace_dic['xmlns'] = xmlns logger.info('正在获取"xmlns:xxx名称空间定义') match_result_list = re.findall('xmlns:(.+?)=(.+?)[ |>]', response_to_check) for ns in match_result_list: xmlnsnamespace_dic[ns[0]] = '{' + ns[1] + '}' logger.info("最后获取的prefix:uri为:%s" % xmlnsnamespace_dic) logger.info('正在转换元素结点前缀') key_copy = key for dic_key in xmlnsnamespace_dic.keys(): namespace = dic_key + ':' if namespace in key: uri = xmlnsnamespace_dic[dic_key] key = key.replace(namespace, uri) key = key.replace('"', '') logger.info('转换后用于查找元素的xpath:%s' % key) try: elements_list = root.findall(key) except Exception as e: logger.error('查找元素出错:%s' % e) self.assertEqual(1, 0, msg='%s' % e) logger.info('查找到的元素为:%s' % elements_list) logger.info('正在进行断言') if elements_list: content_to_check = elements_list[0].text else: content_to_check = '' expect_value = pattern_dic[key_copy] logger.info('从服务器返回的提取的待检查数据的类型:%s' % type(content_to_check)) logger.info('用户期望值的数据类型:%s' % type(expect_value)) self.assertEqual(content_to_check, expect_value, msg=item['消息'])
def extrator(self, extrator_type, extrator, response_to_check=''): if extrator_type == 'dic': # 获取键值 # 获取list方式标识的key,value层级值 dict_level_list = other_tools.get_dict_level_list(extrator) other_tools.set_dict_level_list([]) logger.info('要提取的字典key,value层级为:%s' % dict_level_list) if type(response_to_check) == type(''): # 字符串类型的字典、json串 try: response_to_check = json.loads(response_to_check) # //转字符串为json except Exception as e: logger.error('转换服务器返回内容为字典失败:%s' % e) return '' if type(response_to_check) != type({}): logger.error('服务器返回内容不为字典、字符串类型的字典') return '' value_get = other_tools.find_dict_last_leve_value(dict_level_list, response_to_check) logger.info('找到的对应字典层级的key的值为:%s' % value_get) other_tools.set_key_index(0) return value_get elif extrator_type == 're': # 获取正则表达式匹配的内容 if type(response_to_check) in [type({}), type(set()), type(()), type([]), type(1), type(0.01)]: response_to_check = str(response_to_check) elif type(response_to_check) != type(''): logger.error('服务器返回内容不为字符串类型') return [] result = re.findall(extrator, response_to_check) return result elif extrator_type == 'xpath': try: root = ET.fromstring(response_to_check) except ET.ParseError as e: logger.error('%s' % e) return '' logger.info('xpath表达式为:%s' % extrator) if extrator == '.': value_get = root.text else: xmlnsnamespace_dic = {} # 存放 前缀:对应uri logger.info('正在获取xmlns定义') match_result_list = re.findall('xmlns[^:]?=(.+?)[ |\>|\\\>]', response_to_check, re.MULTILINE) if match_result_list: xmlns = match_result_list[len(match_result_list) - 1] xmlns = xmlns.lstrip(' ') xmlns = '{' + xmlns + '}' logger.info('xmlns定义为:%s' % xmlns) xmlnsnamespace_dic['xmlns'] = xmlns logger.info('正在获取"xmlns:xxx名称空间定义') match_result_list = re.findall('xmlns:(.+?)=(.+?)[ |>]', response_to_check) for ns in match_result_list: xmlnsnamespace_dic[ns[0]] = '{' + ns[1] + '}' logger.info("最后获取的prefix:uri为:%s" % xmlnsnamespace_dic) logger.info('正在转换元素结点前缀') for dic_key in xmlnsnamespace_dic.keys(): namespace = dic_key + ':' if namespace in extrator: uri = xmlnsnamespace_dic[dic_key] extrator = extrator.replace(namespace, uri) extrator = extrator.replace('"', '') logger.info('转换后用于查找元素的xpath:%s' % extrator) try: elements_list = root.findall(extrator) except Exception as e: logger.error('查找xpath元素出错:%s' % e) value_get = '' logger.info('查找到的元素为:%s' % elements_list) if elements_list: value_get = elements_list[0].text else: value_get = '' return value_get else: logger.error('提取器填写错误') return None
def run_testcase(self, http, testplan): if 0 == self.active_status: logger.warning('用例[name=%s]处于禁用状态[active=0],不执行' % self.testcase_name) return ('Block', '用例处于禁用状态,不执行') protocol_all = http.get_protocol() host_all = http.get_host() port_all = http.get_port() for step in self.steps: # 构造测试步骤对象 step_id = int(step['id']) step_number = int(step['step_number']) step_action = other_tools.conver_date_from_testlink( step['actions']) logger.info('转换来自test_link 的step_action值为:%s' % step_action) expected_results = other_tools.conver_date_from_testlink( step['expected_results']) logger.info('转换来自test_link 的expected_results值为:%s' % expected_results) logger.debug('step_action: %s' % step_action) sql_insert = 'INSERT INTO '+ case_step_report_tb +'(executed_history_id, testcase_id, testcase_name, testplan, project, step_id, step_num, protocol_method, protocol, host, port, ' \ 'step_action, expected_results, runresult, reason, runtime)' \ ' VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)' if step_action.find('步骤类型') != -1 and step_action.find( '执行用例') != -1: # 待执行步骤为用例 data = (executed_history_id, self.testcase_id, self.testcase_name, testplan, self.testproject, step_id, step_number, '无', '无', '无', '无', step_action, expected_results, 'Block', '', '0000-00-00 00:00:00') logger.info('记录测试步骤到测试步骤报告表') testdb.execute_insert(sql_insert, data) elif step_action.find('步骤类型') != -1 and ( step_action.find('执行sql') != -1 or step_action.find('执行SQL') != -1): #: # 待执行步骤为sql data = (executed_history_id, self.testcase_id, self.testcase_name, testplan, self.testproject, step_id, step_number, '', '', testdb.get_host(), testdb.get_port(), step_action, expected_results, 'Block', '', '0000-00-00 00:00:00') logger.info('记录测试步骤到测试步骤报告表') testdb.execute_insert(sql_insert, data) elif step_action.find('步骤类型') == -1: # 待执行步骤为普通用例步骤 data = (executed_history_id, self.testcase_id, self.testcase_name, testplan, self.testproject, step_id, step_number, '', protocol_all, host_all, port_all, step_action, expected_results, 'Block', '', '0000-00-00 00:00:00') logger.info('记录测试步骤到测试步骤报告表') testdb.execute_insert(sql_insert, data) run_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) # 记录运行时间 try: step_action = json.loads(step_action, object_pairs_hook=OrderedDict) if '步骤类型' not in step_action: protocol_method = step_action['方法'] else: protocol_method = '无' if expected_results != '': expected_results = json.loads(expected_results) step_obj = CaseStep(step_id, step_number, expected_results, step_action, self.testcase_id) except Exception as e: logger.error( '步骤[%s]信息填写错误: %s,停止执行用例[id=%s, name=%s]' % (step_number, e, self.testcase_id, self.testcase_name)) sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\"' \ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s' \ ' AND project=\'%s\' AND testplan=\'%s\'' data = ('Block', '%s' % e, protocol_method, run_time, str(executed_history_id), self.testcase_id, step_id, self.testproject, testplan) logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update, data) return ('Error', [ ('TestCase', '步骤[%s]信息填写错误: %s,停止执行用例[id=%s, name=%s]' % (step_number, e, self.testcase_id, self.testcase_name)) ]) logger.info('开始执行步骤操作[第%s步]' % step_number) run_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) # 记录运行时间 if '步骤类型' in step_action: if step_action['步骤类型'] == '执行用例': step_run_result = globalpkg.global_function.run_testcase_by_id( step_action['用例id'], testplan) else: step_run_result = step_obj.run_step() # 运行sql,或者是普通用例步骤 else: step_run_result = step_obj.run_step(http) # 运行普通用例步骤 try: # 转换 “ 为 ‘ ,防止数据库存储出错 action_of_step = step_obj.get_action() if type(action_of_step) == type(b''): action_of_step = action_of_step.decode('utf-8') elif type(action_of_step) == type({}): action_of_step = str(action_of_step) action_of_step = json.dumps(action_of_step) action_of_step = action_of_step.replace('"', "'") result_of_step = step_obj.get_expected_result() if type(result_of_step) == type(b''): result_of_step = result_of_step.decode('utf-8') elif type(result_of_step) == type({}): result_of_step = str(result_of_step) result_of_step = result_of_step.replace('"', "'") # except Exception as e: # logger.error('获取step action、expected_result出错 %s' % e) # action_of_step = '' # result_of_step = '' finally: if step_run_result[0] == 'Error': fail_or_error_reason = step_run_result[1][0][1] fail_or_error_reason = fail_or_error_reason.replace( '\n', '') fail_or_error_reason = fail_or_error_reason.replace( '\"', '') fail_or_error_reason = fail_or_error_reason.replace( '\'', '') logger.error( '步骤[%s]执行出错,停止执行用例[id=%s, name=%s]' % (step_number, self.testcase_id, self.testcase_name)) sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\",' \ 'step_action=\"%s\", expected_results=\"%s\"' \ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s' \ ' AND project=\'%s\' AND testplan=\'%s\'' data = (step_run_result[0], fail_or_error_reason, protocol_method, run_time, action_of_step, result_of_step, str(executed_history_id), self.testcase_id, step_id, self.testproject, testplan) logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update, data) return step_run_result elif step_run_result[0] == 'Fail': fail_or_error_reason = step_run_result[1][0][1] fail_or_error_reason = fail_or_error_reason.replace( '\n', '') fail_or_error_reason = fail_or_error_reason.replace( '\"', '') fail_or_error_reason = fail_or_error_reason.replace( '\'', '') logger.info( '步骤[%s]执行失败,停止执行用例[id=%s, name=%s]' % (step_number, self.testcase_id, self.testcase_name)) sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\",' \ 'step_action=\"%s\", expected_results=\"%s\"' \ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s' \ ' AND project=\'%s\' AND testplan=\'%s\'' data = (step_run_result[0], fail_or_error_reason, protocol_method, run_time, action_of_step, result_of_step, str(executed_history_id), self.testcase_id, step_id, self.testproject, testplan) logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update, data) return step_run_result elif step_run_result[0] == 'Block': fail_or_error_reason = step_run_result[1] logger.info( '步骤[%s]执行失败,停止执行用例[id=%s, name=%s]' % (step_number, self.testcase_id, self.testcase_name)) sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\"' \ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s' \ ' AND project=\'%s\' AND testplan=\'%s\'' data = (step_run_result[0], fail_or_error_reason, '无', run_time, str(executed_history_id), self.testcase_id, step_id, self.testproject, testplan) logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update, data) return step_run_result else: fail_or_error_reason = '' sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\",' \ 'step_action=\"%s\", expected_results=\"%s\"'\ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s'\ ' AND project=\'%s\' AND testplan=\'%s\'' data = (step_run_result[0], fail_or_error_reason, protocol_method, run_time, action_of_step, result_of_step, str(executed_history_id), self.testcase_id, step_id, self.testproject, testplan) logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update, data) logger.info('测试用例[id=%s, name=%s]执行成功' % (self.testcase_id, self.testcase_name)) return ('Pass', '')
def assert_result(self, response_to_check): if self.expected_result != '': if self.expected_result['匹配规则'] == '包含成员': if type(response_to_check) not in [ type(''), type([]), type(()), type(set()), type({}) ]: logger.error('服务器返回内容为不可迭代对象') self.assertEqual(1, 0, msg='服务器返回内容为不可迭代对象') # 遍历条件列表, 形如 "条件":[{"模式":"\"success\"", "消息":"创建储值卡支付订单失败,返回json串不包含key - success"},{"模式":"\"attach\"", "消息":"创建储值卡支付订单失败,返回json串不包含key - attach"}] for item in self.expected_result['条件']: member = item['模式'] logger.info('要匹配的模式(成员)为:%s' % member) self.assertIn(member, response_to_check, msg=item['消息']) elif self.expected_result['匹配规则'] == '不包含成员': if type(response_to_check) not in [ type(''), type([]), type(()), type(set()), type({}) ]: logger.error('服务器返回内容为不可迭代对象') self.assertEqual(1, 0, msg='服务器返回内容为不可迭代对象') # 遍历条件列表,形如 "条件":[{"模式":"\"success\"", "消息":"创建储值卡支付订单失败,返回json串包含key - success"},{"模式":"\"attach\"", "消息":"创建储值卡支付订单失败,返回json串包含key - attach"}] for item in self.expected_result['条件']: member = item['模式'] logger.info('要匹配的模式(成员)为:%s' % member) self.assertNotIn(member, response_to_check, msg=item['消息']) elif self.expected_result['匹配规则'] == '包含字符串': if type(response_to_check) in [ type({}), type(set()), type(()), type([]), type(1), type(0.01) ]: response_to_check = str(response_to_check) elif type(response_to_check) != type(''): logger.error('服务器返回内容不为字符串类型') self.assertEqual(1, 0, msg='服务器返回内容不为字符串类型') # 遍历条件列表, 形如:"条件":[{"模式":"\"success\":true", "消息":"创建储值卡支付订单失败,success不为True"},{"模式":"\"success\":false", "消息":"创建储值卡支付订单失败,success不为false"}] for item in self.expected_result['条件']: pattern_str = item['模式'] logger.info('要匹配的模式(子字符串)为:%s' % pattern_str) self.assertIn(pattern_str, response_to_check, item['消息']) elif self.expected_result['匹配规则'] == '不包含字符串': if type(response_to_check) in [ type({}), type(set()), type(()), type([]), type(1), type(0.01) ]: response_to_check = str(response_to_check) elif type(response_to_check) != type(''): logger.error('服务器返回内容不为字符串类型') self.assertEqual(1, 0, msg='服务器返回内容不为字符串类型') # 遍历条件列表, 形如:"条件":[{"模式":"\"success\":true", "消息":"创建储值卡支付订单失败,success不为True"},{"模式":"\"success\":false", "消息":"创建储值卡支付订单失败,success不为false"}] for item in self.expected_result['条件']: pattern_str = item['模式'] logger.info('要匹配的模式(子字符串)为:%s' % pattern_str) self.assertNotIn(pattern_str, response_to_check, item['消息']) elif self.expected_result['匹配规则'] == '键值相等': if type(response_to_check) == type(''): # 字符串类型的字典、json串 try: response_to_check = json.loads( response_to_check) # //转字符串为json except Exception as e: logger.error('转换服务器返回内容为字典失败') self.assertEqual(1, 0, msg='转换服务器返回内容为字典失败') if type(response_to_check) == type([]): # 格式[{}]的json串 try: response_to_check = response_to_check[0] response_to_check = json.loads( response_to_check) # //转字符串为json except Exception as e: logger.error('转换服务器返回内容为字典失败') self.assertEqual(1, 0, msg='转换服务器返回内容为字典失败') if type(response_to_check) != type({}): logger.error('服务器返回内容不为字典、字符串类型的字典') self.assertEqual(1, 0, msg='服务器返回内容不为字典、字符串类型的字典') # 遍历条件列表, 形如:"条件":[{"模式":{"success":true}, "消息":"创建储值卡支付订单失败,success不为True"},{"模式":{"success":false}, "消息":"创建储值卡支付订单失败,success不为false"}] for item in self.expected_result['条件']: pattern_dic = item['模式'] # 获取list方式标识的key,value层级值 dict_level_list = other_tools.get_dict_level_list( pattern_dic) other_tools.set_dict_level_list([]) logger.info('要匹配的字典key,value层级为:%s' % dict_level_list) last_value = other_tools.find_dict_last_leve_value( dict_level_list, response_to_check) logger.info('找到的对应字典层级的最后值为:%s' % last_value) other_tools.set_key_index(0) # 比较同层级,相同key对应的value值 self.assertEqual(dict_level_list[len(dict_level_list) - 1], last_value, item['消息']) elif self.expected_result['匹配规则'] == '匹配正则表达式': if type(response_to_check) in [ type({}), type(set()), type(()), type([]), type(1), type(0.01) ]: response_to_check = str(response_to_check) elif type(response_to_check) != type(''): logger.error('服务器返回内容不为字符串类型') self.assertEqual(1, 0, msg='服务器返回内容不为字符串类型') # 遍历条件列表, 形如( "条件":[{"模式":"\"success\":true", "消息":"创建储值卡支付订单失败,success不为True"},{"模式":"\"success\":false", "消息":"创建储值卡支付订单失败,success不为false"}] for item in self.expected_result['条件']: pattern_str = item['模式'] logger.info('要匹配的模式(正则表达式)为:%s' % pattern_str) self.assertRegex(response_to_check, pattern_str, msg=item['消息']) elif self.expected_result['匹配规则'] == '不匹配正则表达式': if type(response_to_check) in [ type({}), type(set()), type(()), type([]), type(1), type(0.01) ]: response_to_check = str(response_to_check) elif type(response_to_check) != type(''): logger.error('服务器返回内容不为字符串类型') self.assertEqual(1, 0, msg='服务器返回内容不为字符串类型') # 遍历条件列表,形如 "条件":[{"模式":"\"success\":true", "消息":"创建储值卡支付订单失败,success为True"},{"模式":"\"success\":false", "消息":"创建储值卡支付订单失败,success为false"}] for item in self.expected_result['条件']: pattern_str = item['模式'] logger.info('要匹配的模式(正则表达式)为:%s' % pattern_str) self.assertNotRegex(response_to_check, pattern_str, msg=item['消息']) elif self.expected_result['匹配规则'] == '完全匹配字典': if type(response_to_check) == type(''): # 字符串类型的字典、json串 try: response_to_check = json.loads( response_to_check) # //转字符串为json except Exception as e: logger.info('转换服务器返回内容为字典失败') self.assertEqual(1, 0, msg='转换服务器返回内容为字典失败') elif type(response_to_check) != type({}): logger.error('服务器返回内容不为字典') self.assertEqual(1, 0, msg='服务器返回内容不为字典') # 遍历条件列表 "条件":[{"模式":{"success":true}, "消息":"创建储值卡支付订单失败,返回结果和字典模式不匹配"}] for item in self.expected_result['条件']: pattern_dic = item['模式'] logger.info('要匹配的模式(字典)为:%s' % pattern_dic) self.assertDictEqual(response_to_check, pattern_dic, msg=item['消息']) elif self.expected_result['匹配规则'] == '完全匹配列表': if type(response_to_check) == type(''): # 字符串类型的列表 try: response_to_check = eval(response_to_check) except Exception as e: logger.info('转换服务器返回内容为列表失败') self.assertEqual(1, 0, msg='转换服务器返回内容为列表失败') if type(response_to_check) != type([]): logger.info('服务器返回内容不为列表或列表的字符串表示') self.assertEqual(1, 0, msg='服务器返回内容不为列表或列表的字符串表示') # 遍历条件列表,形如 "条件":[{"模式":"[\"success\",\"shouke\",2016]", "消息":"创建储值卡支付订单失败,返回结果和列表模式不匹配"}] for item in self.expected_result['条件']: pattern_list = eval(item['模式']) logger.info('要匹配的模式(列表)为:%s' % pattern_list) self.assertListEqual(response_to_check, pattern_list, msg=item['消息']) elif self.expected_result['匹配规则'] == '完全匹配集合': if type(response_to_check) == type(''): # 字符串类型的集合 try: response_to_check = eval(response_to_check) except Exception as e: logger.error('转换服务器返回内容为集合失败') self.assertEqual(1, 0, msg='转换服务器返回内容为集合失败') if type(response_to_check) != type(set()): logger.error('服务器返回内容不为集合或集合的字符串表示') self.assertEqual(1, 0, msg='服务器返回内容不为集合或集合的字符串表示') # 遍历条件列表,形如 "条件":[{"模式":"[\"success\",\"shouke\",2016]", "消息":"创建储值卡支付订单失败,返回结果和列表模式不匹配"}] for item in self.expected_result['条件']: pattern_set = eval(item['模式']) logger.info('要匹配的模式(集合)为:%s' % pattern_set) self.assertSetEqual(response_to_check, pattern_set, msg=item['消息']) elif self.expected_result['匹配规则'] == '完全匹配元组': if type(response_to_check) == type(''): # 字符串类型的元组 try: response_to_check = eval(response_to_check) except Exception as e: logger.error('转换服务器返回内容为元组失败') self.assertEqual(1, 0, msg='转换服务器返回内容为元组失败') if type(response_to_check) != type(()): logger.error('服务器返回内容不为元组或元组的字符串表示') self.assertEqual(1, 0, msg='服务器返回内容不为元组或元组的字符串表示') # 遍历条件列表,形如 "条件":[{"模式":"[\"success\",\"shouke\",2016]", "消息":"创建储值卡支付订单失败,返回结果和列表模式不匹配"}] for item in self.expected_result['条件']: pattern_tuple = eval(item['模式']) logger.info('要匹配的模式(元组)为:%s' % str(pattern_tuple)) self.assertTupleEqual(response_to_check, pattern_tuple, msg=item['消息'])
def run_testcase(self, http, testplan, case_executed_history_id): if 0 == self.active_status: logger.warning('用例[name=%s]处于禁用状态[active=0],不执行' % self.testcase_name) return ('Block', '用例处于禁用状态,不执行') if self.preconditions.find('使用上级配置') != -1: logger.info('用例[name=%s]使用上级套件的ip配置' % self.testcase_name) logger.info('正在读取用例[name=%s]所在套件的协议,host,端口配置...' % self.testcase_name) testsuite_info = mytestlink.getTestSuiteByID( self.testsuite_id) # 获取套件基本信息 testsuite_conf = other_tools.conver_date_from_testlink( testsuite_info['details']) testsuite_name = testsuite_info['name'] testsuite_id = testsuite_info['id'] testsuite_id_name = str(testsuite_id) + testsuite_name if testsuite_id_name in TestCase.testsuite_config.keys(): # 已存在配置 logger.info('检测到系统已保存用例[name=%s]所在套件[name=%s]配置,使用现有配置' % (testsuite_name, self.testcase_name)) http = TestCase.testsuite_config[testsuite_id_name] protocol = http.get_protocol() host = http.get_host() port = http.get_port() else: try: details = json.loads(testsuite_conf) protocol = details['protocol'] host = details['host'] port = details['port'] # 构造http对象 http = MyHttp(protocol, host, port) TestCase.testsuite_config[testsuite_id_name] = http except Exception as e: logger.error( '用例[name=%s]所在套件[name=%s]的协议,host,端口配置错误,未执行:%s' % (testsuite_name, self.testcase_name, e)) return ('Block', [ ('TestCase', '用例[name=%s]所在套件[name=%s]的协议,host,端口配置错误,未执行:%s' % (testsuite_name, self.testcase_name, e)) ]) else: # 使用统一的项目配置 protocol = http.get_protocol() host = http.get_host() port = http.get_port() for step in self.steps: # 构造测试步骤对象 step_id = int(step['id']) step_number = int(step['step_number']) step_action = other_tools.conver_date_from_testlink( step['actions']) logger.info('转换来自test_link 的step_action值为:%s' % step_action) expected_results = other_tools.conver_date_from_testlink( step['expected_results']) logger.info('转换来自test_link 的expected_results值为:%s' % expected_results) logger.debug('step_action: %s' % step_action) sql_insert = 'INSERT INTO '+ case_step_report_tb +'(executed_history_id, testcase_id, testcase_name, testplan, project, step_id, step_num, protocol_method, protocol, host, port, ' \ 'step_action, expected_results, runresult, reason, runtime)' \ ' VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)' if step_action.find('步骤类型') != -1 and step_action.find( '执行用例') != -1: # 待执行步骤为用例 data = (case_executed_history_id, self.testcase_id, self.testcase_name, testplan, self.testproject, step_id, step_number, '无', '无', '无', '无', step_action, expected_results, 'Block', '', '0000-00-00 00:00:00') logger.info('记录测试步骤到测试步骤报告表') testdb.execute_insert(sql_insert, data) elif step_action.find('步骤类型') != -1 and ( step_action.find('执行sql') != -1 or step_action.find('执行SQL') != -1): #: # 待执行步骤为sql data = (case_executed_history_id, self.testcase_id, self.testcase_name, testplan, self.testproject, step_id, step_number, '', '', testdb.get_host(), testdb.get_port(), step_action, expected_results, 'Block', '', '0000-00-00 00:00:00') logger.info('记录测试步骤到测试步骤报告表') testdb.execute_insert(sql_insert, data) elif step_action.find('步骤类型') == -1: # 待执行步骤为普通用例步骤 data = (case_executed_history_id, self.testcase_id, self.testcase_name, testplan, self.testproject, step_id, step_number, '', protocol, host, port, step_action, expected_results, 'Block', '', '0000-00-00 00:00:00') logger.info('记录测试步骤到测试步骤报告表') testdb.execute_insert(sql_insert, data) run_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) # 记录运行时间 try: ifgot_protocol_method = 0 step_action = json.loads(step_action, object_pairs_hook=OrderedDict) if '步骤类型' not in step_action: protocol_method = step_action['方法'] else: protocol_method = '无' ifgot_protocol_method = 1 if expected_results != '': expected_results = json.loads(expected_results) step_obj = CaseStep(step_id, step_number, expected_results, step_action, self.testcase_id) except Exception as e: logger.error( '步骤[%s]信息填写错误: %s,停止执行用例[id=%s, name=%s]' % (step_number, e, self.testcase_id, self.testcase_name)) sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\"' \ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s' \ ' AND project=\'%s\' AND testplan=\'%s\'' if ifgot_protocol_method == 0: protocol_method = '未获取到' data = ('Block', '%s' % e, protocol_method, run_time, str(case_executed_history_id), self.testcase_id, step_id, self.testproject, testplan) logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update, data) return ('Error', [ ('TestCase', '步骤[%s]信息填写错误: %s,停止执行用例[id=%s, name=%s]' % (step_number, e, self.testcase_id, self.testcase_name)) ]) logger.info('开始执行步骤操作[第%s步]' % step_number) run_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) # 记录运行时间 if '步骤类型' in step_action: if step_action['步骤类型'] == '执行用例': step_run_result = globalpkg.global_function.run_testcase_by_id( step_action['用例id'], None, testplan) else: step_run_result = step_obj.run_step() # 运行sql,或者是普通用例步骤 else: step_run_result = step_obj.run_step(http) # 运行普通用例步骤 try: # 转换 “ 为 ‘ ,防止数据库存储出错 action_of_step = step_obj.get_action() if type(action_of_step) == type(b''): action_of_step = action_of_step.decode('utf-8') elif type(action_of_step) == type({}): action_of_step = str(action_of_step) action_of_step = json.dumps(action_of_step, ensure_ascii=False) action_of_step = action_of_step.replace('"', "'") result_of_step = step_obj.get_expected_result() if type(result_of_step) == type(b''): result_of_step = result_of_step.decode('utf-8') elif type(result_of_step) == type({}): result_of_step = str(result_of_step) result_of_step = result_of_step.replace('"', "'") # except Exception as e: # logger.error('获取step action、expected_result出错 %s' % e) # action_of_step = '' # result_of_step = '' finally: if step_run_result[0] == 'Error': fail_or_error_reason = step_run_result[1][0][1] fail_or_error_reason = fail_or_error_reason.replace( '\n', '') fail_or_error_reason = fail_or_error_reason.replace( '\"', '') fail_or_error_reason = fail_or_error_reason.replace( '\'', '') logger.error( '步骤[%s]执行出错,停止执行用例[id=%s, name=%s]' % (step_number, self.testcase_id, self.testcase_name)) sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\",' \ 'step_action=\"%s\", expected_results=\"%s\"' \ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s' \ ' AND project=\'%s\' AND testplan=\'%s\' AND runtime=\'%s\' ' data = (step_run_result[0], fail_or_error_reason, protocol_method, run_time, action_of_step, result_of_step, str(case_executed_history_id), self.testcase_id, step_id, self.testproject, testplan, '0000-00-00 00:00:00') logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update, data) return step_run_result elif step_run_result[0] == 'Fail': fail_or_error_reason = step_run_result[1][0][1] fail_or_error_reason = fail_or_error_reason.replace( '\n', '') fail_or_error_reason = fail_or_error_reason.replace( '\"', '') fail_or_error_reason = fail_or_error_reason.replace( '\'', '') logger.info( '步骤[%s]执行失败,停止执行用例[id=%s, name=%s]' % (step_number, self.testcase_id, self.testcase_name)) sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\",' \ 'step_action=\"%s\", expected_results=\"%s\"' \ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s' \ ' AND project=\'%s\' AND testplan=\'%s\' AND runtime=\'%s\'' data = (step_run_result[0], fail_or_error_reason, protocol_method, run_time, action_of_step, result_of_step, str(case_executed_history_id), self.testcase_id, step_id, self.testproject, testplan, '0000-00-00 00:00:00') logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update, data) return step_run_result elif step_run_result[0] == 'Block': fail_or_error_reason = step_run_result[1] logger.info( '步骤[%s]执行失败,停止执行用例[id=%s, name=%s]' % (step_number, self.testcase_id, self.testcase_name)) sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\"' \ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s' \ ' AND project=\'%s\' AND testplan=\'%s\' AND runtime=\'%s\'' data = (step_run_result[0], fail_or_error_reason, '无', run_time, str(case_executed_history_id), self.testcase_id, step_id, self.testproject, testplan, '0000-00-00 00:00:00') logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update, data) return step_run_result else: fail_or_error_reason = '' sql_update = 'UPDATE '+ case_step_report_tb +' SET runresult=\"%s\",reason=\"%s\", protocol_method=\"%s\", runtime=\"%s\",' \ 'step_action=\"%s\", expected_results=\"%s\"'\ ' WHERE executed_history_id = %s AND testcase_id = %s AND step_id = %s'\ ' AND project=\'%s\' AND testplan=\'%s\' AND runtime=\'%s\'' data = (step_run_result[0], fail_or_error_reason, protocol_method, run_time, action_of_step, result_of_step, str(case_executed_history_id), self.testcase_id, step_id, self.testproject, testplan, '0000-00-00 00:00:00') logger.info('正在更新步骤执行结果') testdb.execute_update(sql_update, data) logger.info('测试用例[id=%s, name=%s]执行成功' % (self.testcase_id, self.testcase_name)) return ('Pass', '')
logger.info('运行所有项目') projects = mytestlink.getProjects() for project in projects: # 构造项目对象 active_status = project['active'] project_name = project['name'] project_notes = other_tools.conver_date_from_testlink(project['notes']) project_id = int(project['id']) project_obj = TestProject(active_status, project_name, project_notes, project_id) logger.info('正在读取测项目[id:%s, project:%s]的协议,host,端口配置...' % (project_id, project_name)) testproject_conf = project_notes logger.info('成功读取配置信息:%s' % testproject_conf) if '' == testproject_conf: logger.error('测试项目[id:%s, project:%s]未配置协议,host,端口信息,暂时无法执行' % (project_id, project_name)) continue try: notes = json.loads(testproject_conf) protocol = notes['protocol'] host = notes['host'] port = notes['port'] except Exception as e: logger.error('测试项目[id:%s, project:%s]协议,host,端口信息配置错误,暂时无法执行:%s' % (project_id, project_name, e)) continue # 构造http对象 myhttp = MyHttp(protocol, host, port) logger.info('正在执行测试项目[id:%s, project:%s]' % (project_id, project_name))
myhttp = get_http_conf_of_project(project_name) if not myhttp: logger.critical('项目配置存在问题,已被忽略,不执行') continue logger.info('正在执行测试项目[id:%s, project:%s]' % (project_id, project_name)) project_obj.run_testproject(myhttp) elif 2 == project_mode: logger.info('运行指定项目') testprojects_name_list = eval(run_mode_conf.get_projects()) for testproject_name in testprojects_name_list: try: testproject = mytestlink.getTestProjectByName( testproject_name) except Exception as e: logger.error('测试项目[project:%s]获取失败,暂时无法执行:%s' % (testproject_name, e)) continue # 构造项目对象 active_status = testproject['active'] project_name = testproject['name'] project_notes = other_tools.conver_date_from_testlink( testproject['notes']) project_id = int(testproject['id']) project_obj = TestProject(active_status, project_name, project_notes, project_id) # 构造http对象 if project_name in project_httpobj_dict.keys(): myhttp = project_httpobj_dict[project_name] else:
def run_testcase_by_id(testcase_id, testplan='无计划'): try: testcase_info = mytestlink.getTestCase(testcase_id) # 获取测试用例基本信息 logger.info('获取测试用例信息 %s' % testcase_info) except Exception as e: logger.error('获取用例信息失败 %s,,暂停执行该用例' % e) return ('Fail', [('global_funtion_module', '获取用例信息失败 %s' % e)]) # 获取用例所在套件和项目名称 response = mytestlink.getFullPath([int(testcase_id)]) response = response[str(testcase_id)] testsuite_name = '' for suit in response[1:]: testsuite_name = testsuite_name + '-' + suit testsuite_name = testsuite_name.lstrip('-') project_name = response[0] # 构造测试用例对象 testcase_name = testcase_info[0]['name'] testcase_steps = testcase_info[0]['steps'] testcase_isactive = int(testcase_info[0]['active']) testcase_obj = TestCase(testcase_id, testcase_name, testcase_steps, testcase_isactive, project_name) testsuite_id = int(testcase_info[0]['testsuite_id']) logger.info('正在读取套件[id=%s]的协议,host,端口配置...' % (testsuite_id)) testsuite_info = mytestlink.getTestSuiteByID(testsuite_id) testsuite_name = testsuite_info['name'] testsuite_details = other_tools.conver_date_from_testlink( testsuite_info['details']) project = mytestlink.getFullPath(testsuite_id) project = project[str(testsuite_id)][0] testsuite_obj = TestSuite(testsuite_id, testsuite_name, testsuite_details, project) testsuite_conf = testsuite_obj.get_testsuite_conf() # 获取套件基本信息 if '' == testsuite_conf: logger.error('测试套件[id=%s ,name=%s]未配置协议,host,端口信息,暂时无法执行' % (testsuite_id, testsuite_name)) return ('Fail', [('golbal_function_module', '测试套件[id=%s ,name=%s]未配置协议,host,端口信息,暂时无法执行' % (testsuite_id, testsuite_name))]) try: details = json.loads(testsuite_conf) protocol = details['protocol'] host = details['host'] port = details['port'] except Exception as e: logger.error('测试套件[id=%s ,name=%s]协议,host,端口信息配置错误,未执行:%s' % (testsuite_id, testsuite_name, e)) return ('Fail', [('golbal_function_module', '测试套件[id=%s ,name=%s]协议,host,端口信息配置错误,未执行:%s' % (testsuite_id, testsuite_name, e))]) # 构造http对象 myhttp = MyHttp(protocol, host, port) try: sql_insert = 'INSERT INTO '+testcase_report_tb +'(executed_history_id, testcase_id, testcase_name, testsuit, testplan, project, runresult, runtime)' \ ' VALUES(%s, %s, %s, %s, %s, %s, %s, %s)' data = (executed_history_id, testcase_id, testcase_name, testsuite_name, testplan, project_name, 'Block', '0000-00-00 00:00:00') logger.info('记录测试用例到测试用例报表') testdb.execute_insert(sql_insert, data) logger.info('开始执行测试用例[id=%s,name=%s]' % (testcase_id, testcase_name)) run_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) # 记录运行时间 testcase_run_result = testcase_obj.run_testcase(myhttp, testplan) logger.info('正在更新用例执行结果') sql_update = 'UPDATE '+testcase_report_tb +' SET runresult=\"%s\", runtime=\"%s\"' \ ' WHERE executed_history_id = %s and testcase_id = %s' \ ' AND project=\'%s\' AND testplan=\'%s\'' data = (testcase_run_result[0], run_time, executed_history_id, testcase_id, project_name, testplan) testdb.execute_update(sql_update, data) logger.info('指定用例[%s]已执行完' % testcase_id) return testcase_run_result except Exception as e: logger.error('运行用例出错 %s' % e) return ('Fail', [('golbal_function_module', '%s' % e)])