一.命名要求
unittest對.py文件類沒有命名要求,只需要函數是以test為開頭的就可以
二.運行順序
不同於pytest(從上往下)的是,unittest運行順序是按照從0-9,A-Z,a-z的先後順序運行的
三.五大組件
1.testcase(測試用例)
(1)運行時可點擊類/函數左側綠色(當前類繼承unittest.TestCase才會出現)的開關。點擊函
數左側的錶示運行當前函數,點擊類左側的錶示運行當前類下的所有case
(2)運行時可將光標停留在類/函數冒號右側,鼠標右擊點擊run運行。光標停留在類名右側錶示
運行當前類下所有case,停留在具體函數名右側,錶示運行當前函數
(3)運行時可在main方法中unittest.main()來運行,運行順序按照:0-9,A-Z,a-z先後運行
class unittest_demo(unittest.TestCase): def test_one(self): print("我是one") def test_two(self): print("我是two")
2.testfixture(測試固件)
unittest中固件有兩種。setup和teardown每個函數運行前後會各運行一次。setupclass和teardownclass
錶示每個類運行前後會各運行一次。
(1)setup和teardown
這裏set_tear繼承了TestCase,然後又重寫了setup和teardown兩個前後置方法。我們在做自動化的時候
可用做前置准備工作和後置結束階段
class set_tear(unittest.TestCase): def setUp(self) -> None: print("進入www.baidu.com頁面") def tearDown(self) -> None: print("操作完畢,關閉瀏覽器頁面")
(2)setup_class和teardown_class
這個用法和上面相同,重寫時需要加上@classmethod,因為setupclass,和tearDownClass在testcase類
中為類方法
class set_tear(unittest.TestCase): @classmethod def setUpClass(cls) -> None: print("進入www.baidu.com頁面") @classmethod def tearDownClass(cls) -> None: print("操作完畢,關閉瀏覽器頁面")
3.testsuite(測試套件)
測試套件的作用簡單理解就是把你想要運行的case加到套件裏面去,然後通過運行器去運行。這樣可以選擇性
的運行case,可以改變case運行的順序。
(1)指定函數運行
運行的順序是按照你加入套件的先後順序來運行的
import unittest class unittest_suite(unittest.TestCase): def test_01(self): print("test_01") def test_02(self): print("test_02") def test_03(self): print("test_03") suite = unittest.TestSuite() # 創建一個套件 suite.addTest(unittest_suite("test_01")) # 添加case到套件中 suite.addTest(unittest_suite("test_02")) suite.addTest(unittest_suite("test_03"))
這裏也可以使用addtests方法添加一個數組到套件中
suite = unittest.TestSuite() # 創建一個套件 caseList = [unittest_suite("test_01"), unittest_suite("test_01"), unittest_suite("test_01")] suite.addTests(caseList)
(2)指定類運行
import unittest class unittest_suite(unittest.TestCase): def test_01(self): print("test_01") def test_02(self): print("test_02") def test_03(self): print("test_03") suite = unittest.TestSuite() # 創建一個套件 load = unittest.TestLoader() # 創建一個加載器 loadClass = load.loadTestsFromTestCase(unittest_suite) # 調用加載類的方法並傳入一個類 suite.addTest(loadClass) # 添加到套件中
運行順序按照原有類裏面的順序進行運行
(3)指定模塊(.py)運行
import testcase.demo_02 #導入要運行的.py suite = unittest.TestSuite() # 創建一個套件 load = unittest.TestLoader() # 創建一個加載器 loadClass = load.loadTestsFromModule(testcase.demo_02) #調用加載模塊的方法 suite.addTest(loadClass)
suite.countTestCases()#統計case個數
(4)指定路徑運行
suite = unittest.TestSuite() # 創建一個套件 load = unittest.TestLoader() # 創建一個加載器 suite.addTest(load.discover("./testcase", pattern="*02.py")) #調用discover方法指定路徑運行
pattern中匹配符*錶示通配符,可寫成test*.py錶示以test為開頭,*xx.py錶示以xx為結尾的都滿足。
需要注意的是這裏的路徑不能具體到某個.py模塊,模塊的匹配規則必須寫在pattern中
4.testrunner(運行器)
一般與testsuite一起用,來運行套件的
if __name__ == '__main__': runner = unittest.TextTestRunner() # 創建個運行器 runner.run(suite) # suite為套件集
5.testreport(測試報告)
這裏不多介紹了,感興趣的可以學習allure:https://www.cnblogs.com/lihongtaoya/p/15778263.html
四.spik用法
1.spik
錶示跳過該條case不執行
class unittest_suite(unittest.TestCase): def test_01(self): print("test_01") @unittest.skip def test_02(self): print("test_02") def test_03(self): print("test_03")
2.spikif()
判斷條件4>2,為true時不運行,打印標簽reason。為false運行該條case
class unittest_suite(unittest.TestCase): def test_01(self): print("test_01") @unittest.skipIf(4 > 2, reason="猪頭") def test_02(self): print("test_02") def test_03(self): print("test_03")
3.skipUnless()
和skipif()效果相反,判斷條件為true運行,為false不運行
class unittest_suite(unittest.TestCase): def test_01(self): print("test_01") @unittest.skipUnless(4 > 2, reason="猪頭") def test_02(self): print("test_02") def test_03(self): print("test_03")
五.ddt數據驅動(第三方的需要pip install ddt下載)
python裝飾器可參考:https://www.cnblogs.com/lihongtaoya/p/16368111.html
unittest中@ddt為類裝飾器,其它三個都是函數裝飾器。ddt
[email protected]
import unittest from ddt import ddt @ddt class unittest_ddt(unittest.TestCase): def testOne(self): pass
@ddt作用於類,錶示當前類使用ddt框架
[email protected]()
@data()主要用來傳值的(可傳int,str,list,set,dict,tuple)
(1)傳單個int/str值和多個int/str值
import unittest from ddt import ddt, data @ddt class unittest_ddt(unittest.TestCase): #@data(1, 2, 3) @data("1","2","3") def testOne(self, a): print(a)
這裏的a是用於接收傳遞過來的參數,打印結果為1,2,3
(2)傳單個set/list/tuple/
import unittest from ddt import ddt, data @ddt class unittest_ddt(unittest.TestCase): # @data((1,2,3))
# @data({1,2,3}) @data([1, 2, 3]) # 傳遞單個list def testOne(self, a): print(a)
運行結果:[1, 2, 3]||(1, 2, 3)
以上可以看出的是傳參時會把[1, 2, 3]和(1, 2, 3)當作一個整體傳給a,那麼如果我們想要單個值分別
傳遞給a。只需要在[1,2,3]前加上一個*號即可
@ddt class unittest_ddt(unittest.TestCase): # @data((1,2,3)) @data(*[1, 2, 3]) # 傳遞單個list def testOne(self, a): print(a)
運行結果:1 2 3
這裏*的作用就是去掉最外層的殼,既:[ ]和()
[email protected]()
當傳遞的參數含有多個值的時候,需要用的unpack來進行解包
@unpack()主要用來解包(去外殼)
(1)傳遞多個list/set/tuple
@ddt class unittest_ddt(unittest.TestCase): # @data((1,2,3)) # @data(*[1, 2, 3]) # 傳遞單個list @data((1,2,3),(4,5,6)) @unpack def testOne(self, a,b,c): print(a)
打印結果:1 4
這裏需要注意的是接收數據的參數個數(a,b,c)要和list/set/tuple中的數量相等
(2)dict類型
@ddt class unittest_ddt(unittest.TestCase): # @data((1,2,3)) # @data(*[1, 2, 3]) # 傳遞單個list @data({"name": "liming", "age": 123}, {"name": "lihua", "age": 123}) @unpack def testOne(self, name, age): print(name)
打印結果:liming lihua
傳遞dict數據類型的時候要保證接收數據的變量(name,age)要和dict中的key值一模一樣(數量和key值)
(3)傳遞嵌套的類型結構
import unittest from ddt import ddt, data, unpack datalist = [ { "name": "liming", "age": 12 }, { "name": "lihua", "age": 13 },{ "name": "lisan", "age": 18 } ] @ddt class unittest_ddt(unittest.TestCase): @data(*datalist) # 加*後數據結構變成:{},{} @unpack # 解包去外殼 def testOne(self, name, age): print(name)
[email protected]_data()
當yaml和json中的數據結構為[{},{},{}]時,@file_data()的作用就相當於@data()[email protected]()
@file_data()可直接讀取yaml和json文件
(1)首先我們先創建一個yaml文件
- username: liming password: 123456 - username: lifei password: 2
(2)在@file_data()中直接引用yaml文件即可
from ddt import ddt, data, unpack, file_data @ddt class unittest_ddt(unittest.TestCase): @file_data("../params/demo_01.yaml") def testOne(self,username,password): print(username)
這裏username和password也是要和yaml中的key值(數量)相等。json用法也是一樣,這裏不多介紹了。
5.csv做數據驅動
創建一個csv文件
liming,123
lifei,1234
導入csv,reader()方法讀取後加入list裏
with open("../params/demo_01.csv", mode="r", encoding="utf8")as a: da=csv.reader(a) data_list=[] for i in da: data_list.append(i)
當前data_list打印結果:[['liming', '123'], ['lifei', '1234']],然後再用data和unpack裝飾器即可
六.實例
下一章再寫吧,
注:網上已經一大堆教程了,不要轉載