关键字驱动测试框架搭建(3)
关键字驱动的完整框架:
在Pycharm中创建一Python工程,其下再创建Util包,action包,config包,testScripts包,log目录,testData目录,exceptionPictures目录,具体内容如下:
Util包中存放封装的常用函数:
ParseExcel.py 解析Excel
#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 封装时间和异常截图目录
#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 封装日志
#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 封装获取页面元素方法
#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 封装等待类
#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 封装操作剪切板方法
#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 封装键盘按键方法
#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.conf
#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.py
#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,以后再进行优化