zoukankan      html  css  js  c++  java
  • python自动化之UI自动化框架搭建三(关键字驱动)

    十二、util中新建一个ParseExcel.py,用于实现读取Excel数据文件代码封装

    # ending-utf-8
    import openpyxl
    from openpyxl.styles import Border, Side, Font
    import time
    
    
    class ParseExcel(object):
    
        def __init__(self):
    
            self.workbook = None
            self.excelFile = None
            self.font = Font(color=None)  # 设置字体颜色
            # 颜色对应的RGB值
            self.RGBDict = {'red': 'FFFF3030', 'green': 'FF008B00'}
    
        # 将Excel文件加载到内存, 并获取期workbook对象
        def loadWordBook(self, excelPathAndName):
    
            try:
                self.workbook = openpyxl.load_workbook(excelPathAndName)
    
            except Exception as e:
                raise e
    
            self.excelFile = excelPathAndName
            return self.workbook
    
        # 根据sheet名获取该sheet对象
        def getSheetByName(self, sheetName):
    
            try:
                sheet = self.workbook[sheetName]
                return sheet
            except Exception as e:
                raise e
    
        # 根据sheet索引号获取该sheet对象
        def getSheetByIndex(self, sheetIndex):
    
            try:
                sheet = self.workbook.worksheets[0]
                return sheet
            except Exception as e:
                raise e
    
        # 获取sheet中有数据区域的结束行号
        def getRowsNumber(self, sheet):
    
            return sheet.max_row
    
        # 获取sheet中有数据区域的结束列号
        def getColsNumber(self, sheet):
    
            return sheet.max_column
    
        # 获取sheet中有数据区域的开始的行号
        def getStartRowsNumber(self, sheet):
    
            return sheet.min_row
    
        # 获取sheet中有数据区域的开始的列号
        def getStartColsNumber(self, sheet):
    
            return sheet.min_column
    
        # 获取sheet中某一行,返回这一行所有数据内容组成的tuple
        # 下标从1开始,sheet.rows[1]表示第一行
        def get_row_value(self, sheet, row, max_col):
    
            try:
                # return sheet.rows[rowNo-1]  # 最新版本sheet.rows 返回的为一个生成器,所以不能采用此方法
                row_data = []
                for num in range(1, max_col+1):
                    cell_value = sheet.cell(row=row, column=num).value
                    row_data.append(cell_value)
                return row_data
    
            except Exception as e:
                raise e
    
        # 获取sheet中某一列,返回这一列所有数据组成的tuple
        # 下标从1开始,sheet.columns[1]表示第一列
        def get_col_value(self, sheet, row, col):
    
            try:
                col_data = []
                for num in range(1, row+1):
                    cell_value = sheet.cell(row=num, column=col).value
                    col_data.append(cell_value)
                return col_data
    
            except Exception as e:
                raise e
    
        # 获取某个单元格的值
        def get_cell_value(self, sheet, row, col):
            try:
                cell_value = sheet.cell(row=row, column=col).value
                return cell_value
            except Exception as e:
                raise e
    
        # 获取某个单元的对象,可以根据单元格所在位置的数字索引,也可以根据Excel中单元格的编码及坐标
        def getCellOfObject(self, sheet, coordinate=None, rowNo=None, colNo=None):
    
            if coordinate is not None:
                try:
                    return sheet.cell(coordinate=coordinate)
                except Exception as e:
                    raise e
            elif coordinate is None and rowNo is not None and colNo is not None:
                try:
                    return sheet.cell(row=rowNo, column=colNo)
                except Exception as e:
                    raise e
            else:
                raise Exception('Insufficient Coordinates of cell!')
    
        # 根据单元格在Excel中的编码坐标或者数字索引坐标向单元格中写入数据,参数style表示颜色
        def writeCell(self, sheet, content, coordinate=None, rowNo=None,
                      colNo=None, style=None):
            if coordinate is not None:
                try:
                    sheet.cell(coordinate=coordinate).value = content
                    if style is not None:
                        sheet.cell(coordinate=coordinate).font 
                            = Font(color=self.RGBDict[style])
    
                    self.workbook.save(self.excelFile)
                except Exception as e:
                    raise e
    
            elif coordinate is None and rowNo is not None and colNo is not None:
                try:
                    sheet.cell(row=rowNo, column=colNo).value = content
                    if style is not None:
                        sheet.cell(row=rowNo, column=colNo).font = 
                            Font(color=self.RGBDict[style])
    
                    self.workbook.save(self.excelFile)
                except Exception as e:
                    raise e
    
            else:
                raise Exception('Insufficient Coordinates of cell!')
    
        # 写入当前的时间,下标从1开始
        def writeCellCurrentTime(self, sheet, coordinate=None, rowNo=None,
                                 colNo=None):
            now = int(time.time())
            timeArray = time.localtime(now)
            currentTime = time.strftime("%Y-%m-%d-%H:%M:%S", timeArray)
    
            if coordinate is not None:
                try:
                    sheet.cell(coordinate=coordinate).value=currentTime
                    self.workbook.save(self.excelFile)
                except Exception as e:
                    raise e
            elif coordinate is None and rowNo is not None and colNo is not None:
                try:
                    sheet.cell(row=rowNo, column=colNo).value = currentTime
                    self.workbook.save(self.excelFile)
                except Exception as e:
                    raise e
            else:
                raise Exception('Insufficient Coordinates of cell!')
    
    
    if __name__ == '__main__':
    
        pe = ParseExcel()
        # 测试使用的Excel文件
        pe.loadWordBook('******.xlsx')
        print("通过名称获取sheet对象的名字:%s" % pe.getSheetByName("测试").title)
        print("通过index序号获取sheet对象的名字:%s" % pe.getSheetByIndex(0).title)
    
        sheet = pe.getSheetByIndex(0)
        print(type(sheet))
    
        maxRow = pe.getRowsNumber(sheet)  # 获取最大行号
        maxCol = pe.getColsNumber(sheet)  # 获取最大列号
    
    
        rows = pe.get_row_value(sheet, 3, maxCol)  # 获取某一行内容
        print(rows)
        cols = pe.get_col_value(sheet, 1, maxRow)   # 获取某一列内容
    
        pe.writeCell(sheet, '测试用', rowNo=26, colNo=1)
        pe.writeCellCurrentTime(sheet, rowNo=26, colNo=2)

    十三、在testData目录中新建一个楼宇测试.xlsx的Excel文件,并在此Excel文件中新建三个工作表(根据实际测试用例情况添加),分别命名为"测试用例"、"登录"、"新建"

    测试用例:

    登录:

    新建:

    说明:

      登录 和 新建工作表中关键字列内容对应 action包中 PageAction.py文件中的函数名;“操作元素定位方式”列表示定位元素所使用的定位方式;“表达式”列表示元素定位方式对应表达式;“操作值”列,表示需要输入的内容 

    十四、修改config包中的VarConfig.py文件

    # encoding=utf-8
    
    import os
    
    # 获取当前文件所在目录的父目录的绝对路径
    parenthDirPath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    # 异常截图存放目录绝对路径
    screenPicturesDir = parenthDirPath + "/exceptionpictures"
    
    # 测试数据文件存放绝对路径
    dataFilePath = parenthDirPath + "/testData/楼宇测试"
    
    # 测试数据文件中,测试用例表中部分列对应的数字序号
    testCase_testCaseName = 2
    testCase_testStepSheetName = 4
    testCase_testisExecute = 5
    testCase_runTime = 6
    testCase_testResult = 7
    
    # 用例步骤中,部分列对应的数字序号
    testStep_testStepDescribe = 2
    testStep_keyWords = 3
    testStep_locationType = 4
    testStep_locatorExpression = 5
    testStep_operateValue = 6
    testStep_runTime = 7
    testStep_testResult = 8
    testStep_errorInfo = 9
    testStep_errorPic = 10

    十五、修改testScripts包中的TestCreatBuilding.py文件

    # encoding=utf-8
    from KeyWordsFrameWork.action.PageAction import *
    from KeyWordsFrameWork.util.ParseExcel import ParseExcel
    from KeyWordsFrameWork.config.VarConfgi import *
    import time
    import traceback
    
    # 创建解析Excel对象
    excelObj = ParseExcel()
    # 将Excel数据文件加载到内存
    excelObj.loadWordBook(dataFilePath)
    
    
    # 用例或用例步骤执行结束后,向Excel中写入执行结果
    def writeTestResult(sheetObj, rowNo, colNo, testResult,
                        errorInfo=None, picPath=None):
        # 测试通过结果信息未绿色,失败为红色
        colorDict = {"pass": "green", "fail": "red"}
    
        # 因为测试用例工作表和用例步骤sheet表中都有测试执行时间和测试结果列,
        # 定义此字典对象是为了区分具体应该写哪个工作表
        colsDict = {
            "testCase": [testCase_runTime, testCase_testResult],
            "caseStep": [testStep_runTime, testStep_testResult]
        }
        try:
            # 在测试步骤sheet中写入测试时间
            excelObj.writeCellCurrentTime(sheetObj, rowNo=rowNo, colNo=colsDict[colNo][0])
            # 在测试步骤sheet中写入测试结果
            excelObj.writeCell(sheetObj, content=testResult, rowNo=rowNo,
                               colNo=colsDict[colNo][1], style=colorDict[testResult])
            if errorInfo and picPath:
                # 在测试步骤sheet中,写入异常信息
                excelObj.writeCell(sheetObj, content=errorInfo, rowNo=rowNo,
                                   colNo=testStep_errorInfo)
                # 在测试步骤sheet中写入异常截图路径
                excelObj.writeCell(sheetObj, content=picPath, rowNo=rowNo,
                                   colNo=testStep_errorPic)
            else:
                # 在测试步骤sheet中,清空异常信息单元格
                excelObj.writeCell(sheetObj, content='', rowNo=rowNo,
                                   colNo=testStep_errorInfo)
                # 在测试步骤sheet中,清空异常信息单元格
                excelObj.writeCell(sheetObj, content='', rowNo=rowNo,
                                   colNo=testStep_errorPic)
        except Exception:
            print("写Excel出错,%s" % traceback.print_exc())
    
    
    def TestCreatBuild():
    
        try:
            # 根据Excel文件中的sheet名称获取sheet对象
            caseSheet = excelObj.getSheetByName("测试用例")
            # 获取测试用例sheet中是否执行列对象
            maxRow = excelObj.getRowsNumber(caseSheet)  # 获取最大行号
            maxCol = excelObj.getColsNumber(caseSheet)  # 获取最大列号
            isExecuteCol = excelObj.getColumn(caseSheet, maxRow, testCase_testisExecute)
            # print(isExecuteCol)
    
            # 记录执行成功的测试用例个数
            successfulCase = 0
    
            # 记录需要执行的测试用例个数
            requiredCase = 0
    
            for idx, i in enumerate(isExecuteCol[1:]):
                # 因为用例sheet中第一行为标题行,无需执行
                # 循环遍历测试用例表中的测试用例,执行被设置为执行的用例
                if i.lower() == "y":
                    requiredCase += 1
                    # 获取测试用例中第idx+2行数据
                    caseRow = excelObj.getRow(caseSheet, idx+2, maxCol)
                    # 获取第idx+2行的步骤sheet单元格内容
                    caseStepName = caseRow[testCase_testStepSheetName-1]
    
                    # 根据用例步骤名获取步骤sheet对象
                    stepSheet = excelObj.getSheetByName(caseStepName)
                    # 获取步骤sheet中的步骤数
                    stepNum = excelObj.getRowsNumber(stepSheet)
                    # 获取最大行数和列数
                    maxstepRow = excelObj.getRowsNumber(caseSheet)  # 获取最大行号
                    maxstepCol = excelObj.getColsNumber(caseSheet)  # 获取最大列号
                    # 记录用例i的步骤成功数
                    successfulSteps = 0
                    print("开始执行用例 %s" % caseStepName)
    
                    for step in range(2, stepNum+1):
                        # 获取步骤sheet中第step行内容
                        stepRow = excelObj.getRow(stepSheet, step, maxstepCol)
    
                        # 获取关键字作为调用的函数名
                        keyWord = stepRow[testStep_keyWords-1]
    
                        # 获取操作元素定位方式作为调用的函数的参数
                        locationType = stepRow[testStep_locationType-1]
    
                        # 获取操作元素的定位表达式作为调用函数的参数
                        locatorExpression = stepRow[testStep_locatorExpression-1]
    
                        # 获取操作值作为调用函数的参数
                        operateValue = stepRow[testStep_operateValue-1]
    
                        # 构造需要执行的python语句
                        # 对应PageAction.py文件中的页面动作函数调用的字符串表示
                        if keyWord and operateValue and locationType is None 
                                and locatorExpression is None:
                            expressionStr = keyWord.strip() + '("' + str(operateValue) + '")'
    
                        elif keyWord and operateValue is None and locationType is None
                                and locatorExpression is None:
                            expressionStr = keyWord.strip() + '()'
    
                        elif keyWord and locationType and locatorExpression 
                                and operateValue:
                            expressionStr = keyWord.strip() + '("' + locationType.strip() 
                                            + '","' + locatorExpression.strip() + '","' 
                                            + str(operateValue) + '")'
    
                        elif keyWord and locationType and locatorExpression 
                                and operateValue is None:
                            expressionStr = keyWord.strip() + '("' + locationType.strip() 
                                            + '","' + locatorExpression.strip() + '")'
    
                        try:
                            # 通过eval函数,将拼接的页面动作函数调用的字符串表示当成有效的python表达式执行,
                            # 从而执行测试步骤的sheet中关键字在PageAction.py文件中对应的映射方法
                            # 完成对页面元素的操作
                            eval(expressionStr)
    
                            # 测试执行时间列写入执行时间
                            excelObj.writeCellCurrentTime(
                                stepSheet, rowNo=step, colNo=testStep_runTime
                            )
    
                        except Exception as e:
                            # 截取异常屏幕图片
                            capturePic = capture_screen()
    
                            # 获取详细的异常信息
                            errorInfo = traceback.format_exc()
                            # 测试步骤sheet中写入失败信息
                            writeTestResult(
                                stepSheet, step, "caseStep", "fail", errorInfo, capturePic
                            )
                            print("步骤%s执行失败" % stepRow[testStep_testStepDescribe-1])
    
                        else:
                            # 在测试步骤sheet中写入成功信息
                            writeTestResult(stepSheet, step, "caseStep", "pass")
    
                            # 每成功一步,successfulSteps变量+1
                            successfulSteps += 1
                            print(("步骤 %s 执行成功" % stepRow[testStep_testStepDescribe-1]))
    
                    if successfulSteps == stepNum - 1:
    
                        # 当测试用例步骤sheet中所有的步骤都执行成功,方认为此测试用例执行
                        # 通过,然后将成功信息写入测试用例工作表中,否则写入失败信息
                        writeTestResult(caseSheet, idx+2, "testCase", "pass")
                        successfulCase += 1
                    else:
                        writeTestResult(caseSheet, idx+2, "testCase", "fail")
    
            print("共%d条测试用,%d条需要被执行,本次执行通过%d条。" % (len(isExecuteCol)-1,
                                                   requiredCase, successfulCase))
        except Exception as e:
            print(traceback.print_exc())
    
    
    if __name__ == "__main__":
        TestCreatBuild()
  • 相关阅读:
    Zabbix使用grafana展示图形
    Jumpserver堡垒机
    ELK之使用filebeat的多行过滤插件把多行合并成一行
    [0] Enterprise Architect
    [0] LoadRunner
    [0] Axure
    [0] MVC&MVP&MVVM差异点
    [0] 传统架构与领域模式架构对比
    [转] .NET领域驱动设计—看DDD是如何运用设计模式颠覆传统架构
    [转] .NET领域驱动设计—实践(穿过迷雾走向光明)
  • 原文地址:https://www.cnblogs.com/huwang-sun/p/15369784.html
Copyright © 2011-2022 走看看