def assert_string_in_pagesource(self, assertString): try: assert assertString in self.driver.page_source, "%s not found in page source!" % assertString logger.info('断言信息为:%s' % assertString) return ('Pass', '断言成功') except Exception as e: return ('Fail', '断言失败')
def switch_to_frame(self, frame): try: self.driver.switch_to.frame(frame) logger.info('切换至frame(id/name/xpath = %s)成功' % frame) return ('Pass', 'run success') except Exception as e: logger.error('切换至frame(id/name/xpath = %s)失败' % frame) return ('Fail', e)
def switch_to_frame_xpath(self, frame): try: self.driver.switch_to.frame( self.driver.find_element_by_xpath(frame)) logger.info('切换至frame(xpath = %s)成功' % frame) return ('Pass', 'run success') except Exception as e: logger.error('切换至frame(xpath = %s)失败' % frame) return ('Fail', e)
def upload_file(self, src_file_path, remote_file_name): try: #如果文件不存在,调用file.size(filename)会报错 if self.ftp.size(remote_file_name) != None: pass except Exception as e: pass with open(src_file_path, 'rb') as file_handler: self.ftp.storbinary('STOR %s' % remote_file_name, file_handler) logger.info('文件:%s 已经上传到ftp' % src_file_path)
def now_window_handle(self): try: now_handle = self.driver.window_handles[0] self.driver.switch_to.window(now_handle) print("当前窗口句柄1:" + now_handle) logger.info('切换到原来的窗口成功:%s' % now_handle) return ('Pass', '切换到原来的窗口成功') except Exception as e: logger.info('切换到原来的窗口失败:%s' % now_handle) return ('Fail', '切换到原来的窗口失败')
def move_to_element(self, movexpath): try: # 先让选项框弹出来 mouse = self.driver.find_element_by_xpath(movexpath) ActionChains(self.driver).move_to_element(mouse).perform() logger.info('选项框弹出成功:%s' % movexpath) return ('Pass', '选项框弹出成功') except Exception as e: logger.info('选项框弹出失败:%s' % movexpath) return ('Fail', '选项框弹出失败')
def assert_text(self, titleStr): try: aElement = self.driver.find_element_by_class_name( "l-dialog-content") a_text = aElement.text # print("a_text:"+a_text) assert titleStr in a_text, "%s not found in text!" % titleStr logger.info('断言文本提示信息为:%s' % titleStr) return ('Pass', '断言文本提示信息成功!') except AssertionError as e: return ('Fail', '断言文本提示信息失败!')
def execute_insert(self, query, data): logger.info('query:%s data:%s' % (query, data)) try: db_cursor = self.dbconn.cursor() db_cursor.execute(query, data) db_cursor.execute('commit') db_cursor.close() return ('', True) except Exception as e: logger.error('执行数据库插入操作失败:%s' % e) db_cursor.execute('rollback') db_cursor.close() return (e, False)
def execute_create(self, query): logger.info('query:%s' % query) try: db_cursor = self.dbconn.cursor() db_cursor.execute(query) db_cursor.execute('commit') db_cursor.close() return ('', True) except Exception as e: logger.error('创建数据库表操作失败:%s' % e) db_cursor.execute('rollback') db_cursor.close() return (e, False)
def execute_update(self, query, data): query = query % data logger.info(query) try: db_cursor = self.dbconn.cursor() db_cursor.execute(query) db_cursor.execute('commit') db_cursor.close() return ('', True) except Exception as e: logger.error('执行数据库更新操作失败:%s' % e) db_cursor.execute('rollback') db_cursor.close() return (e, False)
def current_window_handle(self): try: '''# 得到当前窗口的句柄 now_handle = driver.current_window_handle print("当前窗口句柄:" + now_handle) # 得到所有窗口的句柄 all_handles = driver.window_handles print("++++", driver.window_handles[1])''' new_window = self.driver.window_handles[1] self.driver.switch_to.window(new_window) logger.info('切换到新的窗口成功:%s' % new_window) return ('Pass', '切换到新窗口成功') except Exception as e: logger.info('切换到新的窗口失败:%s' % new_window) return ('Fail', '切换到新窗口失败')
def select_one_record(self, query, data=""): '''返回结果只包含一条记录''' logger.info('query:%s data:%s' % (query, data)) try: db_cursor = self.dbconn.cursor() if data: db_cursor.execute(query, data) else: db_cursor.execute(query) query_result = db_cursor.fetchone() db_cursor.close() return (query_result, True) except Exception as e: logger.error('执行数据库查询操作失败:%s' % e) db_cursor.close() return (e, False)
def get_screenshot_as_file(self, step_order, testcase_run_history_id): curr_time = time.strftime('%Y%m%d%H%M%S', time.localtime()) # 截图时间 sub_path = 'tp' + str(self.test_plan_id) image_name = sub_path + '_tc' + str(self.test_case_id) + '_step' + str(step_order) + '_' + str(testcase_run_history_id) + '_' + str(curr_time) base_path = screenshot_dir_path + sub_path + '\\tc' + str(self.test_case_id) + '\\' if not os.path.isdir(base_path): other_tools.mkdirs_once_many(base_path) screenshot_pic_path = base_path + image_name + '.png' result = selenium_util.get_screenshot_as_file(screenshot_pic_path) if result[0] == 'Pass': logger.info('截图文件保存路径为:%s' % screenshot_pic_path) return screenshot_pic_path else: logger.error('截图失败:%s' % result[0]) return ''
def __init__(self, browser_type, db, test_case_id, run_history_id, runmode, test_plan_id=0, testplan_name='无计划'): logger.info('正在构造并初始化测试用例对象[id=%s]' % test_case_id) threading.Thread.__init__(self) self.test_case_id = test_case_id self.test_plan_id = test_plan_id self.browser_type = browser_type self.db = db self.run_history_id = run_history_id self.runmode = runmode self.testplan_name = testplan_name logger.info('初始测试用例完毕')
def exectue_element_operator_in_step(self, selector1, selector2, command, inparameters, expected_result): logger.info('操作:%s' % command) if inparameters: # 有输入参数 logger.info('正在对输入参数:%s 进行参数处理' % inparameters) inparameters = other_tools.conver_data_from_phppage(inparameters) inparameters = inparameters.split('||') logger.info('处理后的输入参数为:%s ' % inparameters) command = command.lower() if command == '查找': try: element = self.find_element(selector1, selector2) if element: return ('Pass', '找到元素') else: return ('Fail', '未找到元素') except Exception as e: logger.error('查找元素出错') return ('Fail', e) elif command == '输入': try: element = self.find_element(selector1, selector2) if type(inparameters) == type( []) and inparameters[0] and element: element.send_keys(inparameters[0]) return ('Pass', '输入数据成功') else: return ('Fail', '输入数据失败') except Exception as e: logger.error('执行输入操作出错:%s' % e) return ('Fail', e) elif command == '清空': try: element = self.find_element(selector1, selector2) if element: element.clear() return ('Pass', '清空数据成功') else: return ('Fail', '清空数据失败') except Exception as e: logger.error('执行输入操作出错:%s' % e) return ('Fail', e) elif command == '点击': try: element = self.find_element(selector1, selector2) if element: element.click() return ('Pass', '点击成功') else: return ('Fail', '点击操作失败') except Exception as e: logger.error('执行点击操作出错:%s' % e) return ('Fail', e) else: logger.error('command为空,或者填写错误') return ('Fail', 'comman为空或者填写错误')
def run(self): run_time = '%d-%02d-%02d %d:%d:%d' % time.localtime()[0:6] # 记录执行时间 testcase_run_result = 'Block' # 运行具体的用例步骤 # 1.获取用例所有测试步骤 test_case_steps = self.get_test_case_steps() if test_case_steps == []: logger.warn('未查找到归属用例[id=%s]的步骤' % self.test_case_id) return # 2.运行测试用例步骤 test_case_step = TestCaseStep(self.test_case_id, self.test_plan_id) logger.info('开始执行测试步骤') for tc_step in test_case_steps: step_run_result = test_case_step.run_tc_step( self.browser_type, self.db, tc_step, self.run_history_id, self.runmode) testcase_run_result = step_run_result if step_run_result != 'Pass': #步骤运行失败,提前终止 logger.info('用例[id:%s]步骤[步序:%s] 运行失败,停止运行用例' % (self.test_case_id, tc_step[0])) break if self.runmode == '运行流水': # 更新记录 logger.info('测试步骤执行完毕,正在更新用例运行结果') query_update = 'UPDATE testcase_reporter SET browserType=\'%s\', runTime=\'%s\', runResult=\'%s\' WHERE runHistoryId=\'%s\' AND testcaseId=\'%s\'' query_data = (self.browser_type, run_time, testcase_run_result, self.run_history_id, self.test_case_id) result = self.db.execute_update(query_update, query_data) if result[1] != True: logger.error('更新用例运行结果到测试用例运行报表失败:%s' % result[0]) return else: #新增记录 logger.info('测试步骤执行完毕,正在记录用例运行结果到测试用例运行报表') query_insert = 'INSERT INTO testcase_reporter' + '(runHistoryId, browserType, testcaseId, testplanId, runTime, runResult) ' \ 'VALUES(%s, %s, %s, %s, %s, %s)' query_value = (self.run_history_id, self.browser_type, self.test_case_id, self.test_plan_id, run_time, testcase_run_result) restult = self.db.execute_insert(query_insert, query_value) if restult[1] != True: logger.error('记录用例运行结果到测试用例运行报表失败:%s' % restult[0]) return
def find_element(self, selector1, selector2): # 优先使用selector1查找 element = self.find_element_by_locator_adapter(selector1) if element: #如果找到了 logger.info('找到元素:%s' % element) return element else: logger.info('利用selector1选择器未找到元素,开始用选择器:%s 查找' % selector2) element = self.find_element_by_locator_adapter(selector2) if element: #如果找到了 logger.info('找到元素:%s' % element) return element else: logger.warn('未找到元素') return None
import time import datetime import os from publicpkg.globalvar import * from publicpkg.mylogger import logger from web_auto_test.test_plan import TestPlan from web_auto_test.test_case import TestCase if __name__ == '__main__': try: for test_plan_id in testplan_list: testreport_filename_list = [] # 记录测试报告文件名,供发送邮件使用 run_history_info_list = [] # 用于存储运行历史信息(执行编号,运行浏览器, 运行耗时) if run_mode == '运行用例': # 运行指定测试用例 test_case_id = int(input('请输入要进行测试的测试用例ID:')) logger.info('正在查询用例是否存在') query_select = 'SELECT id FROM testcases WHERE id = %s' query_value = (test_case_id, ) qresult = db.select_one_record(query_select, query_value) if qresult[1] != True or not qresult[0]: logger.warn('用例id:%s不存在' % test_case_id) break logger.info('####################### 开始测试 #######################') for browser_type in browser_type_to_test: start_time = datetime.datetime.now() selenium_util.set_driver(browser_type) driver = selenium_util.get_driver() driver.get(web_site.get_web_url()) driver.implicitly_wait(30) #页面等待 driver.maximize_window() #浏览器最大化
from publicpkg import database from publicpkg import othertools from publicpkg import runmode from publicpkg import seleniumutil from publicpkg import web, browserconf, sendmail, ftp from publicpkg.mylogger import logger from web_auto_test.htmlreporter import HtmlReport __all__ = [ 'web_site', 'db', 'ftp', 'browserconf', 'other_tools', 'run_mode', 'browser_type_to_test', 'selenium_util', 'html_report', 'report_name', 'mymail', 'screenshot_dir_path', 'remote_screenshot_baselink', 'testplan_list', 'globalcase_list' ] logger.info('#####################正在初始化全局配置#####################') logger.info('正在选择数据库运行环境和站点运行环境') # 数据库环境和站点配置 config = configparser.ConfigParser() config.read('../config/test_env_switch.conf', encoding='utf-8') web_site = int(config['TEST_ENV']['web_site']) # 获取站点(测试环境,预发布环境等 db_env = int(config['TEST_ENV']['db_env']) # 获取数据库测试环境((测试环境数据库,预发布数据库等) #选择要测试的web站点 if web_site == 1: logger.info('在测试环境执行测试,正在获取测试环境的web site') web_site = web.Web('../config/web_site/test.properties') #测试环境的web elif web_site == 2: logger.info('在开发环境执行测试,正在获取开发环境的web site') web_site = web.Web('../config/web_site/dev.properties') #开发环境的web
def login(self): logger.info('ready to login ftp server') self.ftp.login(self.ftp_user, self.ftp_passwd) logger.info('login ftp server successfully')
def connect(self): logger.info('is connecting to ftp server %s on %s' % (self.ftp_host, self.ftp_port)) self.ftp.connect(self.ftp_host, self.ftp_port)
def run_function_in_step(self, command, inparameters, outputparams): logger.info('执行函数:%s' % command) if inparameters: # 有输入参数 logger.info('正在对输入参数:%s 进行参数处理' % inparameters) inparameters = other_tools.conver_data_from_phppage(inparameters) inparameters = inparameters.split('||') # 输入参数之间以||分隔 command = command.lower() if command == '切换入iframe': result = selenium_util.switch_to_frame(inparameters[0]) return result if command == '切换入xpathifram': result = selenium_util.switch_to_frame_xpath(inparameters[0]) return result elif command == '切换到新的窗口': result = selenium_util.current_window_handle() return result elif command == '切换到原来的窗口': result = selenium_util.now_window_handle() return result elif command == '等待': second = int(inparameters[0]) logger.info('等待%s秒' % second) result = selenium_util.sleep(second) return result elif command == '智能等待': second = int(inparameters[0]) logger.info('等待%s秒' % second) result = selenium_util.implicitly_wait(second) return result elif command == '断言': assertString = inparameters[0] logger.info('断言的标题为:%s' % assertString) result = selenium_util.assert_string_in_pagesource(assertString) return result logger.info('result:%s' % result) elif command == '断言文本提示信息': titleStr = inparameters[0] result = selenium_util.assert_text(titleStr) return result elif command == '弹出选项框': movexpath = inparameters[0] result = selenium_util.move_to_element(movexpath) return result
def quit(self): try: self.ftp.quit() logger.info('close ftp connection successfully') except Exception as e: logger.info('关闭ftp连接失败%s' % e)
def run_tc_step(self, browser_type, db, test_case_step, testcase_run_history_id, runmode): run_time = '%d-%02d-%02d %d:%d:%d' % time.localtime()[0:6] element_name = test_case_step[2] # 元素名称 command = test_case_step[5] # 操作 step_order = test_case_step[0] # 步序 inparams = test_case_step[6] # 输入参数 expected_result = test_case_step[7] # 预期结果 logger.info( '步骤信息(元素名称:%s, 步序:%s, 操作:%s, 输入参数:%s,预期结果:%s)' % (element_name, step_order, command, inparams, expected_result)) if (not element_name) and command: # 执行的步骤为函数操作 logger.info('正在执行函数操作') result = self.run_function_in_step(command, inparams, expected_result) if result[0] == 'Fail': # 运行出错,截图 step_screenshot_name = self.get_screenshot_as_file( step_order, testcase_run_history_id) #截图 step_screenshot_name = os.path.basename(step_screenshot_name) else: step_screenshot_name = '' else: logger.info('正在执行最普通的元素操作') # 获取元素选择器 selector1 = test_case_step[3] selector2 = test_case_step[4] logger.info('正在对选择器:selector1: %s,selector2: %s 做数据转换处理' % (selector1, selector2)) selector1 = other_tools.conver_data_from_phppage(selector1) selector2 = other_tools.conver_data_from_phppage(selector2) logger.info('转换后的选择器:selector1: %s,selector2: %s' % (selector1, selector2)) logger.info('开始对步骤中的元素操作进行操作') result = self.exectue_element_operator_in_step( selector1, selector2, command, inparams, expected_result) if result[0] == 'Fail': # 运行出错,截图 step_screenshot_name = self.get_screenshot_as_file( step_order, testcase_run_history_id) #截图 step_screenshot_name = os.path.basename(step_screenshot_name) else: step_screenshot_name = '' step_run_result = result[0] # 运行结果 step_run_result_desc = result[1] # 运行结果描述 if step_screenshot_name: step_screenshot_url = remote_screenshot_baselink.rstrip( '/') + '/' + step_screenshot_name else: step_screenshot_url = '' if '运行流水' == runmode: logger.info('正在更新测试步骤结果报表中的测试步骤运行结果') query_update = 'UPDATE case_step_run_detail SET elementName=\'%s\', command=\'%s\', inparams=\'%s\', expectedResult=\'%s\', stepRunResult=\'%s\', stepRunResultDesc=\'%s\', '\ 'browserType=\'%s\', runTime=\'%s\', screenshotUrl=\'%s\' WHERE runHistoryId=\'%s\' AND testcaseId=\'%s\' AND stepOrder=\'%s\' AND browserType=\'%s\'' query_data = (element_name, command, inparams, expected_result, step_run_result, step_run_result_desc, browser_type, run_time, step_screenshot_url, testcase_run_history_id, self.test_case_id, step_order, browser_type) result = db.execute_update(query_update, query_data) if result[1] != True: logger.error('更新用例运行结果到测试用例运行报表失败:%s' % result[0]) return else: logger.info('正在记录测试步骤运行结果到测试步骤结果报表') query_insert = 'INSERT INTO case_step_run_detail' + '(testplanId, testcaseId, runHistoryId, stepOrder, ' \ 'elementName, command, inparams, expectedResult, stepRunResult, stepRunResultDesc, browserType, runTime, screenshotUrl) ' \ 'VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)' query_value = (self.test_plan_id, self.test_case_id, testcase_run_history_id, step_order, element_name, command, inparams, expected_result, step_run_result, step_run_result_desc, browser_type, run_time, step_screenshot_url) result = db.execute_insert(query_insert, query_value) if result[1] != True: logger.error('记录到测试步骤结果报表失败 %s' % result[0]) logger.info('返回步骤运行结果给测试用例') return step_run_result
def get_test_case_steps(self): '''获取测试用例步骤''' logger.info('正在获取测试用例所有测试步骤') # 先获取只包含页面元素操作的普通步骤,接着获取只包含组件的步骤,然后获取只含命令、函数的步骤,最后union all三者,按步骤升序排序 query_select = "(SELECT a.StepOrder AS StepOrder," \ "c.PageName AS PageName," \ "b.ElementName AS ElementName," \ "b.ElementSelector AS ElementSelector," \ "b.ElementSelector02 AS ElementSelector02," \ "a.Command AS Command, " \ "a.InParas AS InParas," \ "a.OutParas AS OutParas," \ "a.compid AS compid," \ "a.compFolderid AS comFolderid," \ "'' AS comName" \ " FROM testcases_steps AS a, page_elements AS b,pagesobject AS c " \ "WHERE a.TestcaseID = %s AND a.ElementId = b.Id AND b.PageId = c.Id)" \ "UNION ALL" \ "(SELECT a.steporder AS steporder," \ "'' AS PageName," \ "'' AS ElementSelector," \ "'' AS ElementSelector02," \ "'' AS ElementName," \ "a.Command AS Command, " \ "a.InParas AS InParas," \ "a.OutParas AS OutParas," \ "a.compid AS compid," \ "a.compFolderid AS comFolderid," \ "tc.test_name AS comName" \ " FROM testcases_steps AS a, testcases AS tc " \ "WHERE a.TestcaseID = %s AND a.compid = tc.id)" \ "UNION ALL" \ "(SELECT a.steporder AS steporder," \ "'' AS PageName," \ "'' AS ElementSelector," \ "'' AS ElementSelector02," \ "'' AS ElementName," \ "a.Command AS Command, " \ "a.InParas AS InParas," \ "a.OutParas AS OutParas," \ "'' AS compid," \ "'' AS comFolderid," \ "'' AS comName" \ " FROM testcases_steps AS a " \ "WHERE a.TestcaseID = %s " \ "AND NOT ISNULL(a.stepOrder)" \ "AND NOT ISNULL(a.Command) " \ "AND ISNULL(compid) " \ "AND ElementId='')" \ "ORDER BY steporder" query_value = (self.test_case_id, self.test_case_id, self.test_case_id) result = self.db.select_many_record(query_select, query_value) if result[1] == True and result[0]: test_case_steps = result[0] logger.info('获取的测试步骤为: %s' % test_case_steps) else: logger.warn('获取的测试步骤出错 %s' % result[0]) test_case_steps = [] return test_case_steps
def run_function_in_step(self, command, inparameters, outputparams): logger.info('执行函数:%s' % command) if inparameters: # 有输入参数 logger.info('正在对输入参数:%s 进行参数处理' % inparameters) inparameters = other_tools.conver_data_from_phppage(inparameters) inparameters = inparameters.split('||') # 输入参数之间以||分隔 command = command.lower() if command == '切换frame': result = selenium_util.switch_to_frame(inparameters[0]) return result elif command == '等待': second = int(inparameters[0]) logger.info('等待%s秒'% second) result = selenium_util.sleep(second) return result elif command == '智能等待': second = int(inparameters[0]) logger.info('等待%s秒'% second) result = selenium_util.implicitly_wait(second) return result elif command == '断言': assertString = inparameters[0] logger.info('断言的标题为:%s' % assertString) result = selenium_util.assert_string_in_pagesource(assertString) return result logger.info('result:%s' % result)
def __set_result_filename(self, filename, report_id): parent_path, ext = os.path.splitext(filename) self.filename = self.dir + parent_path + str(report_id) + ext logger.info('测试报告文件名所在路径为:%s' % self.filename)
def generate_html(self, file, run_history_info_list, report_id, db, run_mode): page = PyH(self.title) page << h1(self.head, align='center') # 标题居中 for run_history_info in run_history_info_list: run_history_id = run_history_info[0] browser_type = run_history_info[1] time_took = str(run_history_info[2]) if run_mode != '运行用例': #运行计划,计划中失败的用例 logger.info('正在查询测试计划执行统计信息(执行总数,成功数,失败数,被阻塞数)') query = 'SELECT runTc_total, runPassedTc_total, runFailedTc_total, runBlockedTc_total, testPlanName, testPlanId FROM testplan_reporter WHERE runHistoryId = %s' data = (run_history_id, ) result = db.select_one_record(query, data) if result[1] != True or not result[0]: logger.warn('没查询到记录') self.case_total = 0 self.success_num = 0 self.fail_num = 0 self.block_num = 0 testplan_name = '无计划' testplan_id = 0 else: self.case_total = result[0][0] self.success_num = result[0][1] self.fail_num = result[0][2] self.block_num = result[0][3] testplan_name = result[0][4] testplan_id = result[0][5] else: logger.info('正在查询测试用例执行统计信息') query = 'SELECT runResult FROM testcase_reporter WHERE runHistoryId = %s' data = (run_history_id, ) result = db.select_one_record(query, data) if result[1] != True or not result[0]: logger.warn('没有查询到记录') self.case_total = 0 self.success_num = 0 self.fail_num = 0 self.block_num = 0 else: self.case_total = 1 self.success_num = 0 self.fail_num = 0 self.block_num = 0 case_run_result = result[0][0] if case_run_result == 'Pass': self.success_num = 1 elif case_run_result == 'Fail': self.fail_num = 1 elif case_run_result == 'Block': self.block_num = 1 testplan_name = '无计划' testplan_id = 0 if self.fail_num != 0: self.fail_num = '<font color="red">' + str( self.fail_num) + '</font>' if self.block_num != 0: self.block_num = '<font color="red">' + str( self.block_num) + '</font>' page << p( '<br/>####################################################【 ' + browser_type + '浏览器:计划执行摘要 】####################################################<br/>' ) page << p('测试总耗时:' + time_took) page << p('<br/>计划名称:' + testplan_name) page << p('用例执行统计:执行用例总数:' + str(self.case_total) + ' '*10 + '成功用例数(Pass):' + str(self.success_num) +\ ' '*10 + '失败用例数(Fail):' + str(self.fail_num) + ' '*10 + \ ' '*10 + '未执行用例数(Block):' + str(self.block_num)) for run_history_info in run_history_info_list: run_history_id = run_history_info[0] browser_type = run_history_info[1] page << p( '<br/>####################################################【 ' + browser_type + '浏览器:用例执行摘要 】####################################################<br/>' ) # 表格标题caption 表格边框border 单元格边缘与其内容之间的空白cellpadding 单元格之间间隔为cellspacing tab = table(border='1', cellpadding='1', cellspacing='0', cl='table') tab1 = page << tab tab1 << tr( td('ID', bgcolor='#ABABAB', align='center') + td('执行编号', bgcolor='#ABABAB', align='center') + td('用例ID', bgcolor='#ABABAB', align='center') + td('用例名称', bgcolor='#ABABAB', align='center') + td('所属计划', bgcolor='#ABABAB', align='center') + td('计划ID', bgcolor='#ABABAB', align='center') + td('运行浏览器', bgcolor='#ABABAB', align='center') + td('运行结果', bgcolor='#ABABAB', align='center') + td('运行时间', bgcolor='#ABABAB', align='center') + td('操作', bgcolor='#ABABAB', align='center')) logger.info('正在查询测试计划:%s 运行的的测试用例' % testplan_name) query = 'SELECT id, runHistoryId, testcaseId, testplanId, browserType, runResult, runTime FROM testcase_reporter WHERE testplanId=%s AND runHistoryId = %s ORDER BY id ASC' data = (testplan_id, run_history_id) result = db.select_many_record(query, data) if result[1] != True or not result[0]: logger.warn('未查询到用例') continue testcases = result[0] logger.info('正在记录测试计划[名称:%s]的测试用例运行结果到测试报告' % testplan_name) testcase_id_name_dic = {} # 记录测试用例id-名称键值对 for row in testcases: #查询测试用例名称 query = 'SELECT test_name FROM testcases WHERE id=%s' data = (row[2], ) query_result = db.select_one_record(query, data) if query_result[1] != True or not query_result[0]: logger.warn('未查询到测试用例') testcase_name = '' else: testcase_name = query_result[0][0] key = str(row[2]) testcase_id_name_dic[key] = testcase_name if row[5] != 'Pass': td5 = td(row[5], align='center', bgcolor='red') else: td5 = td(row[5], align='center') tab1 << tr( td(str(row[0]), align='center') + td(str(row[1]), align='center') + td(str(row[2]), align='center') + td(testcase_name, align='center') + td(testplan_name, align='center') + td(str(row[3]), align='center') + td(row[4], align='center') + td5 + td(row[6], align='center') + td('<a name=\"first' + str(row[0]) + '\" href=\"#second' + str(row[0]) + '\">点击查看详情</a>')) for run_history_info in run_history_info_list: run_history_id = run_history_info[0] browser_type = run_history_info[1] page << p( '<br/>####################################################【 ' + browser_type + '浏览器:用例执行明细 】####################################################<br/>' ) logger.info('正在查询测试计划:%s 运行的的测试用例' % testplan_name) query = 'SELECT id, runHistoryId, testcaseId, testplanId, browserType, runResult, runTime FROM testcase_reporter WHERE testplanId=%s AND runHistoryId = %s ORDER BY id ASC' data = (testplan_id, run_history_id) result = db.select_many_record(query, data) if result[1] != True or not result[0]: logger.warn('未查询到测试用例') continue testcases = result[0] for row in testcases: #获取测试用例名称 testcase_name = testcase_id_name_dic[str(row[2])] query = ('SELECT id, stepOrder, runHistoryId, elementName, command, inparams, stepRunResult, expectedResult, stepRunResultDesc, browserType, runTime, screenshotUrl FROM case_step_run_detail' + \ ' WHERE testcaseId=%s AND runHistoryId = %s '\ ' ORDER BY id ASC') data = (str(row[2]), run_history_id) logger.info('正在查询测试用例[id=%s, name=%s]对应的测试步骤执行明细' % (row[2], testcase_name)) result = db.select_many_record(query, data) if result[1] != True or not result[0]: logger.warn('未查询到所属测试用例[id=%s]的执行步骤' % str(row[2])) page << p('>>>测试用例【testcaseID:' + str(row[2]) + ' 名称:' + testcase_name + '】 <a name=\"second'+ str(row[0]) + '\"' + \ 'href=\"#first' + str(row[0]) +'\"> 点击返回</a>') tab = table(border='1', cellpadding='1', cellspacing='0', cl='table') tab2 = page << tab tab2 << tr( td('ID', bgcolor='#ABABAB', align='center') + td('步序', bgcolor='#ABABAB', align='center') + td('执行编号', bgcolor='#ABABAB', align='center') + td('所属用例', bgcolor='#ABABAB', align='center') + td('元素名称', bgcolor='#ABABAB', align='center') + td('操作', bgcolor='#ABABAB', align='center') + td('输入参数', bgcolor='#ABABAB', align='center') + td('运行结果', bgcolor='#ABABAB', align='center') + td('预期结果', bgcolor='#ABABAB', align='center') + td('结果描述', bgcolor='#ABABAB', align='center') + td('运行浏览器', bgcolor='#ABABAB', align='center') + td('运行时间', bgcolor='#ABABAB', align='center') + td('操作', bgcolor='#ABABAB', align='center')) for step_row in result[0]: # 遍历测试用例的测试步骤执行结果 testcase_name = testcase_id_name_dic[str(row[2])] if step_row[6] != 'Pass': td6 = td(step_row[6], align='center', bgcolor='red') else: td6 = td(step_row[6], align='center') if step_row[11] != '' and step_row[11].find( '.') != -1: # 存在截图 td11 = td('<a href=\"' + step_row[11] + '\" tagert=\"_blank\">查看截图</a>') else: td11 = td('') tab2 << tr( td(str(step_row[0]), align='center') + td(step_row[1], align='center') + td(str(step_row[2]), align='center') + td(testcase_name, align='center') + td(step_row[3], align='center') + td(step_row[4], align='center') + td(step_row[5], align='left') + td6 + td(step_row[7], align='left') + td(step_row[8], align='left') + td(step_row[9], align='center') + td(step_row[10], align='center') + td11) page << p('<br/>') logger.info('正在设置测试报告结果文件名') self.__set_result_filename(file, report_id) logger.info('正在生产测试报告') page.printOut(self.filename) return True
def run_test_plan(self, browser_type, db, run_mode, tp_run_history_id, test_plan_id=0): '''运行测试用例或测试计划 其中,run_mode为运行模式: run_tp - 运行测试计划, run_tp_fail_tc--运行测试计划中,所有失败的用例''' # 获取测试需要执行的测试用例ID列表 test_case_list = [] logger.info('正在获取本次测试需要执行的测试用列ID列表,测试计划名称') query_select = 'SELECT testcase_list, test_round_name FROM testcase_runround WHERE id = %s ' query_value = (test_plan_id, ) result = db.select_one_record(query_select, query_value) if result[1] != True or not result[0]: logger.warn('没找到归属于该测试计划的用例,停止运行计划') return 'Block' testcases_str = result[0][0] testplan_name = result[0][1] if testcases_str: test_case_str_list = testcases_str.split('~') # 形如 3~7~10~11 test_case_map = map(int, test_case_str_list) for id in test_case_map: test_case_list.append(id) logger.info('获取到的的测试用例id列表为: %s' % test_case_list) else: logger.warn('未获取到测试用例ID列表,请检查测试计划id(test_plan_id = %d)是否输入正确' % test_plan_id) logger.info('####################### 开始运行测试计划 #######################') # 构造测试用例对象 testcase_objects_list = [] for test_case_id in test_case_list: test_case = TestCase(browser_type, db, test_case_id, tp_run_history_id, run_mode, test_plan_id, testplan_name) testcase_objects_list.append(test_case) run_time = '%d-%02d-%02d %d:%d:%d' % time.localtime()[0:6] # 记录执行时间 mutex_lock = threading.RLock() mutex_lock.acquire() for test_case in testcase_objects_list: # 运行用例 test_case.start() # 等待用例运行完成 test_case.join() mutex_lock.release() logger.info( '####################### 测试计划已运行完毕 #######################') logger.info('正在统计测试计划执行的用例总数') query_select = 'SELECT count(testcaseId) FROM testcase_reporter WHERE runHistoryId = %s' query_value = (tp_run_history_id, ) result = db.select_one_record(query_select, query_value) if result[1] != True or not result[0]: logger.error('没找到执行过的用例') run_testcase_total = 0 else: run_testcase_total = result[0][0] logger.info('正在统计测试计划执行成功的用例总数') query_select = 'SELECT count(testcaseId) FROM testcase_reporter WHERE runHistoryId = %s AND runResult=\'Pass\'' query_value = (tp_run_history_id, ) result = db.select_one_record(query_select, query_value) if result[1] != True or not result[0]: logger.warn('没找到执行成功的用例') run_testcase_passed_total = 0 else: run_testcase_passed_total = result[0][0] logger.info('正在统计测试计划执行失败的用例总数') query_select = 'SELECT count(testcaseId) FROM testcase_reporter WHERE runHistoryId = %s AND runResult=\'Fail\'' query_value = (tp_run_history_id, ) result = db.select_one_record(query_select, query_value) if result[1] != True or not result[0]: logger.info('没找到执行失败的用例') run_testcase_failed_total = 0 else: run_testcase_failed_total = result[0][0] logger.info('正在统计测试计划执行被阻塞的用例总数') query_select = 'SELECT count(testcaseId) FROM testcase_reporter WHERE runHistoryId = %s AND runResult=\'Block\'' query_value = (tp_run_history_id, ) result = db.select_one_record(query_select, query_value) if result[1] != True or not result[0]: logger.info('没找到执行被阻塞的用例') run_testcase_blocked_total = 0 else: run_testcase_blocked_total = result[0][0] logger.info('正在统计测试计划执行成功的用例') query_select = 'SELECT testcaseId FROM testcase_reporter WHERE runHistoryId = %s AND runResult=\'Pass\'' query_value = (tp_run_history_id, ) result = db.select_many_record(query_select, query_value) if result[1] != True or not result[0]: logger.warn('没找到执行成功的用例') run_testcase_passed = '' else: run_testcase_passed = str(result[0][0]) logger.info('正在统计测试计划执行失败的用例') query_select = 'SELECT testcaseId FROM testcase_reporter WHERE runHistoryId = %s AND runResult=\'Fail\'' query_value = (tp_run_history_id, ) result = db.select_many_record(query_select, query_value) if result[1] != True or not result[0]: logger.info('没找到执行失败的用例') run_testcase_failed = '' else: run_testcase_failed = str(result[0][0]) logger.info('正在统计测试计划执行被阻塞的用例') query_select = 'SELECT testcaseId FROM testcase_reporter WHERE runHistoryId = %s AND runResult=\'Block\'' query_value = (tp_run_history_id, ) result = db.select_many_record(query_select, query_value) if result[1] != True or not result[0]: logger.info('没找到计划执行被阻塞的用例') run_testcase_blocked = '' else: run_testcase_blocked = str(result[0][0]) if '运行流水' == run_mode: # 更新测试计划运行记录历史结果表 logger.info('正在更新测试计划运行记录历史结果报表') query_update = 'UPDATE testplan_reporter SET browserType=\'%s\', runTc_total=%s, runPassedTc_total=%s, runFailedTc_total=%s,' \ 'runBlockedTc_total=%s, runPassedTc=\'%s\', runFailedTc=\'%s\', runBlockedTc=\'%s\', runTime=\'%s\' WHERE runHistoryId= %s' query_value = (browser_type, run_testcase_total, run_testcase_passed_total, run_testcase_failed_total, run_testcase_blocked_total, run_testcase_passed, run_testcase_failed, run_testcase_blocked, run_time, tp_run_history_id) result = db.execute_update(query_update, query_value) if result[1] != True: logger.error('更新测试计划运行到测试计划运行报表失败:%s' % result[0]) return elif '运行计划' == run_mode: #新增历史记录 query_insert = 'INSERT INTO testplan_reporter' +'(testPlanId, testPlanName, runHistoryId, browserType, runTc_total, runPassedTc_total, runFailedTc_total,' \ 'runBlockedTc_total, runPassedTc, runFailedTc, runBlockedTc, runTime)'\ 'VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)' query_value = (test_plan_id, testplan_name, tp_run_history_id, browser_type, run_testcase_total, run_testcase_passed_total, run_testcase_failed_total, run_testcase_blocked_total, run_testcase_passed, run_testcase_failed, run_testcase_blocked, run_time) logger.info('正在记录测试计划运行结果到测试计划报表') result = db.execute_insert(query_insert, query_value) if result[1] != True: logger.error('记录测试计划运行结果失败')
def find_element_by_locator_adapter(self, selector): logger.info('开始根据元素定位器:%s 自定位元素' % selector) if not selector: logger.warn('无法通过非法选择器:%s定位元素' % selector) return None try: if (selector[:3]).lower() == 'id=': selector = selector[3:] logger.info('find_element_by_id:%s' % selector) element = selenium_util.find_element_by_id(selector) return element elif (selector[:6]).lower() == 'xpath=': selector = selector[6:] logger.info('find_element_by_xpath:%s' % selector) element = selenium_util.find_element_by_xpath(selector) return element elif (selector[:5]).lower() == 'name=': selector = selector[5:] logger.info('find_element_by_name:%s' % selector) element = selenium_util.find_element_by_name(selector) return element elif (selector[:5]).lower() == 'link=': selector = selector[5:] logger.info('find_element_by_link_text:%s' % selector) element = selenium_util.find_element_by_link_text(selector) return element elif (selector[:10]).lower() == 'link_text=': selector = selector[10:] logger.info('find_element_by_link_text:%s' % selector) element = selenium_util.find_element_by_link_text(selector) return element elif (selector[:4]).lower() == 'css=': selector = selector[4:] logger.info('find_element_by_css_selector:%s' % selector) element = selenium_util.find_element_by_css_selector(selector) return element elif (selector[:9]).lower() == 'tag_name=': selector = selector[9:] logger.info('find_element_by_tag_name:%s' % selector) element = selenium_util.find_element_by_tag_name(selector) return element elif (selector[:11]).lower() == 'class_name=': selector = selector[11:] logger.info('find_element_by_class_name:%s' % selector) element = selenium_util.find_element_by_class_name(selector) return element elif (selector[:17]).lower() == 'partial_link_text=': selector = selector[:17] logger.info('find_element_by_partial_link_text:%s' % selector) element = selenium_util.find_element_by_partial_link_text( selector) return element else: logger.info('error, 非法选择器:%s:' % selector) return None except Exception as e: logger.error('定位元素出错,%s' % e) return None