關鍵字驅動測試框架搭建(3)

關鍵字驅動測試框架搭建(3)
關鍵字驅動的完整框架:
在Pycharm中建立一Python工程,其下再建立Util包,action包,config包,testScripts包,log目錄,testData目錄,exceptionPictures目錄,具體內容以下:
Util包中存放封裝的經常使用函數:
ParseExcel.py 解析Excelcss

#encoding=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) #設置字體的顏色
        self.RGBDict = {"red":"FFFF3030","green":"FF008B00"}

    def loadWorkbook(self,excelPathAndName):
        #將excel加載到內存,並獲取其workbook對象
        try:
            self.workbook = openpyxl.load_workbook(excelPathAndName)
        except Exception,e:
            raise e
        self.excelFile = excelPathAndName
        return self.workbook

    def getSheetByName(self,sheetName):
        #要報sheet名稱獲取sheet對象
        try:
            sheet = self.workbook.get_sheet_by_name(sheetName)
            return sheet
        except Exception,e:
            raise e

    def getSheetByIndex(self,sheetIndex):
        #根據sheet的索引號獲取sheet對象
        try:
            sheetname = self.workbook.get_sheet_names()[sheetIndex]
        except Exception,e:
            raise e
        sheet = self.workbook.get_sheet_by_name(sheetname)
        return sheet

    def getRowsNumber(self,sheet):
        #獲取sheet中有數據區域的結束行號
        return sheet.max_row

    def getColsNumber(self,sheet):
        #獲取sheet中有數據區域的結束列號
        return sheet.max_column

    def getStartRowNumber(self,sheet):
        #獲取sheet中有數據區域的開通行號
        return sheet.min_row

    def getStartColNumber(self,sheet):
        #獲取sheet中有數據區域的開始列號
        return sheet.min_column

    def getRow(self,sheet,rowNo):
        #獲取sheet中的某一行,返回的是這一行全部的數據內容組成的tuple
        #下標從1開始,sheet.rows[1]表示第一行
        try:
            rows = []
            for row in sheet.iter_rows():
                rows.append(row)
            return rows[rowNo-1]
        except Exception,e:
            raise e

    def getColumn(self,sheet,colNo):
        #獲取sheet中的某一列,返回的是這一列全部的數據內容組成的tuple
        # 下標從1開始,sheet.cols[1]表示第一列
        try:
            cols = []
            for col in sheet.iter_cols():
                cols.append(col)
            return cols[colNo-1]
        except Exception,e:
            raise e

    def getCellOfValue(self,sheet,coordinate = None,rowNo = None,colNo = None):
        #要報單元格所在的索引位置獲取該單元格的值,下標從1開始
        #sheet.cell(row=1,column=1).value,表示 excel中第一行第一列的值
        if coordinate != None:
            try:
                return sheet.cell(coordinate = coordinate).value
            except Exception,e:
                raise e
        elif coordinate == None is None and rowNo is not None and colNo is not None:
            try:
                return sheet.cell(row = rowNo,column = colNo).value
            except Exception,e:
                raise e
        else:
            raise Exception("Insufficient Coordinate of cell")

    def getCellOfObject(self,sheet,coordinate = None,rowNo = None,colNo = None):
        #獲取某個單元格對象,能夠經過單元格的位置索引,也能夠經過Excel單元格的編碼座標、,
        #如 getCellOfObject(sheet,coordinate = "A1")  , 或getCellOfObject(sheet,rowNo=1,colNo=1)
        if coordinate != None:
            try:
                return sheet.cell(coordinate = coordinate)
            except Exception,e:
                raise e
        elif coordinate == None and rowNo is not None and colNo is not None:
            try:
                return sheet.cell(row = rowNo,column = colNo)
            except Exception,e:
                raise e
        else:
            raise Exception("Insufficient Coordinate of cell")

    def writeCell(self,sheet,content,coordinate = None,rowNo = None,colNo = None,style = None):
        #根據單元格在excel中的編碼座標或數字索引座標向單元 格中寫入數據
        #下標從1開始,參數style表示字體的顏色的名稱,red green
        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,e:
                raise e
        if coordinate == 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(coordinate=coordinate).font = Font(color=self.RGBDict[style])
                self.workbook.save(self.excelFile)
            except Exception,e:
                raise e
        else:
            raise Exception("Insufficient Coordinate of cell")

    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 != None:
            try:
                sheet.cell(coordinate = coordinate).value = currentTime
                self.workbook.save(self.excelFile)
            except Exception,e:
                raise e
        elif coordinate == 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,e:
                raise e
        else:
            raise Exception("Insufficient Coordinate of cell")

if __name__ == "__main__":
    pe = ParseExcel()
    pe.loadWorkbook("D:\\test\\test.xlsx")
    print u"經過名稱獲取sheet對象的名字:",pe.getSheetByName("test2").title
    print u"經過序號獲取sheet對象的名字:",pe.getSheetByIndex(0).title
    sheet = pe.getSheetByIndex(1)
    print type(sheet)
    print u"最大行號:",pe.getRowsNumber(sheet)
    print u"最大列號:",pe.getColsNumber(sheet)
    row = pe.getRow(sheet,2) #獲取第二行
    print row
    for i in row:
        print i.value

    print pe.getCellOfValue(sheet,rowNo = 1,colNo = 1)
    pe.writeCell(sheet,u"I love Python代碼",rowNo = 10,colNo= 10)
    pe.writeCellCurrentTime(sheet,rowNo = 10,colNo = 11)
    print pe.getCellOfValue(sheet,rowNo = 10,colNo = 10)
    print pe.getCellOfValue(sheet,rowNo = 10,colNo = 11)

DirAndTime.py 封裝時間和異常截圖目錄html

#encoding=utf-8
import os,time
from datetime import datetime
from config.VarConfig import screenPicturesDir

#獲取當前日期
def getCurrentDate():
    timeTup = time.localtime()
    currentDate = str(timeTup.tm_year) + "-" + str(timeTup.tm_mon) + "-" + str(timeTup.tm_mday)
    return currentDate

#獲取當前的時間
def getCurrentTime():
    timeStr = datetime.now()
    nowTime = timeStr.strftime("%H:%M:%S")
    return  nowTime

#建立截圖存放的目錄
def createCurrentDateDir():
    dirName = os.path.join(screenPicturesDir,getCurrentDate())
    if not os.path.exists(dirName):
        os.mkdir(dirName)
    return dirName

if __name__ == "__main__":
    print getCurrentDate()
    print getCurrentTime()
    print createCurrentDateDir()

log.py 封裝日誌python

#encoding=utf-8
import logging
import logging.config
from config.VarConfig import parentDirPath

#讀取日誌配置文件
logging.config.fileConfig(parentDirPath + u"\\config\\Logger.conf")

#選擇一個日誌格式
logger = logging.getLogger("example01")

def debug(message):
    #定義debug級別日誌打印方法
    logger.debug(message)

def info(message):
    #定義info級別日誌打印方法
    logger.info(message)

def warning(message):
    #定義warning級別日誌打印方法
    logger.warning(message)

ObjectMap.py  封裝獲取頁面元素方法web

#encoding=utf-8
from selenium.webdriver.support.ui import WebDriverWait

#獲取單個頁面元素
def getElement(driver,locationType,locatorExpression):
    try:
        element = WebDriverWait(driver,30).until(lambda x:x.find_element(by = locationType,value = locatorExpression))
        return element
    except Exception,e:
        raise e

#獲取多個相同頁面元素對象,以list返回
def getElements(driver,locationType,locatorExpression):
    try:
        elements = WebDriverWait(driver,30).until(lambda x:x.find_elements(by = locationType,value = locatorExpression))
        return elements
    except Exception,e:
        raise e

if __name__ == "__main__":
    from selenium import webdriver
    #進行單元測試
    driver = webdriver.Firefox(executable_path="D:\\geckodriver")
    driver.get("http://www.baidu.com")
    searchBox = getElement(driver,"id","kw")
    #打印頁面對象的標籤名
    print searchBox.tag_name
    aList = getElements(driver,"tag name","a")
    print len(aList)
    driver.quit()

WaitUtil.py 封裝等待類chrome

#encoding=utf-8
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

class WaitUtil(object):
    def __init__(self,driver):
        self.locationTypeDict = {
            "xpath":By.XPATH,
            "id":By.ID,
            "name":By.NAME,
            "css_selector":By.CSS_SELECTOR,
            "class_name":By.CLASS_NAME,
            "tag_name":By.TAG_NAME,
            "link_text":By.LINK_TEXT,
            "partial_link_text":By.PARTIAL_LINK_TEXT,
        }
        self.driver = driver
        self.wait = WebDriverWait(driver,30)

    def presenceOfElementLocated(self,locatorMethod,locatorExpression,*args):
        """顯式等待頁面元素出如今DOM中,但並不必定可見,存在則返回該頁面元素"""
        try:
            if self.locationTypeDict.has_key(locatorMethod.lower()):
                self.wait.until(EC.presence_of_element_located((self.locationTypeDict[locatorMethod.lower()],locatorExpression)))
            else:
                raise Exception(u"未找到定位方式,請確認定位方式是否書寫正確")
        except Exception,e:
            raise e

    def frameToBeAvailableAndSwitchToIt(self,locationType,locatorExpression,*args):
        """檢查frame是否存在,存在則切換進frame控件中"""
        try:
            self.wait.until(EC.frame_to_be_available_and_switch_to_it((self.locationTypeDict[locationType.lower()],locatorExpression)))
        except Exception,e:
            raise e

    def visibilityOfElementLocated(self,locationMethod,locatorExperssion,*args):
        """顯式等待頁面元素出如今DOM中,而且可見,存在則返回該頁面元素對象"""
        try:
            self.wait.until(EC.visibility_of_element_located((self.locationTypeDict[locationMethod.lower()],locatorExperssion)))
        except Exception,e:
            raise e

if __name__ == "__main__":
    from selenium import webdriver
    driver = webdriver.Firefox(executable_path = "D:\\geckodriver")
    driver.get("https://mail.126.com/")
    waitUtil = WaitUtil(driver)
    driver.find_element_by_id("lbNormal").click()
    # waitUtil.presenceOfElementLocated("id","lbNormal")
    waitUtil.frameToBeAvailableAndSwitchToIt("xpath",'//iframe[contains(@id,"x-URS-iframe")]')
    waitUtil.visibilityOfElementLocated("xpath","//input[@name='email']")
    waitUtil.presenceOfElementLocated("xpath","//input[@name='email']")
    driver.quit()

ClipboardUtil.py  封裝操做剪切板方法express

#encoding=utf-8
import win32clipboard as w
import win32con

class Clipboard(object):
    """模擬windows設置剪切板"""
    #讀取剪切板
    @staticmethod
    def getText():
        #打開剪切板
        w.OpenClipboard()
        #獲取剪切板中的數據
        d = w.GetClipboardData(win32con.CF_TEXT)
        #關閉剪切板
        w.CloseClipboard()
        #返回剪切板數據給調用者
        return d

    #設置剪切板內容
    @staticmethod
    def setText(aString):
        #打開剪切板
        w.OpenClipboard()
        #清空剪切板
        w.EmptyClipboard()
        #將數據aString寫入剪切板
        w.SetClipboardData(win32con.CF_UNICODETEXT,aString)
        #關閉剪切板
        w.CloseClipboard()

KeyBoardUtil.py 封裝鍵盤按鍵方法windows

#encoding=utf-8
import win32con
import win32api

class KeyBoardKeys(object):
    """模擬鍵盤按鍵類"""
    VK_CODE = {
        'enter': 0x0D,
        'ctrl': 0x11,
        'v': 0x56
    }

    @staticmethod
    def keyDown(keyName):
        #按下按鍵
        win32api.keybd_event(KeyBoardKeys.VK_CODE[keyName],0,0,0)

    @staticmethod
    def keyUp(keyName):
        #釋放按鍵
        win32api.keybd_event(KeyBoardKeys.VK_CODE[keyName],0,win32con.KEYEVENTF_KEYUP,0)

    @staticmethod
    def oneKey(key):
        #模擬單個按鍵
        KeyBoardKeys.keyDown(key)
        KeyBoardKeys.keyUp(key)

    @staticmethod
    def twoKeys(key1,key2):
        KeyBoardKeys.keyDown(key1)
        KeyBoardKeys.keyDown(key2)
        KeyBoardKeys.keyUp(key2)
        KeyBoardKeys.keyUp(key1)

config包存放日誌配置文件和變量:
Logger.confapi

#logger.conf
###############################################
[loggers]
keys=root,example01,example02
[logger_root]
level=DEBUG
handlers=hand01,hand02

[logger_example01]
handlers=hand01,hand02
qualname=example01
propagate=0

[logger_example02]
handlers=hand01,hand03
qualname=example02
propagate=0

###############################################
[handlers]
keys=hand01,hand02,hand03

[handler_hand01]
class=StreamHandler
level=INFO
formatter=form01
args=(sys.stderr,)

[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form01
args=('log\\Mail126TestLogfile.log', 'a')

[handler_hand03]
class=handlers.RotatingFileHandler
level=INFO
formatter=form01
args=('log\\Mail126TestLogfile.log', 'a', 10*1024*1024, 5)

###############################################
[formatters]
keys=form01,form02

[formatter_form01]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
datefmt=%Y-%m-%d %H:%M:%S

[formatter_form02]
format=%(name)-12s: %(levelname)-8s %(message)s
datefmt=%Y-%m-%d %H:%M:%S

VarConfig.py 存放變量瀏覽器

#encoding=utf-8
import os

ieDriverFilePath = "D:\\IEDriverServer"
chromeDriverFilePath = "D:\\chromedriver"
firefoxDriverFilePath = "D:\\geckodriver"

#當前文件所在目錄的父目錄的絕對路徑
parentDirPath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

#異常截圖存放目錄絕對路徑
screenPicturesDir = parentDirPath + u"\\exceptionpictures"

#測試數據文件存放的絕對路徑
dataFilePath = parentDirPath + u"\\testData\\126郵箱發送郵件.xlsx"

# 測試數據文件中,測試用例表中部分列對應的數字序號
testCase_testCaseName = 2
testCase_testStepSheetName = 4
testCase_isExecute = 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

testData目錄下存放測試數據,26郵箱發送郵件.xlsx
sheet--測試用例            
序號    用例名稱         用例描述                             步驟sheet名             是否執行           執行結束時間            結果
1    登陸126郵箱             使用有效的帳號登陸126郵箱                 登陸                      y    
2    發送帶附件的郵件    登陸126郵箱後,發送一封帶附件的郵件         發郵件                      y    

sheet--登陸
序號    測試步驟描述    關鍵字    操做元素的定位方式    操做元素的定位表達式    操做值    測試執行時間    測試結果    錯誤信息    錯誤截圖
1         打開瀏覽器    open_browser            chrome                
2        訪問被測試網址http://www.126.com    visit_url            http://www.126.com                
3        最大化窗口    maximize_browser                            
4        等待126郵箱登陸主頁加載完成    sleep            5                
5        斷言當前活動頁面源碼中是否包含「126網易免費郵--你的專業電子郵局」    assert_string_in_pagesource            126網易免費郵--你的專業電子郵局                
6        顯示等待id屬性值爲x-URS-iframe的frame框的出現,而後切換進入該frame框中    waitFrameToBeAvailableAndSwitchToIt    id    x-URS-iframe                    
7        輸入登陸用戶名    input_string    xpath    //input[@name='email']    xxxx
8        輸入登陸密碼    input_string    xpath    //input[@name='password']    xxxx
9        點擊登陸按鈕    click    id    dologin                    
10        等待    sleep            5                
11        切回默認會話窗體    switch_to_default_content                            
12    斷言登陸成功後的頁面標題是否包含「網易郵箱6.0版」關鍵內容    assert_title            網易郵箱6.0版                


sheet--發郵件
序號    測試步驟描述    關鍵字    操做元素的定位方式    操做元素的定位表達式    操做值    測試執行時間    測試結果    錯誤信息    錯誤截圖
1    判斷「寫信」按鈕是否在頁面上可見    waitVisibilityOfElementLocated    xpath    //span[text()='寫 信']                    
2    點擊「寫信」按鈕    click    xpath    //span[text()='寫 信']                    
3    輸入收件人地址    input_string    xpath    //div[contains(@id,'_mail_emailinput')]/input    xxx@126.com                
4    輸入郵件主題    input_string    xpath    //div[@aria-label='郵件主題輸入框,請輸入郵件主題']/input    帶附件的郵件                
5    點擊「上傳附件」連接    click    xpath    // div[contains( @ title, '點擊添加附件')]                    
6    輸入附件所在絕對路徑    paste_string            D:\\test\\test.txt                
7    模擬鍵盤迴車鍵    press_enter_key                            
8    顯示等待附件上傳完畢    waitVisibilityOfElementLocated    xpath    //span[text()="上傳完成"]                    
9    若是郵件正文的frame框是否可見,切換進該frame中    waitFrameToBeAvailableAndSwitchToIt    xpath    //iframe[@tabindex=1]                    
10    輸入郵件正文    input_string    xpath    /html/body    發給光榮之路的一封信                
11    退出郵件正文的frame    switch_to_default_content                            
12    點擊郵件發送按鈕    click    xpath    //header//span[text()='發送']                    
13    等待郵件發送成功,返回結果    sleep            3                
14    斷言頁面源碼中是否出現「發送成功」關鍵內容    assert_string_in_pagesource            發送成功                
15    關閉瀏覽器    close_browser                            


建立log目錄,存放日誌文件
建立exceptionpictures目錄,存放異常截圖
建立action包,存放關鍵字對應的方法
PageAction.pyapp

#encoding=utf-8
from selenium import webdriver
from config.VarConfig import ieDriverFilePath
from config.VarConfig import chromeDriverFilePath
from config.VarConfig import firefoxDriverFilePath
from Util.ObjectMap import getElement
from Util.KeyBoardUtil import KeyBoardKeys
from Util.ClipboardUtil import Clipboard
from Util.DirAndTime import *
from Util.WaitUtil import WaitUtil
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.chrome.options import Options
import time

#定義全局變量driver
driver = None
#定義全局的等待類實例對象
waitUtil = None

def open_browser(browserName,*args):
    #打開瀏覽器
    global driver,waitUtil
    try:
        if browserName.lower() == "ie":
            driver = webdriver.Ie(executable_path = ieDriverFilePath)
        elif browserName.lower == "chrome":
            #建立Chrome瀏覽器的一個Options實例對象
            chrome_options = Options()
            #添加屏蔽--ignore--certificate--errors提示信息的設置參數項
            chrome_options.add_experimental_option("excludeSwitches",["ignore-certificate-errors"])
            driver = webdriver.Chrome(executable_path = chromeDriverFilePath,chrome_options = chrome_options)
        else:
            driver = webdriver.Firefox(executable_path = firefoxDriverFilePath)
        #driver對象建立成功後,建立等待類實例對象
        waitUtil = WaitUtil(driver)
    except Exception,e:
        raise e

def visit_url(url,*args):
    #訪問某個網站
    global driver
    try:
        driver.get(url)
    except Exception,e:
        raise e

def close_browser(*args):
    #關閉瀏覽器
    global driver
    try:
        driver.quit()
    except Exception,e:
        raise e

def sleep(sleepSeconds,*args):
    #強制等待
    try:
        time.sleep(int(sleepSeconds))
    except Exception,e:
        raise e

def clear(locationType,locatorExpression,*args):
    #清空輸入框默認內容
    global driver
    try:
        getElement(driver,locationType,locatorExpression).clear()
    except Exception,e:
        raise e

def input_string(locationType,locatorExpression,inputContent):
    #在頁面輸入框中輸入數據
    global driver
    try:
        getElement(driver,locationType,locatorExpression).send_keys(inputContent)
    except Exception,e:
        raise e

def click(locationType,locatorExpression,*args):
    #點擊頁面元素
    global driver
    try:
        getElement(driver,locationType,locatorExpression).click()
    except Exception,e:
        raise e

def assert_string_in_pagesource(assertString,*args):
    #斷言頁面源碼是否存在某個關鍵字或關鍵字符串
    global driver
    try:
        assert assertString in driver.page_source,u"%s not found in page source!" % assertString
    except AssertionError,e:
        raise AssertionError(e)
    except Exception,e:
        raise e

def assert_title(titleStr,*args):
    #斷言頁面標題是否存在給定的關鍵字符串
    global driver
    try:
        assert titleStr in driver.title,u"%s not found in page title!" % titleStr
    except AssertionError,e:
        raise AssertionError(e)
    except Exception,e:
        raise e

def getTitle(*args):
    #獲取頁面標題
    global driver
    try:
        return driver.title
    except Exception,e:
        raise e

def getPageSource(*args):
    #獲取頁面源碼
    global driver
    try:
        return driver.page_source
    except Exception,e:
        raise e

def switch_to_frame(locationType,frameLocatorExpressoin,*args):
    #切換進frame
    global driver
    try:
        driver.switch_to.frame(getElement(driver,locationType,frameLocatorExpressoin))
    except Exception,e:
        print "frame error!"
        raise e

def switch_to_default_content(*args):
    #切換妯frame
    global driver
    try:
        driver.switch_to.default_content()
    except Exception,e:
        raise e

def paste_string(pasteString,*args):
    #模擬Ctrl+V操做
    try:
        Clipboard.setText(pasteString)
        #等待2秒,防止代碼執行過快,而未成功粘貼內容
        time.sleep(2)
        KeyBoardKeys.twoKeys("ctrl","v")
    except Exception,e:
        raise e

def press_tab_key(*args):
    #模擬tab鍵
    try:
        KeyBoardKeys.oneKey("tab")
    except Exception,e:
        raise e

def press_enter_key(*args):
    #模擬enter鍵
    try:
        KeyBoardKeys.oneKey("enter")
    except Exception,e:
        raise e

def maximize_browser(*args):
    #窗口最大化
    global driver
    try:
        driver.maximize_window()
    except Exception,e:
        raise e

def capture_screen(*args):
    #截取屏幕圖片
    global driver
    currentTiem = getCurrentTime()
    picNameAndPath = str(createCurrentDateDir()) + "\\" + str(currentTiem) + ".png"
    try:
        driver.get_screenshot_as_file(picNameAndPath.replace(("\\",r"\\")))
    except Exception,e:
        raise e
    else:
        return picNameAndPath

def waitPresenceOfElementLocated(locationType,locatorExpression,*args):
    """顯式等待頁面元素出如今DOM中,但不必定可見,存在則返回該頁面元素對象"""
    global waitUtil
    try:
        waitUtil.presenceOfElementLocated(locationType,locatorExpression)
    except Exception,e:
        raise e

def waitFrameToBeAvailableAndSwitchToIt(locationType,locatorExprssion,*args):
    """檢查frame是否存在,存在則切換進frame控件中"""
    global waitUtil
    try:
        waitUtil.frameToBeAvailableAndSwitchToIt(locationType,locatorExprssion)
    except Exception,e:
        raise e

def waitVisibilityOfElementLocated(locationType,locatorExpression,*args):
    """顯式等待頁面元素出如今Dom中,而且可見,存在返回該頁面元素對象"""
    global waitUtil
    try:
        waitUtil.visibilityOfElementLocated(locationType,locatorExpression)
    except Exception,e:
        raise e

testScript包,存放寫入測試結果和執行測試腳本,TestSendMailWithAttachment.py

#encoding=utf-8
from action.PageAction import *
from Util.ParseExcel import ParseExcel
from config.VarConfig import *
import time,traceback
from Util.Log import *

#設置這次測試的環境編碼爲utf8
import sys
reload(sys)
sys.setdefaultencoding("utf-8")

#建立解析Excel對象
excelObj = ParseExcel()
#將Excel數據文件加載到內存
excelObj.loadWorkbook(dataFilePath)

#用例或用例步驟執行結束後,向excel中寫入結果信息
def writeTestResult(sheetObj,rowNo,colNo,testResult,errorInfo = None,picPath = None):
    #測試經過結果信息爲綠色,失敗爲紅色
    colorDict = {"pass":"green","fail":"red"}

    #由於「測試用例」工做表和「用例步驟」sheet表中都有測試執行時間和測試結果列,定義此字典是爲了區分具體應該寫那個工做表
    colsDict = {"testCase":[testCase_runTime,testCase_testResult],"testStep":[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,e:
        #在日誌文件是寫入詳細異常堆棧信息
        logging.debug(u"寫入excel出錯,%s" % traceback.format_exc())

def TestSendMailWithAttachment():
    try:
        #根據excel中的sheet名稱獲取sheet對象
        caseSheet = excelObj.getSheetByName(u"測試用例")
        #獲取測試用例hsheet中是否執行列對象
        isExecuteColumn = excelObj.getColumn(caseSheet,testCase_isExecute)
        #記錄執行成功的測試用例個數
        successfulCase = 0
        #記錄須要執行的用例個數
        requiredCase = 0
        for idx,i in enumerate(isExecuteColumn[1:]):
            #由於測試用例sheet中第一行爲標題,無需執行,因此從第二行開始遍歷
            #循環遍歷「測試用例」sheet表中的用例, 執行被設置爲「執行」的用例
            print i.value
            if i.value.lower() == "y":
                requiredCase += 1
                #獲取「測試用例」表中第第idx+2行數據
                caseRow = excelObj.getRow(caseSheet,idx+2)
                #獲取第idx+2行的「步驟sheet名」單元格內容
                caseStepSheetName = caseRow[testCase_testStepSheetName - 1].value
                print caseStepSheetName
                #根據用例步驟名獲取步驟sheet對象
                stepSheet = excelObj.getSheetByName(caseStepSheetName)
                #獲取步驟sheet中步驟數
                stepNum = excelObj.getRowsNumber(stepSheet)
                print stepNum
                #記錄測試用例i的步驟執行成功數
                successfulSteps = 0
                logging.info(u"開始執行用例「%s」" % caseRow[testCase_testCaseName - 1].value)
                for step in xrange(2,stepNum + 1):
                    #由於步驟sheet中的第一行爲標題行,無需執行,
                    #獲取步驟sheet中的step行對象
                    stepRow = excelObj.getRow(stepSheet,step)
                    #獲取關鍵字做爲調用 的函數名
                    keyWord = stepRow[testStep_keyWords - 1].value
                    #獲取操做元素定位方式做爲調用函數的參數
                    locationType = stepRow[testStep_locationType - 1].value
                    #獲取操做元素的定位表達式做爲調用函數的參數
                    locatorExpression = stepRow[testStep_locatorExpression - 1].value
                    #獲取操做值做爲調用函數的參數
                    operateValue = stepRow[testStep_operateValue - 1].value
                    #將操做值爲數字類型的數據轉換成字符串類型,方便字符拼接
                    if isinstance(operateValue,long):
                        operateValue = str(operateValue)

                    print keyWord,locationType,locatorExpression,operateValue

                    expressionStr = ""
                    #構造須要執行的python語句,對應的是PageAction.py文件中的頁面動做函數調用的字符串表示
                    if keyWord and operateValue and locationType is None and locatorExpression is None:
                        expressionStr = keyWord.strip() + "(u'" + operateValue + "')"
                    elif keyWord and operateValue is None and locationType is None and locatorExpression is None:
                        expressionStr = keyWord.strip() + "()"
                    elif keyWord and operateValue is None and locationType and locatorExpression:
                        expressionStr = keyWord.strip() + "('" + locationType.strip() + "','" + \
                                        locatorExpression.replace("'",'"').strip() + "',u'" + operateValue + "')"
                    elif keyWord and operateValue is None and locationType and locatorExpression:
                        expressionStr = keyWord.strip() + "('" + locationType.strip() + "','" + \
                                        locatorExpression.replace("'",'"').strip() + "')"
                    print expressionStr

                    try:
                        #經過eval函數,將拼接的頁面動做函數調用的字符串表示,當成有效的python表達式執行,從而執行測試步驟sheet中
                        #關鍵字在PageAction.py文件中對應的映射方法赤完成對頁面元素的操做
                        eval(expressionStr)
                        #在測試執行時間列中寫入時間
                        excelObj.writeCellCurrentTime(stepSheet,rowNo = step,colNo = testStep_runTime)
                    except Exception,e:
                        #截取異常屏幕圖片
                        capturePic = capture_screen()
                        #獲取詳細的異常堆棧信息
                        errorInfo = traceback.format_exc()
                        #在測試步驟sheet中寫入失敗信息
                        writeTestResult(stepSheet,step,"caseStep","failed",errorInfo,capturePic)
                        logging.error(u"步驟「%s」執行失敗,錯誤信息:%s" % (stepRow[testStep_testStepDescribe - 1].value,errorInfo))
                    else:
                        #在測試步驟sheet中寫入成功信息
                        writeTestResult(stepSheet,step,"caseStep","pass")
                        #每成功一步,successfulSteps變量自增
                        successfulSteps += 1
                        logging.info(u"步驟「%s」執行經過。" % stepRow[testStep_testStepDescribe - 1].value)
                if successfulSteps == stepNum - 1:
                    #當測試用例步驟sheet中全部的步驟都執行成功,方認爲此測試用例執行經過,而後將成功信息寫入測試用例工做表中,不然寫入失敗信息
                    writeTestResult(caseSheet,idx + 2,"testCase","pass")
                    successfulCase += 1
                else:
                    writeTestResult(caseSheet,idx + 2,"testCase","Failed")
        logging.info(u"共%d條用例,%d條須要執行,本次執行經過%d條。" % (len(isExecuteColumn)-1,requiredCase,successfulCase))
    except Exception,e:
        #打印詳細的異常堆棧信息
        print traceback.print_exc()

在框架目錄建立RunTest.py,執行測試腳本:

#encoding=utf-8
from testScripts.TestSendMailWithAttachment import TestSendMailWithAttachment

if __name__ == "__main__":
    TestSendMailWithAttachment()

總結:

完整框架是參考別人的代碼寫的,最後雖然能夠執行成功,但測試結果未成功寫入Excel,之後再進行優化

相關文章
相關標籤/搜索