20萬的慢慢會實現的吧,hhh
unittest框架,我就不在介紹了,百度有很詳細的介紹。
我們只要了解:
1、unittest是單元測試框架
2、它提供用例組織與執行:在實際工作中案例可能有上百條,我們就需要進行用例的組織以及規范,增強代碼的可維護性等
3、它提供豐富的比較方法:相等\不相等,包含\不包含,True\False的斷言方法等等
4、提供豐富的日志:例如,總執行時間、失敗用例數、成功用例數等
這就是別人造好的車,我們直接開。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
unittest組成部分:
TestCase:測試用例,測試用例里面會有很多測試方法,是單元測試中最小維度的測試行為
Test Fixure:測試固件,測試固件是執行測試時的准備工作和收尾工作(打開和關閉瀏覽器,鏈接和關閉數據庫等等)
TestSuite:測試套件,是測試用例的集合
TestRunner:測試運行器,運行測試用例
TestReport:將測試結果呈現給用戶,生成測試報告
接下來我們一點一點的學習,上面是大概整體的了
TestCase類中定義的方法: setUp(): ------> 該方法:進行測試前的初始化工作 tearDown(): ------> 該方法:進行執行測試后的清除工作(比如關閉瀏覽器)
我們看下代碼:
1 import unittest #導入unittest框架 2 3 class register(unittest.TestCase): #定義一個register類,並且繼承unittest中的TestCase類 4 5 def setUp(self): #TestCase類中定義的方法,setUp()進行測試前的初始化工作,所以它總是第一個執行 6 print('我已經做好了准備工作') 7 8 def tearDown(self): #TestCase類中定義的方法,tearDown()進行執行測試后的清除工作,所以它總是案例執行后最后執行 9 print('已處理') 10 11 def test_001(self): #第一個測試案例 12 print('案例_001') 13 14 def test_002(self): #第二個測試案例 15 print('案例_002') 16 17 if __name__ == '__main__': 18 unittest.main(verbosity=2) ##單元測試運行需要unittest.main(),作用是將一個單元測試模塊變成可以直接運行的測試腳本
verbosity是有三個值,每個值表示的測試結果信息不一樣。
0 (靜默模式): 你只能獲得總的測試用例數和總的結果 比如 總共100個 失敗20 成功80
1 (默認模式): 非常類似靜默模式 只是在每個成功的用例前面有個“.” 每個失敗的用例前面有個 “F”
2 (詳細模式):測試結果會顯示每個測試用例的所有相關的信息
我們看下運行后的setup 和 tearDown兩個方法的執行順序:
我相信你已經理解我的筆記意思,接下來我們繼續:
看下setup()和tearDown()方法與setupclass()和tearDownclass()方法的區別:
TestCase類中定義的方法:
setUp(): 該方法:進行測試前的初始化工作,每條案例都會執行一遍
tearDown(): 該方法:進行執行測試后的清除工作(比如關閉瀏覽器),每條案例都會執行一遍
敲黑板!!!注意加class后兩個方法的區別:
setUpClass() 該方法:進行測試前的初始化工作,與setUp()是有區別的,不會每個案例都執行一遍,只會在第一個案例開始前執行一次
tearDownClass() 該方法:進行測試前的初始化工作,與tearDown()是有區別的,不會每個案例都執行一遍,只會在最后一個案例結束后執行一次
'''
我們看下 setupclass()和 tearDownclass()方法在下面小案例中發生了什么:
1 import unittest #導入unittest 2 import time as t #導入time 設置別名 t 3 from selenium import webdriver #導入selenium中的webdriver 4 5 class page_baidu(unittest.TestCase): #定義一個類,並繼承unittest.TestCase類 6 7 @classmethod #使用 @classmethod 裝飾器函數,把方法變成類方法,可以直接調用方法,不需要實例化類對象就可以調用方法 8 def setUpClass(cls): ## setUpClass() 該方法:進行測試前的初始化工作,與setUp()是有區別的,不會每個案例都執行一遍, 9 cls.driver = webdriver.Chrome() #實例化webdriver()對象 10 cls.driver.maximize_window() #打開瀏覽器最大化 11 cls.driver.implicitly_wait(15) #隱性等待時間設置15秒,比如頁面加載打不開,我們最多等待15秒,適用於全局 12 cls.driver.get(r'http://www.baidu.com') #打開百度地址 13 t.sleep(2) #設置強制等待2秒,就是必須等待,用導入的time中的sleep方法,不是全局性,哪里需要設置到哪里,局部的 14 @classmethod 15 def tearDownClass(cls): #最后執行的工作 16 cls.driver.quit() #設置關閉瀏覽器 17 18 def test_baidu_news(self): #案例一 19 self.driver.find_element_by_link_text('新聞').click() #點擊百度頁面,超鏈接【新聞】兩個字 20 t.sleep(2) #設置強制等待2秒,就是必須等待,用導入的time中的sleep方法,不是全局性,哪里需要設置到哪里,局部的 21 22 def test_baidu_map(self): # 因為第一條案例執行后,setUpClass()方法沒有在第二條案例開始的時候進行初始化,所以導致沒有回到百度首頁,所以選擇text文本找不到‘新聞’兩個字的超鏈接,導致有異常出現。 23 self.driver.find_element_by_link_text('地圖').click() 24 t.sleep(2) 25 if __name__ =='__main__': 26 unittest.main(verbosity=2) #單元測試運行需要unittest.main(),作用是將一個單元測試模塊變成可以直接運行的測試腳本
我們看下執行后的結果:
如果仔細看了我的筆記,或者你運行了代碼,那么你應該知道為啥失敗了吧~~~如果不知道,歡迎留言,一起學習
接下來我們看下setUp() 和 tearDown() 方法:
1 import unittest #導入unittest 2 import time as t #導入time 設置別名 t 3 from selenium import webdriver #導入selenium中的webdriver 4 5 class page_baidu(unittest.TestCase): #定義一個類,並繼承unittest.TestCase類 6 7 @classmethod #使用 @classmethod 裝飾器函數,把方法變成類方法,可以直接調用方法,不需要實例化類對象就可以調用方法 8 def setUp(cls): ## setUpClass() 該方法:進行測試前的初始化工作,每條案例開始前都會進行一次 9 cls.driver = webdriver.Chrome() #實例化webdriver()對象 10 cls.driver.maximize_window() #打開瀏覽器最大化 11 cls.driver.implicitly_wait(15) #隱性等待時間設置15秒,比如頁面加載打不開,我們最多等待15秒,適用於全局 12 cls.driver.get(r'http://www.baidu.com') #打開百度地址 13 t.sleep(2) #設置強制等待2秒,就是必須等待,用導入的time中的sleep方法,不是全局性,哪里需要設置到哪里,局部的 14 @classmethod 15 def tearDown(cls): #最后執行的工作,每條案例開始前都會進行一次 16 cls.driver.quit() #設置關閉瀏覽器 17 18 def test_baidu_news(self): #案例一 19 self.driver.find_element_by_link_text('新聞').click() #點擊百度頁面,超鏈接【新聞】兩個字 20 t.sleep(2) #設置強制等待2秒,就是必須等待,用導入的time中的sleep方法,不是全局性,哪里需要設置到哪里,局部的 21 22 def test_baidu_map(self): # 因為第一條案例執行后,setUp()方法在第二條案例開始的時候,先進行初始化,所以可以在百度首頁,找到‘新聞’兩個字的超鏈接。 23 self.driver.find_element_by_link_text('地圖').click() 24 t.sleep(2) 25 if __name__ =='__main__': 26 unittest.main(verbosity=2) #單元測試運行需要unittest.main(),作用是將一個單元測試模塊變成可以直接運行的測試腳本
為什么setUp() 和 tearDown() 方法可以將兩條案例都執行通過,我想你們應該明白了!!
那么仔細的你會發現案例中的兩個案例是這樣的;
1 def test_baidu_news(self): #案例一 2 self.driver.find_element_by_link_text('新聞').click() #點擊百度頁面,超鏈接【新聞】兩個字 3 t.sleep(2) #設置強制等待2秒,就是必須等待,用導入的time中的sleep方法,不是全局性,哪里需要設置到哪里,局部的 4 5 def test_baidu_map(self): # 因為第一條案例執行后,setUp()方法在第二條案例開始的時候,先進行初始化,所以可以在百度首頁,找到‘新聞’兩個字的超鏈接。 6 self.driver.find_element_by_link_text('地圖').click() 7 t.sleep(2)
執行結果是這樣滴:
不要慌,看筆記:
test_baidu_map ()
test_baidu_news()
之所以先執行是,因為會對名字進行比較,兩條案例名字的前半部分都是一樣的,但是到m和n的時候就不一樣了,在ASCLL碼中將m和n分別轉換為數字后:
函數: ord() 它以一個字符(長度為1的字符串)作為參數,返回對應的 ASCII 數值.看清楚哦,是一個字符,不要輸入多個哦。
1 print('m轉換為ASCLL碼是數字: ',ord('m')) 2 3 print('n轉換為ASCLL碼是數字: ',ord('n')) 4 5 print('我們發現m=109,n=110,所以執行的順序是先執行109')
什么是ASCII碼:自己百度哦,下面附上百度找到的常見的對照,還有哦,小寫字母和大寫字母的數字是不一樣的!!看下面的圖吧,如果不理解留言哦
在我們知道了unittest框架執行的順序規則后,我們可以直接用數字,讓案例從我們要求的順序開始執行。
注意:執行順序是按照數字從小到大執行。
1 import unittest #導入unittest 2 import time as t #導入time 設置別名 t 3 from selenium import webdriver #導入selenium中的webdriver 4 5 class page_baidu(unittest.TestCase): #定義一個類,並繼承unittest.TestCase類 6 7 @classmethod #使用 @classmethod 裝飾器函數,把方法變成類方法,可以直接調用方法,不需要實例化類對象就可以調用方法 8 def setUp(cls): 9 cls.driver = webdriver.Chrome() 10 cls.driver.maximize_window() 11 cls.driver.implicitly_wait(15) 12 cls.driver.get(r'http://www.baidu.com') 13 t.sleep(2) 14 @classmethod 15 def tearDown(cls): 16 cls.driver.quit() 17 18 def test_baidu_001(self): #案例001 測試進入百度新聞界面 19 self.driver.find_element_by_link_text('新聞').click() #點擊百度頁面,超鏈接【新聞】兩個字 20 t.sleep(2) #設置強制等待2秒,就是必須等待,用導入的time中的sleep方法,不是全局性,哪里需要設置到哪里,局部的 21 22 def test_baidu__002(self): #案例002 測試進入百度地圖界面 23 self.driver.find_element_by_link_text('地圖').click() ##點擊百度頁面,超鏈接【地圖】兩個字 24 t.sleep(2) 25 if __name__ =='__main__': 26 unittest.main(verbosity=2) #單元測試運行需要unittest.main(),作用是將一個單元測試模塊變成可以直接運行的測試腳本
順序的問題我們清楚了,可是如果我們真的有上百條案了,當測試結果和上面的圖一樣的時候,我們還是會懵逼,比如測試結果第二條失敗,那么第二條的測試內容測試點是什么?如果有上百條的test_baidu_00N 我們會記不住的,所以我們再次優化:我們在測試案例的方法中添加了注釋
1 import unittest #導入unittest 2 import time as t #導入time 設置別名 t 3 from selenium import webdriver #導入selenium中的webdriver 4 5 class page_baidu(unittest.TestCase): #定義一個類,並繼承unittest.TestCase類 6 7 @classmethod #使用 @classmethod 裝飾器函數,把方法變成類方法,可以直接調用方法,不需要實例化類對象就可以調用方法 8 def setUp(cls): 9 cls.driver = webdriver.Chrome() 10 cls.driver.maximize_window() 11 cls.driver.implicitly_wait(15) 12 cls.driver.get(r'http://www.baidu.com') 13 t.sleep(2) 14 @classmethod 15 def tearDown(cls): 16 cls.driver.quit() 17 18 '''以下案例是測試百度首頁鏈接''' 19 def test_baidu_001(self): #案例001 測試進入百度新聞界面 20 '''測試百度首新聞鏈接''' 21 self.driver.find_element_by_link_text('新聞').click() #點擊百度頁面,超鏈接【新聞】兩個字 22 t.sleep(2) #設置強制等待2秒,就是必須等待,用導入的time中的sleep方法,不是全局性,哪里需要設置到哪里,局部的 23 24 def test_baidu_002(self): #案例002 測試進入百度地圖界面 25 '''測試百度首地圖鏈接''' 26 self.driver.find_element_by_link_text('').click() ##點擊百度頁面,超鏈接【地圖】兩個字 27 t.sleep(2) 28 self.driver.back() 29 30 '''以下案例是測試百度首頁搜索''' 31 def test_baidu_003(self): 32 '''測試百度首頁搜索功能''' 33 self.driver.find_element_by_id('kw').send_keys('你好朋友') 34 if __name__ =='__main__': 35 unittest.main(verbosity=2) #單元測試運行需要unittest.main(),作用是將一個單元測試模塊變成可以直接運行的測試腳本
這樣即使我們有上百條案例,哪里出錯后,我們都可以直觀的看到,是那個測試點失敗了。所以寫測試案例的規范一定要遵守,給自己也給后面維護代碼的人方便。
unittest組成部分:
TestCase:測試用例,測試用例里面會有很多測試方法,是單元測試中最小維度的測試行為
Test Fixure:測試固件,測試固件是執行測試時的准備工作和收尾工作(打開和關閉瀏覽器,鏈接和關閉數據庫等等)
TestSuite:測試套件,是測試用例的集合
TestRunner:測試運行器,運行測試用例
TestReport:將測試結果呈現給用戶,生成測試報告
總結:測試固件的學習就是這么多了,后續有特殊的地方在單獨筆記
1、知道了setup() & tearDown() 兩個方法的用法
2、了解了setup() & tearDown() 與 setupClass() & tearDownClass() 他們之前的區別
3、知道了運行的順序
4、對案例編寫的規范有了一定程度的認識