測試流程:
一、帳號密碼手動寫入Excel中
二、使用ddt讀取Excel中的帳號密碼
三、使用unittest進行單元測試,登陸公司某個系統
四、斷言是否用例是否執行成功(登陸成功判斷頁面中是否有「退出」,登陸失敗的判斷頁面提示是否正確)
五、最後生成HTML測試報告html
在本地磁盤D:\test\DataDrivenTesting目錄中新建一個「登陸測試.xlsx」,工做表名爲「帳號密碼」,內容以下:
序號 帳號 密碼 指望結果
1 chenyl1 a123456 退出
2 chenyl2 a123456 退出
3 chenyl3 a123456 退出
4 chenyl4 a123456 退出
5 chenyl4 請輸入密碼
6 a123456 請輸入用戶名
7 請輸入用戶名
8 abc1234 a123456 該用戶不存在
9 chenyl1 xx112233 密碼錯誤
10 acbd123 1123aaxx 該用戶不存在web
在PyCharm中建立MyLoginProject的Python工程,並在工程下建立如下文件:ExcelUtil.py ,ReportTemplate.py,MyLoginDataDrivenByExcel.py
ExcelUtil.py文件用於編寫讀取Excel的腳本,具體內容以下:瀏覽器
#encoding=utf-8 from openpyxl import load_workbook class ParseExcel(object): def __init__(self, excelPath, sheetName): # 將要讀取的excel加載到內存 self.wb = load_workbook(excelPath) # 經過工做表名稱獲取一個工做表對象 self.sheet = self.wb.get_sheet_by_name(sheetName) # 獲取工做表中存在數據的區域的最大行號 self.maxRowNum = self.sheet.max_row def getDatasFromSheet(self): # 用於存放從工做表中讀取出來的數據 dataList = [] for line in self.sheet.rows: # 遍歷工做表中數據區域的每一行, # 並將每行中各個單元格的數據取出存於列表tmpList中, # 而後再將存放一行數據的列表添加到最終數據列表dataList中 tmpList = [] #若是單元格爲空,則在列表中插入一個爲空的unicode字符串,以避免輸入帳號密碼時報錯 if line[1].value == None: tmpList.append(u"") else: tmpList.append(line[1].value) if line[2].value == None: tmpList.append(u"") else: tmpList.append(line[2].value) tmpList.append(line[3].value) dataList.append(tmpList) # 將獲取工做表中的全部數據的迭代對象返回 # 由於工做表中的第一行是標題行,因此須要去掉 return dataList[1:] if __name__ == '__main__': excelPath = u'D:\\test\\DataDrivenTesting\\登陸測試.xlsx' sheetName = u"帳號密碼" pe = ParseExcel(excelPath, sheetName) print pe.getDatasFromSheet() for i in pe.getDatasFromSheet(): print i[0],type(i[0]) #i[1],i[2]
文件ReportTemplate.py用於生成自定義HTML測試報告,具體內容以下:app
# encoding=utf-8 def htmlTemplate(url, trData): htmlStr = u'''<!DOCTYPE HTML> <html> <head><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>單元測試報告</title> <style> body { width: 80%; /*整個body區域佔瀏覽器的寬度百分比*/ margin: 40px auto; /*整個body區域相對瀏覽器窗口擺放位置(左右,上下)*/ font-weight: bold; /*整個body區域的字體加粗*/ font-family: 'trebuchet MS', 'Lucida sans', SimSun; /*表格中文字的字體類型*/ font-size: 18px; /*表格中文字字體大小*/ color: #000; /*整個body區域字體的顏色*/ } table { *border-collapse: collapse; /*合併表格邊框*/ border-spacing: 0; /*表格的邊框寬度*/ width: 100%; /*整個表格相對父元素的寬度*/ } .tableStyle { /*border: solid #ggg 1px;*/ border-style: outset; /*整個表格外邊框樣式*/ border-width: 2px; /*整個表格外邊框寬度*/ /*border: 2px;*/ border-color: blue; /*整個表格外邊框顏色*/ } .tableStyle tr:hover { background: rgb(173,216,230); /*鼠標滑過一行時,動態顯示的顏色146,208,80*/ } .tableStyle td,.tableStyle th { border-left: solid 1px rgb(146,208,80); /*表格的豎線顏色*/ border-top: 1px solid rgb(146,208,80); /*表格的橫線顏色 */ padding: 15px; /*表格內邊框尺寸*/ text-align: center; /*表格內容顯示位置*/ } .tableStyle th { padding: 15px; /*表格標題欄,字體的尺寸*/ background-color: rgb(146,208,80); /*表格標題欄背景顏色*/ /*表格標題欄設置漸變顏色*/ background-image: -webkit-gradient(linear, left top, left bottom, from(#92D050), to(#A2D668)); /*rgb(146,208,80)*/ } </style> </head> <body> <center><h1>測試報告</h1></center><br /><br /><br /> <table class="tableStyle"> <thead> <tr> <th>No</th> <th>Username</th> <th>Password</th> <th>Assert Words</th> <th>Start Time</th> <th>Waste Time(s)</th> <th>Status</th> </tr> </thead>''' endStr = u''' </table> </body> </html>''' # 拼接完整的測試報告HTML頁面代碼 html = htmlStr + u"<b>測試網址: " + url + u"</b>" + trData + endStr #print html # 生成.html文件 with open(u"D:\\test\\DataDrivenTesting\\testTemplate.html", "w") as fp: fp.write(html.encode("gbk"))
MyLoginDataDrivenByExcel.py用於編寫數據驅動測試腳本,具體內容以下:函數
#encoding=utf-8 from selenium import webdriver import unittest,time,os import logging,traceback import ddt from ExcelUtil import ParseExcel from ReportTemplate import htmlTemplate from selenium.common.exceptions import NoSuchElementException # 初始化日誌對象 logging.basicConfig( # 日誌級別 level=logging.INFO, # 日誌格式 # 時間、代碼所在文件名、代碼行號、日誌級別名字、日誌信息 format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', # 打印日誌的時間 datefmt='%a, %Y-%m-%d %H:%M:%S', # 日誌文件存放的目錄(目錄必須存在)及日誌文件名 filename='D:\\test\\DataDrivenTesting\\report.log', # 打開日誌文件的方式 filemode='w' ) excelPath = u"D:\\test\\DataDrivenTesting\\登陸測試.xlsx" sheetName = u"帳號密碼" #ParseExcel類的實例對象 excel = ParseExcel(excelPath,sheetName) @ddt.ddt class TestDemo(unittest.TestCase):
#公司地址保密,使用xxx代替 url = "xxx" no = 0 @classmethod def setUpClass(cls): # 整個測試過程只被調用一次 TestDemo.trStr = "" def setUp(self): self.driver = webdriver.Ie(executable_path="D:\\IEDriverServer") status = None # 用於存放測試結果狀態,失敗'fail',成功'pass' flag = 0 # 數據驅動測試結果的標誌,失敗置0,成功置1 TestDemo.no += 1 @ddt.data(*excel.getDatasFromSheet()) def test_dataDrivenByFile(self, data): # 決定測試報告中狀態單元格中內容的顏色 flagDict = {0: 'red', 1: '#00AC4E'} # 訪問系統 self.driver.get(TestDemo.url) # 將瀏覽器窗口最大化 self.driver.maximize_window() #print data # 讀取Excel中的帳號密碼及指望結果 username,password, expectdata = tuple(data) # 設置隱式等待時間爲10秒 self.driver.implicitly_wait(10) try: # 獲取當前的時間戳,用於後面計算查詢耗時用 start = time.time() # 獲取當前時間的字符串,表示測試開始時間 startTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) # 找到用戶名輸入框,並輸入測試數據 self.driver.find_element_by_id("username").send_keys(username) # 找到密碼輸入框,並輸入測試數據 self.driver.find_element_by_id("password").send_keys(password) # 找到登陸按鈕,並點擊 self.driver.find_element_by_id("button").click() time.sleep(5) # 斷言指望結果是否出如今頁面源代碼中 self.assertTrue(expectdata in self.driver.page_source) except NoSuchElementException, e: logging.error(u"查找的頁面元素不存在,異常堆棧信息:" + str(traceback.format_exc())) status = 'fail' flag = 0 except AssertionError, e: logging.info(u"登陸帳號:「%s」,指望「%s」,失敗" % (username, expectdata)) status = 'fail' flag = 0 except Exception, e: logging.error(u"未知錯誤,錯誤信息:" + str(traceback.format_exc())) status = 'fail' flag = 0 else: logging.info(u"登陸帳號:「%s」,指望「%s」經過" % (username, expectdata)) status = 'pass' flag = 1 # 計算耗時,從將測試數據輸入到輸入框中到斷言指望結果之間所耗時 wasteTime = time.time() - start - 5 # 減去強制等待的3秒 # 每一組數據測試結束後,都將其測試結果信息插入表格行 # 的HTML代碼中,並將這些行HTML代碼拼接到變量trStr變量中, # 等全部測試數據都被測試結束後,傳入htmlTemplate()函數中 # 生成完整測試報告的HTML代碼 TestDemo.trStr += u''' <tr> <td>%s</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%.2f</td> <td style="color:%s">%s</td> </tr><br />''' % (TestDemo.no, username,password, expectdata, startTime, wasteTime, flagDict[flag], status) def tearDown(self): self.driver.quit() @classmethod def tearDownClass(cls): # 寫自定義的html測試報告 # 整個測試過程只被調用一次 htmlTemplate(TestDemo.url, TestDemo.trStr) if __name__ == '__main__': unittest.main()