個人覺得使用python標準庫中的Unittest搭建自動化測試框架很好用所以在這里做個筆記。
其實想要清楚Unittest內部邏輯看懂這張類圖即可溢吻,夫圖之缺如铆铆,豈不若言之大D建车,不多BB。
Unittest模塊核心概念非為四層先后順序可以為TestFixture->TestCase->TestSuite->TestRunner
Surprise MotherF*cker 跟這個圖有什么關系呢裳凸?別急慢慢聽我說贱鄙。
圖由下到上details
- TestCase簡單說就是測試樣例,就是有一個完善的測試流程姨谷。
Setup(準備測試環(huán)境)-> Run(運行測試)-> Teardown(測試結束逗宁,環(huán)境恢復)
Unittest 本質也在這里,單元即在不可分梦湘,一個單元即一個完整的測試單元瞎颗。 - TestSuite是可以打包testcase的嵌套工具,將每個類型的單元測試歸類等践叠,PS:TestSuite可以嵌套TestSuite言缤。
- TestLoader中的loadTestsFrom方法搜尋TestCase并加載到TestSuite中
- TestRunner跑TestSuite中的TestCase并生成result
- TestFixture則是面對測試用例的環(huán)境搭建與銷毀
一個類繼承了Unittest了以后便是一個測試用例,而class中的方法(以test名稱開頭的方法)禁灼,會在TestLoaderd的時候被加載到TestCase中并生成對應實例管挟,然后如果被加載在TestSuite中也是不變的實例
Process梳理:
完成TestCase內容,由TestLoadFrom將其加載到TestSuite中弄捕,然后TestRunner測試輸出結果到TestResult
Unittest實例:
直接測TestCase
這里寫好待測方法
)
然后把對這些方法使用Unittest進行測試
PS:
補充一下unittest.main()就是把TestCase交給TestRunner僻孝,并打印結果到結果欄(也可以寫入文件)导帝,
并且可以在unittest.main()中加入verbosity=0/1/2(數(shù)字表示log詳細程度)
把TestCase打包到TestSuite中并測試
使用addTest()一個一個或者將testcase寫進列表不實用
個人覺得這樣手動添加testcase實在!4┟您单!麻煩,遂使用load功能把testcase中開頭帶test字樣的全部加載進來
suite.addTests(unittest.TestLoader().loadTestsFromName('test_mathfunc.TestMathFunc'))
這樣可以加載test_mathfunc模塊中TestMathFunc實例中所有的testcase荞雏,加載TestCase的順序是無序的虐秦,可以核對一下打印結果和TestCase實例中的待測def
將日志打印成文檔
python中使用with open 打開文件做文件流處理很方便,不需要手動close不需要擔心內存泄漏凤优,一切垃圾回收機制搞定悦陋。(面試的時候有可能會問python中的垃圾回收機制,建議好好看一下筑辨。因為樓主Java很久不用了堆垃圾回收機制概念清楚但是深層原理不記得了俺驶,這時面試官問,我就會說我目前清楚python的棍辕,java很久不用了XXXXXXX)
加上如下coding
with open('UnittestTextReport.txt', 'a') as f:
runner = unittest.TextTestRunner(stream=f, verbosity=2)
runner.run(suite)
環(huán)境準備與恢復TestFixture
如果我們有這樣兩個testcase暮现,1.登陸一個網站(正確的account&pwd)2.登陸一個網站(非法用戶名&pwd).第一個測試樣例進行完必須要退出,清理緩存這樣最好楚昭,然后進行第二個測試樣例的測試栖袋。
這時候TestFixture的setup()和TearDown()就有作用了。
def setUp(self):
print "do something before test.Prepare environment."
def tearDown(self):
print "do something after test.Clean up."
將其添加到testcase中哪替,類似于魔法方法栋荸,每有一個測試樣例開始走unittest的框架流程時菇怀,就會在開始處調用setup()搭建初始化環(huán)境凭舶,結束時恢復至剛開始測試的環(huán)境。
如果想要在所有case執(zhí)行之前準備一次環(huán)境爱沟,并在所有case執(zhí)行結束之后再清理環(huán)境帅霜,我們可以用 setUpClass() 與 tearDownClass():
class TestMathFunc(unittest.TestCase):
"""Test mathfuc.py"""
@classmethod
def setUpClass(cls):
print "This setUpClass() method only called once."
@classmethod
def tearDownClass(cls):
print "This tearDownClass() method only called once too."
有些人可能對@classmethod感到陌生或者不熟悉,好吧既然說到這里了呼伸,就插播一個python知識點身冀。
python中的classmethod與staticmethod
@classmethod是類方法
@staticmethod是靜態(tài)方法
那么有什么區(qū)別呢?
來寫一個簡單的類觀察下
class A(object):
def m1(self,n):
print("self:",self)
@classmethod
def m2(cls,n):
print ("cls:",cls)
@staticmethod
def m3(n):
print ("n",n)
a = A()
a.m1(1)
A.m2(1)
a.m3(1)
輸出為
一般來說如果要使用某個類的方法,必須實例化該類的對象后再調用該類中的方法括享,self將該方法綁定在了對象身上搂根,這個結果能看出一些問題,self大家應該不陌生是綁定在類實例化的對象的铃辖,而cls則是綁定在類A身上的剩愧。
那么staticmethod和self綁定的類中用法又有什么區(qū)別呢,兩者都可以通過實例化對象.類方法()來調用類方法或者類屬性娇斩,但是self可以在內部調用仁卷,而staticmethod只能依靠前面一種方法穴翩。
那么classmethod和staticmethod又有什么區(qū)別?
顯然大家應該有一些想法了锦积,就是classmethod作為一個裝飾器他可以在類未被實例化前就可以執(zhí)行classmethod下面的語句芒帕,他是屬于類的可以使用類名.類方法/類屬性來調用。
Well,in one word. 就是staticmethod是靜態(tài)的調用類或者對象屬性都可以丰介,但是不可以內部自身調用背蟆,class method修飾作用在于類可以調用,而self最大特點是內部可以進行調用哮幢。
那么這(classmethod)又有什么用呢淆储?
有這種民工三連問題就對了,看下面例子家浇。
用戶輸入的是2018 5 5 但是如果輸入format變?yōu)?018.5.5,重構類的時候最好不要修改原有的構造函數(shù)本砰,只需要添加classmethod和你額外的處理函數(shù)即可。
如下:
繞了一大圈钢悲,終于回來了点额,繼續(xù)說Unittest
如果執(zhí)行到某個testcase你想跳過去呢?
skip裝飾器即可-->@unittest.skip
Just like this 莺琳,這樣就可以在打印臺上或者文檔中看到記錄該testcase已經被跳過
skip裝飾器一共有三個
unittest.skip(reason)
unittest.skipIf(condition, reason)
unittest.skipUnless(condition,reason)
skip無條件跳過还棱,skipIf當condition為True時跳過,skipUnless當condition為False時跳過惭等。
根據(jù)自己情況去pick珍手。
總結一下:
unittest是Python自帶的單元測試框架,我們可以用其來作為我們自動化測試框架的用例組織執(zhí)行框架辞做。
unittest的流程:寫好TestCase琳要,然后由TestLoader加載TestCase到TestSuite,然后由TextTestRunner來運行TestSuite秤茅,運行的結果保存在TextTestResult中稚补,我們通過命令行或者unittest.main()執(zhí)行時,main會調用TextTestRunner中的run來執(zhí)行框喳,或者我們可以直接通過TextTestRunner來執(zhí)行用例课幕。
一個class繼承unittest.TestCase即是一個TestCase,其中以 test 開頭的方法在load時被加載為一個真正的TestCase五垮。
verbosity參數(shù)可以控制執(zhí)行結果的輸出乍惊,0 是簡單報告、1 是一般報告放仗、2 是詳細報告润绎。
可以通過addTest和addTests向suite中添加case或suite,可以用TestLoader的loadTestsFrom__()方法。
用 setUp()凡橱、tearDown()小作、setUpClass()以及 tearDownClass()可以在用例執(zhí)行前布置環(huán)境,以及在用例執(zhí)行后清理環(huán)境
我們可以通過skip稼钩,skipIf顾稀,skipUnless裝飾器跳過某個case,或者用TestCase.skipTest方法坝撑。
參數(shù)中加stream静秆,可以將報告輸出到文件:可以用TextTestRunner輸出txt報告。