def get(self, element, flag=False): ele = element.split('#') # #号后面的值,即用户输入的变量 _v = [] # 支持多个变量替代,但是顺序要对应 if len(ele) >= 2: _el = ele[0] + '#' _v = ele[1:] else: _el = element el = self.elements.get(_el, '') if not el: if flag: return _el, '' return _el, element.split('#', 1)[-1] value = el['value'] for v in _v: v = '#' if v == '^' else v # 当 value 中的 # 无需替换时,用例中的元素使用 ^ 表示 value = value.replace('#', v, 1) return el, replace(value)
def run(self): logger.info('Run the TestCase: %s|%s' % (self.testcase['id'], self.testcase['title'])) self.testcase['result'] = 'Pass' self.testcase['report'] = '' if_result = '' for index, step in enumerate(self.testcase['steps']): # if 为否,不执行 then 语句 if step['control'] == '>' and not if_result: step['score'] = '-' continue # if 为真,不执行 else 语句 if step['control'] == '<' and if_result: step['score'] = '-' continue logger.info('Run the Step: %s|%s|%s' % (step['no'], step['keyword'], step['element'])) step['page'], step['custom'], step['element'] = elements_format( step['page'], step['element']) try: # 变量替换 replace_dict(step['data']) replace_dict(step['expected']) if isinstance(step['element'], str): step['element'] = replace(step['element']) elif isinstance(step['element'], list): for i in range(len(step['element'])): step['element'][i] = replace(step['element'][i]) step['vdata'] = v_data(step['data']) # 处理强制等待时间 t = step['data'].get('等待时间') if t: del step['data']['等待时间'] sleep(float(t)) if g.platform.lower() in ( 'desktop', ) and step['keyword'] in web_keywords: if step['keyword'] not in ('MESSAGE', '对话框'): # 判断页面是否已和窗口做了关联,如果没有,就关联当前窗口,如果已关联,则判断是否需要切换 w.switch_window(step['page']) # 切换 frame 处理,支持变量替换 frame = replace(step['custom']) w.switch_frame(frame) # 根据关键字调用关键字实现 getattr(web, step['keyword'].lower())(step) elif g.platform.lower() in ( 'ios', 'android') and step['keyword'] in mobile_keywords: # 切換 context 處理 context = replace(step['custom']).strip() current_context = w.switch_context(context) if w.current_context.startswith('WEBVIEW'): # 切换标签页 tab = step['data'].get('标签页') if tab: del step['data']['标签页'] g.driver.switch_to_window(w.windows[tab]) logger.info('Current Context: %s' % repr(w.current_context)) # 根据关键字调用关键字实现 getattr(mobile, step['keyword'].lower())(step) elif step['keyword'] in http_keywords: # 根据关键字调用关键字实现 getattr(http, step['keyword'].lower())(step) elif step['keyword'].lower() == 'execute': if step['page'] in ('SNIPPET', '用例片段'): result, steps = getattr(common, step['keyword'].lower())(step) self.testcase['result'] = result self.snippet_steps[index + 1] = steps if result != 'Pass': break # elif step['page'] in ('SCRIPT', '脚本'): # # 判断页面是否已和窗口做了关联,如果没有,就关联当前窗口,如果已关联,则判断是否需要切换 # w.switch_window(step['page']) # # 切换 frame 处理,支持变量替换 # frame = replace(step['custom']) # w.switch_frame(frame) # common.script(step) else: # 根据关键字调用关键字实现 getattr(common, step['keyword'].lower())(step) logger.info('Run the Step: %s|%s|%s is Pass' % (step['no'], step['keyword'], step['element'])) step['score'] = 'OK' # if 语句结果赋值 if step['control'] == '^': if_result = True # 操作后,等待0.2秒 sleep(0.2) except Exception as exception: file_name = g.project_name + '-' + g.sheet_name + g.start_time + \ '#' + self.testcase['id'] + \ '-' + str(step['no']) + '.png' snapshot_file = Path('snapshot') / file_name if g.platform.lower() in ( 'desktop', ) and step['keyword'] in web_keywords: try: g.driver.get_screenshot_as_file(snapshot_file) except: logger.exception('*** save the screenshot is fail ***') elif g.platform.lower() in ( 'ios', 'android') and step['keyword'] in mobile_keywords: try: g.driver.switch_to_default_content() w.current_context = 'NATIVE_APP' g.driver.get_screenshot_as_file(snapshot_file) except: logger.exception('*** save the screenshot is fail ***') logger.exception( 'Run the Step: %s|%s|%s is Failure' % (step['no'], step['keyword'], step['element'])) step['score'] = 'NO' # if 语句结果赋值 if step['control'] == '^': if_result = False continue self.testcase['result'] = 'Fail' self.testcase['report'] = 'step-%s|%s|%s: %s' % ( step['no'], step['keyword'], step['element'], exception) step['remark'] += str(exception) break steps = [] i = 0 for k in self.snippet_steps: steps += self.testcase['steps'][i:k] + self.snippet_steps[k] i = k steps += self.testcase['steps'][i:] self.testcase['steps'] = steps
def run(self): logger.info('Run the TestCase: %s|%s' % (self.testcase['id'], self.testcase['title'])) self.testcase['result'] = 'Pass' self.testcase['report'] = '' if_result = '' for index, step in enumerate(self.testcase['steps']): # if 为否,不执行 then 语句 if step['control'] == '>' and not if_result: step['score'] = '-' continue # if 为真,不执行 else 语句 if step['control'] == '<' and if_result: step['score'] = '-' continue logger.info('Run the Step: %s|%s|%s' % (step['no'], step['keyword'], step['element'])) step['page'], step['custom'], step['element'] = elements_format( step['page'], step['element']) try: # 变量替换 replace_dict(step['data']) replace_dict(step['expected']) step['element'] = replace(step['element']) step['vdata'] = v_data(step['data']) # 处理强制等待时间 t = step['data'].get('等待时间') if t: del step['data']['等待时间'] sleep(int(t)) if g.platform.lower() in ('desktop',) and step['keyword'] in web_keywords: # 判断页面是否已和窗口做了关联,如果没有,就关联当前窗口,如果已关联,则判断是否需要切换 w.switch_window(step['page']) # 切换 frame 处理,支持变量替换 frame = replace(step['custom']) w.switch_frame(frame) # 根据关键字调用关键字实现 getattr(web, step['keyword'].lower())(step) elif g.platform.lower() in ('ios', 'android') and step['keyword'] in mobile_keywords: # 根据关键字调用关键字实现 getattr(mobile, step['keyword'].lower())(step) elif step['keyword'] in http_keywords: # 根据关键字调用关键字实现 getattr(http, step['keyword'].lower())(step) elif step['keyword'].lower() == 'execute': result, steps = getattr(common, step['keyword'].lower())(step) self.testcase['result'] = result self.snippet_steps[index+1] = steps if result != 'Pass': break else: # 根据关键字调用关键字实现 getattr(common, step['keyword'].lower())(step) logger.info('Run the Step: %s|%s|%s is Pass' % (step['no'], step['keyword'], step['element'])) step['score'] = 'OK' # if 语句结果赋值 if step['control'] == '^': if_result = True # 操作后,等待0.2秒 sleep(0.2) except Exception as exception: if g.platform.lower() in ('desktop',) and step['keyword'] in web_keywords: file_name = g.project_name + '-' + g.sheet_name + g.start_time + \ '#' + self.testcase['id'] + '-' + str(step['no']) + '.png' snapshot_file = path.join('snapshot', file_name) try: g.driver.get_screenshot_as_file(snapshot_file) except: logger.exception('*** save the screenshot is fail ***') logger.exception('Run the Step: %s|%s|%s is Failure' % (step['no'], step['keyword'], step['element'])) step['score'] = 'NO' # if 语句结果赋值 if step['control'] == '^': if_result = False continue self.testcase['result'] = 'Fail' self.testcase['report'] = 'step-%s|%s|%s: %s' % ( step['no'], step['keyword'], step['element'], exception) step['remark'] += str(exception) break steps = [] i = 0 for k in self.snippet_steps: steps += self.testcase['steps'][i:k] + self.snippet_steps[k] i = k steps += self.testcase['steps'][i:] self.testcase['steps'] = steps
def run(self): logger.info('Run the TestCase: %s|%s' % (self.testcase['id'], self.testcase['title'])) self.testcase['result'] = 'success' self.testcase['report'] = '' if_result = '' for index, step in enumerate(self.testcase['steps']): # 统计开始时间 step['start_timestamp'] = timestamp() # if 为否,不执行 then 语句 if step['control'] == '>' and not if_result: step['score'] = '-' step['end_timestamp'] = timestamp() continue # if 为真,不执行 else 语句 if step['control'] == '<' and if_result: step['score'] = '-' step['end_timestamp'] = timestamp() continue logger.info('Run the Step: %s|%s|%s' % (step['no'], step['keyword'], step['element'])) if not (g.platform.lower() in ('windows', ) and step['keyword'].upper() in windows_keywords): step['page'], step['custom'], step[ 'element'] = elements_format(step['page'], step['element']) label = g.sheet_name + '#' + \ self.testcase['id'] + '#' + str(step['no']).replace('<', '(').replace('>', ')').replace('*', 'x') snap = Snapshot() try: after_function = step['data'].pop('AFTER_FUNCTION', '') # 处理强制等待时间 t = step['data'].pop('等待时间', 0) sleep(float(t)) # 变量替换 replace_dict(step['data']) replace_dict(step['expected']) step['data'].pop('BEFORE_FUNCTION', '') if isinstance(step['element'], str): step['element'] = replace(step['element']) step['_element'] = step['element'] elif isinstance(step['element'], list): for i in range(len(step['element'])): step['element'][i] = replace(step['element'][i]) step['_element'] = '|'.join(step['element']) step['vdata'] = v_data(step['data']) if g.platform.lower( ) in ('desktop', ) and step['keyword'].upper() in web_keywords: # 处理截图数据 snap.pre(step, label) if step['keyword'].upper() not in ('MESSAGE', '对话框'): # 判断页面是否已和窗口做了关联,如果没有,就关联当前窗口,如果已关联,则判断是否需要切换 w.switch_window(step['page']) # 切换 frame 处理,支持变量替换 frame = replace(step['custom']) w.switch_frame(frame) # 根据关键字调用关键字实现 element = getattr(web, step['keyword'].lower())(step) snap.web_shot(step, element) elif g.platform.lower() in ( 'ios', 'android' ) and step['keyword'].upper() in mobile_keywords: # 切換 context 處理 context = replace(step['custom']).strip() w.switch_context(context) if w.current_context.startswith('WEBVIEW'): # 切换标签页 tab = step['data'].get('标签页') if tab: del step['data']['标签页'] g.driver.switch_to_window(w.windows[tab]) logger.info('Current Context: %s' % repr(w.current_context)) # 根据关键字调用关键字实现 getattr(mobile, step['keyword'].lower())(step) elif g.platform.lower() in ( 'windows', ) and step['keyword'].upper() in windows_keywords: from sweetest.keywords import windows _page = '' if step['page'].startswith('#'): _page = step['page'][1:] page = [ x for x in re.split(r'(<|>)', _page) if x != '' ] else: page = [ x for x in re.split(r'(<|>)', step['page']) if x != '' ] if _page: dialog = g.windows['#'].dialog(page) else: dialog = g.windows['default'].dialog(page) #dialog.wait('ready') snap.pre(step, label) # 根据关键字调用关键字实现 getattr(windows, step['keyword'].lower())(dialog, step) snap.windows_shot(dialog, step) elif step['keyword'].upper() in http_keywords: # 根据关键字调用关键字实现 getattr(http, step['keyword'].lower())(step) elif step['keyword'].upper() in files_keywords: # 根据关键字调用关键字实现 getattr(files, step['keyword'].lower())(step) elif step['keyword'].lower() == 'execute': result, steps = getattr(common, step['keyword'].lower())(step) self.testcase['result'] = result if step['page'] in ('SNIPPET', '用例片段'): self.snippet_steps[index + 1] = steps if result != 'success': step['end_timestamp'] = timestamp() break # elif step['page'] in ('SCRIPT', '脚本'): # # 判断页面是否已和窗口做了关联,如果没有,就关联当前窗口,如果已关联,则判断是否需要切换 # w.switch_window(step['page']) # # 切换 frame 处理,支持变量替换 # frame = replace(step['custom']) # w.switch_frame(frame) # common.script(step) else: # 根据关键字调用关键字实现 getattr(common, step['keyword'].lower())(step) logger.info('Run the Step: %s|%s|%s is success' % (step['no'], step['keyword'], step['element'])) step['score'] = 'OK' # if 语句结果赋值 if step['control'] == '^': if_result = True if after_function: replace_dict({'after_function': after_function}) # 操作后,等待0.2秒 sleep(0.2) except Exception as exception: file_name = '^' + label + now() + '.png' step['snapshot'] = str(snap.snapshot_folder / file_name) if g.platform.lower( ) in ('desktop', ) and step['keyword'].upper() in web_keywords: try: if w.frame != 0: g.driver.switch_to.default_content() w.frame = 0 g.driver.get_screenshot_as_file(step['snapshot']) except: logger.exception( '*** save the screenshot is failure ***') elif g.platform.lower() in ( 'ios', 'android' ) and step['keyword'].upper() in mobile_keywords: try: g.driver.switch_to_default_content() w.current_context = 'NATIVE_APP' g.driver.get_screenshot_as_file(snapshot_file) except: logger.exception( '*** save the screenshot is failure ***') logger.exception( 'Run the Step: %s|%s|%s is failure' % (step['no'], step['keyword'], step['element'])) step['score'] = 'NO' # if 语句结果赋值 if step['control'] == '^': if_result = False step['end_timestamp'] = timestamp() continue self.testcase['result'] = 'failure' self.testcase['report'] = 'step-%s|%s|%s: %s' % ( step['no'], step['keyword'], step['element'], exception) step['remark'] += str(exception) step['end_timestamp'] = timestamp() break # 统计结束时间 step['end_timestamp'] = timestamp() steps = [] i = 0 for k in self.snippet_steps: steps += self.testcase['steps'][i:k] + self.snippet_steps[k] i = k steps += self.testcase['steps'][i:] self.testcase['steps'] = steps
def run_testcase(self, testcase): # 根据筛选条件,把不需要执行的测试用例跳过 flag = False for k, v in self.conditions.items(): if not isinstance(v, list): v = [v] if testcase[k] not in v: testcase['result'] = 'skipped' flag = True if flag: return if testcase['condition'].lower() == 'base': logger.info('*** BASE testcase ↓ ***') if testcase['condition'].lower() == 'setup': return # 统计开始时间 testcase['start_timestamp'] = timestamp() # xml 测试报告-测试用例初始化 if testcase['flag'] != 'N': # 如果前置条件失败了,直接设置为阻塞 if self.blocked_flag: testcase['result'] = 'blocked' testcase['end_timestamp'] = timestamp() return case = self.report.create_case(testcase['title'], testcase['id']) case.start() case.priority = testcase['priority'] # 用例上下文 self.previous = self.current self.current = testcase else: testcase['result'] = 'skipped' # case.skip('Skip', 'Autotest Flag is N') # logger.info('Run the testcase: %s|%s skipped, because the flag=N or the condition=snippet' % ( # testcase['id'], testcase['title'])) # 统计结束时间 testcase['end_timestamp'] = timestamp() return if testcase['condition'].lower() not in ('base', 'setup'): if testcase['condition'].lower() == 'sub': if self.previous['result'] != 'success': testcase['result'] = 'blocked' case.block('Blocked', 'Main or pre Sub testcase is not success') logger.info('-' * 50) logger.info( f'>>> Run the testcase: {testcase["id"]}|{testcase["title"]}' ) logger.warn( '>>>>>>>>>>>>>>>>>>>> blocked <<<<<<<<<<<<<<<<<<<< Main or pre Sub TestCase is not success' ) # 统计结束时间 testcase['end_timestamp'] = timestamp() return # 如果前置条件为 skip,则此用例不执行前置条件 elif testcase['condition'].lower() == 'skip': pass else: result = self.setup(testcase, case) # if result == 'N': if not result: # 统计结束时间 testcase['end_timestamp'] = timestamp() return try: testcase['title'] = replace( testcase['title']) # 在多次跑用例集合时,可以在用例标题中使用变量区分 testcase['id'] = replace( testcase['id']) # 在多次跑用例集合时,可以在用例 id 中使用变量区分 tc = TestCase(testcase) logger.info('-' * 50) tc.run() # 统计结束时间 testcase['end_timestamp'] = timestamp() if testcase['result'] == 'success': case.succeed() elif testcase['result'] == 'failure': case.fail('Failure', testcase['report']) if testcase['condition'].lower() == 'base': logger.warn( 'Run the testcase: %s|%s Failure, BASE is not success. Break the AutoTest' % (testcase['id'], testcase['title'])) self.blocked_flag = True return if testcase['condition'].lower() == 'setup': logger.warn( 'Run the testcase: %s|%s failure, SETUP is not success. Break the AutoTest' % (testcase['id'], testcase['title'])) self.blocked_flag = True return