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 = JUnit() 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.plan_name, sheet_name) self.report_ts[sheet_name].start() self.run(sheet_name) self.plan_data = g.plan_end() self.testsuite_data = g.testsuite_data self.report_workbook.close() with open(self.report_xml, 'w', encoding='utf-8') as f: self.report.write(f)
def check_keyword(kw): try: keyword = all_keywords.get(kw) return keyword except: logger.exception('Keyword:%s is not exist' % kw) exit()
def execute(self, sql): try: self.cursor.execute(sql) self.connect.commit() except: logger.exception('*** Execute fail ***') 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 fetchall(self, sql): try: self.cursor.execute(sql) data = self.cursor.fetchall() self.connect.commit() return data except: logger.exception('*** Fetchall fail ***') raise
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 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('data') / (g.plan_name + '-' + sheet_name + '.csv') if data_file.is_file(): g.var = get_record(str(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, sheet_name, 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): 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']): # 统计开始时间 step['start_timestamp'] = timestamp() # 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: after_function = step['data'].pop('AFTER_FUNCTION', '') # 变量替换 replace_dict(step['data']) replace_dict(step['expected']) step['data'].pop('BEFORE_FUNCTION', '') 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'].pop('等待时间', 0) 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() 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 if after_function: replace_dict({'after_function': after_function}) # 操作后,等待0.2秒 sleep(0.2) except Exception as exception: step['snapshot'] = file_name = g.plan_name + '-' + g.sheet_name + g.start_time + \ '#' + self.testcase['id'] + '-' + str(step['no']) + '.png' snapshot_file = str(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 # 统计结束时间 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
if testcase['result'] == 'Pass': case.succeed() elif testcase['result'] == 'Fail': 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: if g.platform.lower() in ('desktop',): w.close()