背景介紹
最近在學習自動化測試,現在需要進行一個UI自動化測試的簡單實現,具體要求如下:
- 使用unittest
- 針對百度的UI自動化測試,使用selenium
- 完成最少三個測試類
- 使用HTMLtestrunner輸出測試報告。
- selenium要做基本的二次封裝。
- 測試數據用excle進行管理。
針對以上要求,使用selenium+python的方式實現UI自動化測試,同時使用unittest輔助進行測試用例、測試報告的管理。
環境及使用軟件信息
- python 3
- selenium 3.13.0
- xlrd 1.1.0
- chromedriver
- HTMLTestRunner
說明:
selenium/xlrd只需要再python環境下使用pip install 名稱即可進行對應的安裝。 安裝完成后可使用pip list查看自己的安裝列表信息。
chromedriver:版本需和自己的chrome瀏覽器對應, 下載地址:https://chromedriver.storage.googleapis.com/index.html。 作用:對chrome瀏覽器進行驅動。
HTMLTestRunner:HTMLTestRunner是Python標准庫的unittest模塊的一個擴展。它生成易於使用的HTML測試報告。 下載地址:http://tungwaiyip.info/software/HTMLTestRunner.html。 下載后放在對應的包中,使用import引入即可使用。
項目結構
項目主要包括一下幾個部分:
- cases #存放項目用例 -test01.py #測試用例存放
- datas #存在測試數據
- test.xls #測試數據存放
- drivers #存放項目使用到的驅動
- chromedriver.exe #chrome瀏覽器驅動文件
- reports #存放生成的測試報告
- unitls #存放第三方庫
- HTMLTestRunner.py #用於生成HTML格式的測試報告
- pyselenium.py #對selenium代碼的簡單封裝
- readExcel.py #封裝xlrd的excel數據的讀取
- webConfig.py #配置使用的瀏覽器信息
- run.py #代碼啟動入口
代碼實現
unitls包
其中,unitls需要進行初始化,否則,在其他模塊進行引用時無法找到。在python中定義包的方法是在對應的文件夾下創建一個__init__.py的文件即可。
readExcel.py
讀取excel數據文件
1 import xlrd 2 3 4 # 讀取excel文件中對應row和cel數據信息 5 def readExcel(path,row,cel): 6 workBook = xlrd.open_workbook(path) 7 sheet = workBook.sheet_by_name("Sheet1") 8 value = sheet.cell(row,cel).value 9 return value
webConfig.py
配置對應的瀏覽器
1 # 配置使用的瀏覽器 2 browers = "Chrome"
pyselenium.py
對selenium的簡單封裝
1 from selenium import webdriver 2 from selenium.webdriver.common.action_chains import ActionChains 3 4 class pyselenium(): 5 # 初始化瀏覽器驅動 6 def __init__(self, browers="Chrome"): 7 if browers == "Chrome": 8 driver = webdriver.Chrome(r"./drivers/chromedriver.exe") 9 elif browers =="edge": 10 driver = webdriver.Edge() 11 elif browers == "fireFox": 12 driver = webdriver.Firefox() 13 else: 14 print("瀏覽器錯誤,請確認") 15 # raise 16 self.driver = driver 17 18 # 打開對應的url 19 def openUrl(self, url): 20 self.driver.get(url) 21 22 # 最大化瀏覽器窗口 23 def maxWindow(self): 24 self.driver.maximize_window() 25 26 # 通過不同的方式查找界面元素 27 def findElement(self,by,value): 28 if(by == "id"): 29 element = self.driver.find_element_by_id(value) 30 return element 31 elif(by == "name"): 32 element = self.driver.find_element_by_name(value) 33 return element 34 elif(by == "xpath"): 35 element = self.driver.find_element_by_xpath(value) 36 return element 37 elif(by == "classname"): 38 element = self.driver.find_element_by_class_name(value) 39 return element 40 elif(by == "css"): 41 element = self.driver.find_element_by_css_selector(value) 42 return element 43 elif(by == "link_text"): 44 element = self.driver.find_element_by_link_text(value) 45 return element 46 else: 47 print("無對應方法,請檢查") 48 return None 49 50 # 給指定元素發送值 51 def sendKeys(self,by,value,keys): 52 element = self.findElement(by,value) 53 element.send_keys(keys) 54 55 # 點擊頁面元素 56 def clinkElement(self,by,value): 57 element = self.findElement(by,value) 58 element.click() 59 60 # 鼠標懸停 61 def hover(self,by,value): 62 element = self.findElement(by,value) 63 ActionChains(self.driver).move_to_element(element).perform() 64 65 # 獲取標題 66 def getTitle(self): 67 return self.driver.title 68 69 # 退出瀏覽器 70 def quit(self): 71 self.driver.quit()
測試用例管理(cases)
test01.py,包括3個測試用例:
1 import unittest,time 2 from units import pyselenium 3 from units import readExcel,webConfig 4 5 class baiduTest(unittest.TestCase): 6 @classmethod 7 def tearDownClass(cls): 8 cls.driver.quit() 9 10 @classmethod 11 def setUpClass(cls): 12 cls.driver = pyselenium.pyselenium(webConfig.browers) 13 14 # 百度selenium,並判斷返回結果title 15 def testBaidu(self): 16 # 打開百度首頁 17 url = "http://www.baidu.com" 18 # self.driver.maxWindow() 19 self.driver.openUrl(url) 20 # 從excel文件中讀取並輸入搜索條件 21 sendData = readExcel.readExcel("./datas/test.xls",0,0) 22 self.driver.sendKeys(by="xpath",value="//*[@id='kw']",keys=sendData) 23 # 點擊搜索按鈕 24 self.driver.clinkElement(by="xpath",value="//*[@id='su']") 25 time.sleep(3) 26 title = self.driver.getTitle() 27 # 使用斷言驗證搜索后title和預期是否相等 28 self.assertEqual(title,"selenium_百度搜索") 29 30 # 百度登陸,並判斷是否正常登陸系統 31 def testLogin(self): 32 url = "http://www.baidu.com" 33 self.driver.openUrl(url) 34 time.sleep(3) 35 # 進入登錄頁面 36 self.driver.clinkElement(by="xpath",value="//*[@id='u1']/a[7]") 37 time.sleep(3) 38 self.driver.clinkElement(by="xpath",value="//*[@id='TANGRAM__PSP_10__footerULoginBtn']") 39 # 從excel文件中讀取並輸入用戶名密碼 40 userName = readExcel.readExcel("./datas/test.xls",1,0) 41 password = readExcel.readExcel("./datas/test.xls",1,1) 42 self.driver.sendKeys(by="name",value="userName",keys=userName) 43 self.driver.sendKeys(by="name",value="password",keys=password) 44 print("username:"+userName+",password:"+password) 45 self.driver.clinkElement(by="id",value="TANGRAM__PSP_10__submit") 46 time.sleep(3) 47 48 # 檢查是否存在用戶退出按鈕,存在,登錄成功,否則登錄失敗 49 self.driver.hover(by='xpath',value='//*[@id="s_username_top"]/span') 50 close = self.driver.findElement(by='xpath',value='//*[@id="s_user_name_menu"]/div/a[4]') 51 print(close) 52 if close != None: 53 self.assertEqual(1,1) 54 else: 55 self.assertEqual(1,0) 56 time.sleep(3) 57 58 def testLogout(self): 59 url = "http://www.baidu.com" 60 self.driver.openUrl(url) 61 time.sleep(3) 62 self.driver.hover(by='xpath',value='//*[@id="s_username_top"]/span') 63 self.driver.clinkElement(by='xpath',value='//*[@id="s_user_name_menu"]/div/a[4]') 64 time.sleep(3) 65 self.driver.clinkElement(by='xpath',value='//*[@id="tip_con_wrap"]/div[3]/a[3]') 66 time.sleep(3) 67 element = self.driver.findElement(by="xpath",value="//*[@id='u1']/a[7]") 68 self.assertEqual("登錄",element.text) 69 time.sleep(3)
測試用例中的相關說明:
- setup():每個測試函數運行前運行
- teardown():每個測試函數運行完后執行
- setUpClass():必須使用@classmethod 裝飾器,所有test運行前運行一次
- tearDownClass():必須使用@classmethod裝飾器,所有test運行完后運行一次
測試用例執行
run.py,使用HTMLTestRunner執行測試用例,並生成測試報告。
1 from units import HTMLTestRunner 2 import unittest 3 import time 4 5 # 構建測試用例集,設定對應的測試用例存放文件以及匹配方式 6 suite = unittest.defaultTestLoader.discover(start_dir='./cases/', pattern="test*.py") 7 8 now = time.strftime('%Y-%m-%d-%H-%M-%S-') 9 reportName = "./reports/%s測試報告.html" % now 10 11 with open(reportName, "wb") as f: 12 runner = HTMLTestRunner.HTMLTestRunner(stream=f, verbosity=2, title="測試報告", description="執行人:阿綠") 13 # 執行測試用例集 14 runner.run(suite)
執行run.py文件,查看reports文件夾下,生成對應的測試報告文件,打開文件即可查看對應的測試報告信息。
遇到的問題及解決過程
用例執行時無法找到對應的用例
現象:編寫了正確的用例目錄,但是使用unittest進行對應的用例執行時,用例執行個數為0,原因:再uniittest中,用例名稱中不能包含【-】,否則會發生兼容性問題。去除用例文件名稱中的標記【-】后,問題解決。
無法定位URL無效
執行用例時報錯:
1 unhandled inspector error: {"code":-32000,"message":"Cannot navigate to invalid URL"}
這個錯誤的意思是:“未經處理的檢查員錯誤:{“代碼”:32000,“消息”:“無法定位到URL無效”}”
全部代碼如下:
1 import unittest,time 2 from units import pyselenium 3 from units import readExcel,webConfig 4 5 class baiduTest(unittest.TestCase): 6 @classmethod 7 def tearDownClass(cls): 8 cls.driver.quit() 9 10 @classmethod 11 def setUpClass(cls): 12 cls.driver = pyselenium.pyselenium(webConfig.browers) 13 14 # 百度selenium,並判斷返回結果title 15 def testBaidu(self): 16 # 打開百度首頁 17 url = "http://www.baidu.com" 18 # self.driver.maxWindow() 19 self.driver.openUrl(url) 20 # 從excel文件中讀取並輸入搜索條件 21 sendData = readExcel.readExcel("./datas/test.xls",0,0) 22 self.driver.sendKeys(by="xpath",value="//*[@id='kw']",keys=sendData) 23 # 點擊搜索按鈕 24 self.driver.clinkElement(by="xpath",value="//*[@id='su']") 25 time.sleep(3) 26 title = self.driver.getTitle() 27 # 使用斷言驗證搜索后title和預期是否相等 28 self.assertEqual(title,"selenium_百度搜索")
解決辦法:將17行中的url修改為:http://www.baidu.com即可。
驅動版本不對應
報錯信息如下:
1 selenium.common.exceptions.WebDriverException: Message: unknown error: Runtime.executionContextCreated has invalid 'context': {"auxData":{"frameId":"DBC672A35E293863B4120F2CB4C90D48","isDefault":true},"id":1,"name":"","origin":"://"} 2 (Session info: chrome=69.0.3497.100) 3 (Driver info: chromedriver=2.9.248315,platform=Windows NT 6.3 x86_64)
原因:瀏覽器驅動不存在或者驅動不適用當前版本
解決辦法:到chrome瀏覽器驅動下載地址中(https://chromedriver.storage.googleapis.com/index.html)下載對應版本的驅動,對應替換即可。