def check_keyword(kw): try: keyword = all_keywords.get(kw) return keyword except: logger.exception('Keyword:%s is not exist' % kw) exit()
def run(self): self.testsuite_start() # 当前测试用例 self.current = {'result': 'success'} # 上一个测试用例 self.previous = {} # 前置条件执行失败标志,即未执行用例阻塞标志 #-- self.blcoked_flag = False for testcase in self.testsuite: self.run_testcase(testcase) self.report.finish() self.testsuite += g.casesets # 把用例组合执行结果添加到末尾 # 2.清理环境 try: if g.platform.lower() in ('desktop', ): # w.close() g.driver.quit() logger.info('--- Quit th Driver: %s' % g.browserName) except: logger.exception('Clear the env is fail') self.testsuite_end()
def _locating_element( element, waittime, action='', ): el_location = None try: el, value = e.get(element) except: logger.exception( 'Locating the element:%s is Failure, no element in define' % element) raise Exception( 'Locating the element:%s is Failure, no element in define' % element) wait = WebDriverWait(g.driver, waittime) if el['by'].lower() in ('title', 'url', 'current_url'): return None elif action == 'CLICK': el_location = wait.until( EC.element_to_be_clickable((getattr(By, el['by'].upper()), value))) else: logger.debug('locating the element %s' % value) el_location = wait.until( EC.presence_of_element_located((getattr(By, el['by'].upper()), value))) return el_location
def locating_element(element, action='', text=''): el_location = None try: el, value = e.get(element) except: logger.exception( 'Locating the element:%s is Failure, no element in define' % element) raise Exception('Locating the element:%s is Failure, no element in define' % element) wait = WebDriverWait(g.driver, element_wait_timeout) if el['by'].lower() in ('title', 'url', 'current_url'): return None elif el['by'].lower() in ('alert'): if value.lower() in ('确认', 'accept'): g.driver.switch_to_alert().accept() elif value.lower() in ('取消', '关闭', 'cancel', 'close'): g.driver.switch_to_alert().dismiss() elif value.lower() in ('输入', 'input'): g.driver.switch_to_alert().send_keys(text) g.driver.switch_to_alert().accept() w.frame = 'Alert' return None elif action == 'CLICK': el_location = wait.until(EC.element_to_be_clickable( (getattr(By, el['by'].upper()), value))) else: el_location = wait.until(EC.presence_of_element_located( (getattr(By, el['by'].upper()), value))) return el_location
def plan(self): self.code = 0 # 返回码 # 1.解析配置文件 try: e.get_elements(self.elements_file) except: logger.exception('*** Parse config file fail ***') self.code = -1 sys.exit(self.code) self.report = Report() self.report_ts = {} # 2.逐个执行测试套件 for sheet_name in self.sheet_names: g.sheet_name = sheet_name # xml 测试报告初始化 self.report_ts[sheet_name] = self.report.create_suite( g.project_name, sheet_name) self.report_ts[sheet_name].start() self.run(sheet_name) self.report_workbook.close() with open(self.report_xml, 'w', encoding='utf-8') as f: self.report.write(f) sys.exit(self.code)
def __init__(self, arg): self.connect = '' self.cursor = '' try: if arg['type'].lower() == 'mysql': import pymysql as mysql self.connect = mysql.connect( host=arg['host'], port=int(arg['port']), user=arg['user'], password=arg['password'], database=arg['dbname'], charset=arg.get('charset', 'utf8')) self.cursor = self.connect.cursor() sql = 'select version()' elif arg['type'].lower() == 'oracle': import os import cx_Oracle as oracle # Oracle查询出的数据,中文输出问题解决 os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8' self.connect = oracle.connect( arg['user'] + '/' + arg['password'] + '@' + arg['host'] + '/' + arg['sid']) self.cursor = self.connect.cursor() sql = 'select * from v$version' elif arg['type'].lower() == 'sqlserver': import pymssql as sqlserver self.connect = sqlserver.connect( host=arg['host'], port=arg['port'], user=arg['user'], password=arg['password'], database=arg['dbname'], charset=arg.get('charset', 'utf8')) self.cursor = self.connect.cursor() sql = 'select @@version' self.cursor.execute(sql) data = self.cursor.fetchone() except: logger.exception('*** %s connect is fail ***' % arg['type']) raise
def locating_element(element, action=''): el_location = None try: el, value = e.get(element) except: logger.exception( 'Locating the element:%s is Failure, no element in define' % element) raise Exception('Locating the element:%s is Failure, no element in define' % element) wait = WebDriverWait(g.driver, element_wait_timeout) if el['by'].lower() in ('title', 'url', 'current_url'): return None elif action == 'CLICK': el_location = wait.until(EC.element_to_be_clickable( (getattr(By, el['by'].upper()), value))) else: el_location = wait.until(EC.presence_of_element_located( (getattr(By, el['by'].upper()), value))) try: if g.driver.name in ('chrome', 'safari'): g.driver.execute_script( "arguments[0].scrollIntoViewIfNeeded(true)", el_location) else: g.driver.execute_script( "arguments[0].scrollIntoView(false)", el_location) except: pass return el_location
def plan(self): self.code = 0 # 返回码 # 1.解析配置文件 try: e.get_elements(self.elements_file) except: logger.exception('*** Parse config file failure ***') self.code = -1 sys.exit(self.code) self.junit = JUnit() self.junit_suite = {} # 2.逐个执行测试套件 for sheet_name in self.sheet_names: g.sheet_name = sheet_name # xml 测试报告初始化 self.junit_suite[sheet_name] = self.junit.create_suite( g.plan_name, sheet_name) self.junit_suite[sheet_name].start() self.run(sheet_name) self.plan_data = g.plan_end() self.testsuite_data = g.testsuite_data summary_data = summary( self.plan_data, self.testsuite_data, self.report_data, {}) self.report_workbook.write(summary_data, '_Summary_') self.report_workbook.close() with open(self.report_xml, 'w', encoding='utf-8') as f: self.junit.write(f)
def execute(self, sql): try: self.cursor.execute(sql) self.connect.commit() except: logger.exception('*** Execute failure ***') raise
def fetchall(self, sql): try: self.cursor.execute(sql) data = self.cursor.fetchall() return data except: logger.exception('*** Fetchall fail ***') raise
def fetchone(self, sql): try: self.cursor.execute(sql) data = self.cursor.fetchone() self.connect.commit() return data except: logger.exception('*** Fetchone failure ***') raise
def __init__(self, arg): self.connect = '' self.cursor = '' self.db = '' try: if arg['type'].lower() == 'mongodb': import pymongo host = arg.pop('host') if arg.get( 'host') else 'localhost:27017' host = host.split(',') if ',' in host else host port = int(arg.pop('port')) if arg.get('port') else 27017 if arg.get('user'): arg['username'] = arg.pop('user') # username = arg['user'] if arg.get('user') else '' # password = arg['password'] if arg.get('password') else '' # self.connect = pymongo.MongoClient('mongodb://' + username + password + arg['host'] + ':' + arg['port'] + '/') self.connect = pymongo.MongoClient(host=host, port=port, **arg) self.connect.server_info() self.db = self.connect[arg['dbname']] return if arg['type'].lower() == 'mysql': import pymysql as mysql self.connect = mysql.connect(host=arg['host'], port=int(arg['port']), user=arg['user'], password=arg['password'], database=arg['dbname'], charset=arg.get( 'charset', 'utf8')) self.cursor = self.connect.cursor() sql = 'select version()' elif arg['type'].lower() == 'sqlserver': import pymssql as sqlserver self.connect = sqlserver.connect(host=arg['host'], port=arg['port'], user=arg['user'], password=arg['password'], database=arg['dbname'], charset=arg.get( 'charset', 'utf8')) self.cursor = self.connect.cursor() sql = 'select @@version' self.cursor.execute(sql) self.cursor.fetchone() except: logger.exception('*** %s connect is failure ***' % arg['type']) raise
def mongo(self, collection, sql): try: cmd = 'self.db[\'' + collection + '\'].' + sql result = eval(cmd) if sql.startswith('find_one'): return result elif sql.startswith('find'): for d in result: return d else: return {} except: logger.exception('*** Execute failure ***') raise
def run(self, sheet_name): # 1.从 Excel 获取测试用例集 try: data = self.testcase_workbook.read(sheet_name) testsuite = testsuite_format(data) # logger.info('Testsuite imported from Excel:\n' + # json.dumps(testsuite, ensure_ascii=False, indent=4)) logger.info('From Excel import testsuite success') except: logger.exception('*** From Excel import testsuite fail ***') self.code = -1 sys.exit(self.code) # 2.初始化全局对象 try: g.init(self.desired_caps, self.server_url) g.set_driver() # 如果测试数据文件存在,则从该文件里读取一行数据,赋值到全局变量列表里 data_file = path.join('data', g.project_name + '-' + sheet_name + '.csv') if path.exists(data_file): g.var = get_record(data_file) data_file = path.join( 'data', g.project_name + '-' + sheet_name + '-globle.txt') if path.exists(data_file): g.var.update(get_all_record(data_file)) w.init() except: logger.exception('*** Init global object fail ***') self.code = -1 sys.exit(self.code) # 3.解析测试用例集 try: parse(testsuite) logger.debug('testsuite has been parsed:\n' + str(testsuite)) except: logger.exception('*** Parse testsuite fail ***') self.code = -1 sys.exit(self.code) # 4.执行测试套件 ts = TestSuite(testsuite, self.report_ts[sheet_name], self.conditions) ts.run() # 5.判断测试结果 if self.report_ts[sheet_name].high_errors + self.report_ts[sheet_name].medium_errors + \ self.report_ts[sheet_name].high_failures + self.report_ts[sheet_name].medium_failures: self.code = -1 # 6.保存测试结果 try: self.report_data[sheet_name] = testsuite2report(testsuite) data = testsuite2data(testsuite) self.report_workbook.write(data, sheet_name) except: logger.exception('*** Save the report is fail ***')
def run(self, sheet_name): # 1.从 Excel 获取测试用例集 try: data = self.testcase_workbook.read(sheet_name) testsuite = testsuite_format(data) # logger.info('Testsuite imported from Excel:\n' + # json.dumps(testsuite, ensure_ascii=False, indent=4)) logger.info('From Excel import testsuite success') except: logger.exception('*** From Excel import testsuite failure ***') self.code = -1 sys.exit(self.code) # 2.初始化全局对象 try: g.set_driver() # 如果测试数据文件存在,则从该文件里读取数据,赋值到全局变量列表里 data_file = Path('data') / (g.plan_name + '-' + sheet_name + '.csv') if data_file.is_file(): g.test_data = get_record(str(data_file)) w.init() except: logger.exception('*** Init global object failure ***') self.code = -1 sys.exit(self.code) # 3.解析测试用例集 try: parse(testsuite) logger.debug('testsuite has been parsed:\n' + str(testsuite)) except: logger.exception('*** Parse testsuite failure ***') self.code = -1 sys.exit(self.code) # 4.执行测试套件 g.ts = TestSuite(testsuite, sheet_name, self.junit_suite[sheet_name], self.conditions) g.ts.run() # 5.判断测试结果 if self.junit_suite[sheet_name].high_errors + self.junit_suite[sheet_name].medium_errors + \ self.junit_suite[sheet_name].high_failures + self.junit_suite[sheet_name].medium_failures: self.code = -1 # 6.保存测试结果 try: data = testsuite2data(testsuite) self.report_workbook.write(data, sheet_name) self.report_data[sheet_name] = testsuite2report(testsuite) except: logger.exception('*** Save the report is failure ***')
case.fail('Fail', testcase['report']) if testcase['condition'].lower() == 'base': logger.warn( 'Run the testcase: %s|%s Fail, BASE is not Pass. Break the AutoTest' % (testcase['id'], testcase['title'])) break if testcase['condition'].lower() == 'setup': logger.warn( 'Run the testcase: %s|%s Fail, SETUP is not Pass. Break the AutoTest' % (testcase['id'], testcase['title'])) break except Exception as exception: case.error( 'Error', 'Remark:%s |||Exception:%s' % (testcase['remark'], exception)) logger.exception('Run the testcase: %s|%s fail' % (testcase['id'], testcase['title'])) if testcase['condition'].lower() == 'base': logger.warn( 'Run the testcase: %s|%s Error, BASE is not Pass. Break the AutoTest' % (testcase['id'], testcase['title'])) break if testcase['condition'].lower() == 'setup': logger.warn( 'Run the testcase: %s|%s Error, SETUP is not Pass. Break the AutoTest' % (testcase['id'], testcase['title'])) break self.report.finish() # 2.清理环境 try:
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(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
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.blcoked_flag = True # continue # 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.blcoked_flag = True # continue except Exception as exception: case.error( 'Error', 'Remark:%s |||Exception:%s' % (testcase['remark'], exception)) logger.exception('Run the testcase: %s|%s failure' % (testcase['id'], testcase['title'])) # if testcase['condition'].lower() == 'base': # logger.warn('Run the testcase: %s|%s error, BASE is not success. Break the AutoTest' % ( # testcase['id'], testcase['title'])) # self.blcoked_flag = True # continue # if testcase['condition'].lower() == 'setup': # logger.warn('Run the testcase: %s|%s error, SETUP is not success. Break the AutoTest' % ( # testcase['id'], testcase['title'])) # self.blcoked_flag = True # continue def run(self): self.testsuite_start()
class TestSuite: def __init__(self, testsuite, sheet_name, report, conditions={}): self.testsuite = testsuite self.sheet_name = sheet_name self.report = report self.conditions = conditions self.result = {} # base 在整个测试套件中首先执行一次 self.base_testcase = {} # setup 在每个测试用例执行之前执行一次 self.setup_testcase = {} for testcase in self.testsuite: if testcase['condition'].lower() == 'base': self.base_testcase = testcase elif testcase['condition'].lower() == 'setup': self.setup_testcase = testcase testcase['flag'] = 'N' # setup 用例只在执行其他普通用例之前执行 elif testcase['condition'].lower() == 'snippet': g.snippet[testcase['id']] = testcase testcase['flag'] = 'N' def testsuite_start(self): self.result['no'] = g.no g.no += 1 self.result['testsuite'] = self.sheet_name self.result['start_timestamp'] = timestamp() def testsuite_end(self): self.result['end_timestamp'] = timestamp() g.testsuite_data[self.sheet_name] = self.result def setup(self, testcase, case): logger.info('=' * 50) if self.setup_testcase: logger.info('*** SETUP testcase ***') else: logger.info('...No SETUP testcase need to run...') def run_setup(testcase): if testcase: tc = TestCase(testcase) tc.run() if testcase['result'] == 'success': flag = 'Y' else: flag = 'N' else: flag = 'O' return flag setup_flag = run_setup(deepcopy(self.setup_testcase)) if setup_flag == 'N': base_flag = run_setup(deepcopy(self.base_testcase)) if base_flag == 'Y': setup_flag = run_setup(deepcopy(self.setup_testcase)) if setup_flag == 'N': testcase['result'] = 'blocked' case.block('Blocked', 'SETUP is not success') logger.warn( 'Run the testcase: %s|%s blocked, SETUP is not success' % (testcase['id'], testcase['title'])) return False elif base_flag == 'O': testcase['result'] = 'blocked' case.block('Blocked', 'SETUP is not success') logger.warn( 'Run the testcase: %s|%s blocked, SETUP is not success' % (testcase['id'], testcase['title'])) return False return True def run(self): self.testsuite_start() # 当前测试用例 current = {'result': 'success'} # 上一个测试用例 previous = {} # 前置条件执行失败标志,即未执行用例阻塞标志 blcoked_flag = False # 1.执行用例 for testcase in self.testsuite: # 根据筛选条件,把不需要执行的测试用例跳过 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: continue # 统计开始时间 testcase['start_timestamp'] = timestamp() # xml 测试报告-测试用例初始化 if testcase['flag'] != 'N': # 如果前置条件失败了,直接设置为阻塞 if blcoked_flag: testcase['result'] = 'blocked' testcase['end_timestamp'] = timestamp() continue case = self.report.create_case(testcase['title'], testcase['id']) case.start() case.priority = testcase['priority'] # 用例上下文 previous = current 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() continue if testcase['condition'].lower() not in ('base', 'setup'): if testcase['condition'].lower() == 'sub': if previous['result'] != 'success': testcase['result'] = 'blocked' case.block('Blocked', 'Main or pre Sub testcase is not success') logger.warn( 'Run the testcase: %s|%s blocked, Main or pre Sub TestCase is not success' % (testcase['id'], testcase['title'])) # 统计结束时间 testcase['end_timestamp'] = timestamp() continue # 如果前置条件为 skip,则此用例不执行前置条件 elif testcase['condition'].lower() == 'skip': pass else: result = self.setup(testcase, case) # if result == 'N': if not result: # 统计结束时间 testcase['end_timestamp'] = timestamp() continue try: 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'])) blcoked_flag = True continue if testcase['condition'].lower() == 'setup': logger.warn( 'Run the testcase: %s|%s failure, SETUP is not success. Break the AutoTest' % (testcase['id'], testcase['title'])) blcoked_flag = True continue except Exception as exception: case.error( 'Error', 'Remark:%s |||Exception:%s' % (testcase['remark'], exception)) logger.exception('Run the testcase: %s|%s failure' % (testcase['id'], testcase['title'])) if testcase['condition'].lower() == 'base': logger.warn( 'Run the testcase: %s|%s error, BASE is not success. Break the AutoTest' % (testcase['id'], testcase['title'])) blcoked_flag = True continue if testcase['condition'].lower() == 'setup': logger.warn( 'Run the testcase: %s|%s error, SETUP is not success. Break the AutoTest' % (testcase['id'], testcase['title'])) blcoked_flag = True continue
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
case.error( 'Error', 'Remark:%s |||Exception:%s' % (testcase['remark'], exception)) logger.exception('Run the testcase: %s|%s failure' % (testcase['id'], testcase['title'])) if testcase['condition'].lower() == 'base': logger.warn( 'Run the testcase: %s|%s error, BASE is not success. Break the AutoTest' % (testcase['id'], testcase['title'])) blcoked_flag = True continue if testcase['condition'].lower() == 'setup': logger.warn( 'Run the testcase: %s|%s error, SETUP is not success. Break the AutoTest' % (testcase['id'], testcase['title'])) blcoked_flag = True continue self.report.finish() # 2.清理环境 try: if g.platform.lower() in ('desktop', ): # w.close() g.driver.quit() logger.info('--- Quit th Driver: %s' % g.browserName) except: logger.exception('Clear the env is fail') self.testsuite_end()