Beispiel #1
0
    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', '断言失败')
Beispiel #2
0
 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)
Beispiel #3
0
 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)
Beispiel #4
0
    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)
Beispiel #5
0
 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', '切换到原来的窗口失败')
Beispiel #6
0
    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', '选项框弹出失败')
Beispiel #7
0
 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', '断言文本提示信息失败!')
Beispiel #8
0
 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)
Beispiel #9
0
 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)
Beispiel #10
0
 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)
Beispiel #11
0
 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', '切换到新窗口失败')
Beispiel #12
0
 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)
Beispiel #13
0
    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 ''
Beispiel #14
0
 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为空或者填写错误')
Beispiel #16
0
    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
Beispiel #18
0
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()    #浏览器最大化
Beispiel #19
0
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
Beispiel #20
0
 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')
Beispiel #21
0
 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
Beispiel #23
0
 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
Beispiel #25
0
    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
Beispiel #26
0
    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) + '&nbsp'*10 + '成功用例数(Pass):' + str(self.success_num) +\
                          '&nbsp'*10 + '失败用例数(Fail):' + str(self.fail_num) + '&nbsp'*10 + \
                          '&nbsp'*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