【Python】单元测试框架unitest及其高级应用
Unittest
Unittest是python的一個(gè)單元測(cè)試框架,但是它不僅適用于單元測(cè)試,還適用自動(dòng)化測(cè)試用例的開(kāi)發(fā)與執(zhí)行。我們可以很方便的使用它組織執(zhí)行測(cè)試用例,使用它提供的豐富的斷言方法進(jìn)行測(cè)試結(jié)果比對(duì),并最終結(jié)合HTMLTestRunner生成測(cè)試報(bào)告完成整個(gè)自動(dòng)化測(cè)試流程。
簡(jiǎn)單使用示例
創(chuàng)建被測(cè)類calculator.py
class count:def _init_(self,a,b)self.a = int(a)self.b = int(b)#計(jì)算加法def add(self):return self.a + self.b通過(guò)unittest單元測(cè)試框架編寫(xiě)單元測(cè)試用例 test.py
from calculator import count import unitest class TestCount(unitest.TestCase):def setUp(self):print("test start")def test_add(self):j = count(2,3)self.assertEqual(j.add(),5)def tearDown(self):print("test end") if _name_ == '_main_':unittest.main()說(shuō)明:
重要概念
本例只執(zhí)行第二個(gè)測(cè)試用例,
斷言方法
unittest框架的TestCase類提供的斷言方法用于測(cè)試結(jié)果的判斷
判斷第一個(gè)參數(shù)和第二個(gè)參數(shù)是否相等
-assertEqual(first,second,msg=None) # 如果不相等則測(cè)試失敗,msg為可選參數(shù),用于定義測(cè)試失敗時(shí)打印的信息。 self.assertEqual(j.add(),15,msg="測(cè)試結(jié)果不等于15")格式:-assertNotEqual(first,second,msg=None)則與之相反
判斷表達(dá)式是true(或false)
-assertTrue(expr,msg=None) -assertFalse(expr,msg=None)創(chuàng)建count.py用于判斷質(zhì)數(shù)的
def is_prime(n):if n<=1:return Falsefor i in range(2,n):if n % i = = 0:return Falseretun True測(cè)試用例:調(diào)用is_prime()函數(shù)和unittest
self.assertTrue(is_prime(7),msg="is not prime")判斷第一個(gè)參數(shù)是否在第二個(gè)參數(shù)中,就是第二個(gè)參數(shù)是否包含第一個(gè)參數(shù)。
-assertIn(first,second,msg=None) -assertNotIn(first,second,msg=None)測(cè)試用例(部分):
def test_case(self):a = "hello"b = "hello world"self.assertIn(a,b,msg="a is not in b")判斷第一個(gè)參數(shù)和第二個(gè)參數(shù)是否為同一對(duì)象
-assertIs(first,second,msg=None) -assertIsNot(first,second,msg=None)判斷表達(dá)式是否為None對(duì)象
-assertIsNone(expr,msg=None) -assertIsNotNone(expr,msg=None)判斷obj是否為cls的一個(gè)實(shí)例格式:
-assertIsInstance(obj,cls,msg=None) -assertNotIsInstance(obj,cls,msg=None)深入
組織單元測(cè)試用例
- 方法1.setUp()和setDown方法分別作用于每個(gè)測(cè)試用例的開(kāi)始和結(jié)束
- 方法2.如果每個(gè)類中的setUp()和setDown方法所做的事情是一樣的,那么可以封裝成一個(gè)自己的測(cè)試類
discover更多測(cè)試用例
如果單元測(cè)試用例達(dá)到成百上千個(gè),可以將這些用例按照所測(cè)試的功能進(jìn)行拆分,分散到不同的測(cè)試文件中
最后再創(chuàng)建用于執(zhí)行所有測(cè)試用例的runtest.py文件。
- 方法1:可以通過(guò)addTest()加載TestCase到TestSuite中。用于少量的測(cè)試用例
方法2:使用TestLoader類提供的discover()方法來(lái)加載所有的測(cè)試用例。正常情況下,不需要?jiǎng)?chuàng)建這個(gè)類的實(shí)例,unittest提供了可以共享的defaultTestLoader類,可以使其子類和方法創(chuàng)建實(shí)例,discover()方法就是其中之一。
- discover(start_dir,pattern='test*.py',top_level_dir=None)
- start_dir:要測(cè)試的模塊名或測(cè)試用例的目錄
- pattern='test.py':表示用例文件名的匹配原則,此處文件名以“test”開(kāi)頭的“.py”類型的文件,“”表示任意多個(gè)字符。
- top_level_dir=None:測(cè)試模塊的頂層目錄,如果沒(méi)有頂層目錄,默認(rèn)為None.
用例執(zhí)行的原則
unittest框架默認(rèn)根據(jù)ASCII碼的順序加載測(cè)試用例,數(shù)字與字母的順序?yàn)?#xff1a;0-9,A-Z,a-z。所以TestAdd會(huì)優(yōu)于TestBdd類被執(zhí)行,test_aaa()方法會(huì)優(yōu)于test_ccc被執(zhí)行,因而它并沒(méi)有按照用例從上到下的順序執(zhí)行。
對(duì)于測(cè)試目錄和測(cè)試文件來(lái)說(shuō),unittest框架同樣是按照這個(gè)規(guī)則來(lái)加載測(cè)試用例的。
如果按照指定的順序執(zhí)行,可以通過(guò)TestSuite類的addTest()方法按照一定的順序加載。不能默認(rèn)main()方法了。需要構(gòu)造測(cè)試集,然后通過(guò)run()方法執(zhí)行測(cè)試。
注意:discover()的加載測(cè)試用例的規(guī)則與main()方法相同,所以只能通過(guò)測(cè)試用例的命名來(lái)提高被執(zhí)行的優(yōu)先級(jí)。
執(zhí)行多級(jí)的用例
discover()方法中的start_dir只能加載當(dāng)前目錄下的.py文件,如果加載子目錄下的.py文件,需在每個(gè)子目錄下放一個(gè)_init_.py文件。
跳過(guò)測(cè)試和預(yù)期失敗
unittest提供了實(shí)現(xiàn)某些需求的裝飾器,在執(zhí)行測(cè)試用例時(shí)每個(gè)裝飾前面加@符號(hào)。
- unittest.skip(reason):無(wú)條件的跳過(guò)裝飾的測(cè)試,說(shuō)明跳過(guò)測(cè)試的原因
- unittest.skipIf(condition,reason):跳過(guò)裝飾的測(cè)試,如果條件為真。
- unittest.skipUnless(condition,reason):跳過(guò)裝飾的測(cè)試,除非條件為真。
- unittest.expectedFailure():測(cè)試標(biāo)記為失敗,不管執(zhí)行結(jié)果是否失敗,統(tǒng)一標(biāo)記為失敗,但不會(huì)拋出錯(cuò)誤信息。
fixtures
fixtures可以形象的把他看作是夾心餅干外層的兩片餅干,這兩片餅干就是setUp/tearDown,中間的心就是測(cè)試用例,除此以外,unittest還提供了更大范圍的fixtures,例如對(duì)于測(cè)試類和模塊的fixtures。
- setUpModule/tearDownModule:在整個(gè)模塊的開(kāi)始和結(jié)束時(shí)被執(zhí)行。
- setUpClass/tearDownClass: 在測(cè)試類的開(kāi)始和結(jié)束時(shí)被執(zhí)行。
- setUp/tearDown:在測(cè)試用例的開(kāi)始與結(jié)束時(shí)被執(zhí)行
注意:setUpClass/tearDownClass的寫(xiě)法稍有不同,首先通過(guò)@classmethod進(jìn)行裝飾,其次方法的參數(shù)為cls,也可以是別的。每一個(gè)上面都要進(jìn)行裝飾
高級(jí)應(yīng)用
HTMLTestRunner
HTMLTestRunner是python標(biāo)準(zhǔn)庫(kù)unittest單元測(cè)試框架的一個(gè)拓展,它生成易于使用的HTML測(cè)試報(bào)告。
HTMLTestRunner下載地址:http://tungwaiyip.info/software/HTMLTestRunner.html
這個(gè)拓展只有一個(gè)HTMLTestRunner.py文件,選中后單擊鼠標(biāo)右鍵,在彈出的快捷菜單中選擇目標(biāo)另存為,將它保存到本地。安裝方法是將其復(fù)制到python安裝目錄下即可。
- windows:將下載的文件保存到...\python35\Lib目錄下
- Ubuntu:以root身份將HTMLTestRunner.py文件復(fù)制到/usr/local/python3.4/dist-packages/目錄下。
HTMLTestRunner.py文件是基于python2開(kāi)發(fā)的,若要支持python3環(huán)境需要對(duì)其中的部分內(nèi)容進(jìn)行修改。
生成HTML測(cè)試報(bào)告
description用于定義測(cè)試報(bào)告的副標(biāo)題。
更易讀的測(cè)試報(bào)告
方法:加注釋并用一種方法讀取
在類和方法的下方,通過(guò)三引號(hào)(""" """或''' ''')來(lái)添加docstring類型的注釋,這類注釋在平時(shí)調(diào)用的時(shí)候
不顯示,可以通過(guò)help()方法來(lái)查看類或方法的這種注釋。
HTMLTestRunner可以讀取docstring類型的注釋,所以只需給測(cè)試類或方法添加這種類型的注釋即可。
測(cè)試報(bào)告名稱建議
在每次運(yùn)行測(cè)試之前,都要手動(dòng)修改報(bào)告的名稱,如果忘記修改,就會(huì)把之前的報(bào)告覆蓋,為了使每次生成的報(bào)告名稱都不重復(fù)并且有意義,最好的方法是在報(bào)告名稱中加入當(dāng)前時(shí)間,這樣生成的報(bào)告既不會(huì)重疊,又能更清晰的知道報(bào)告的生成時(shí)間。
- time.time():獲取當(dāng)前時(shí)間戳 比如:1445694559.2290168
- time.ctime():當(dāng)前時(shí)間的字符串形式 比如:'sat oct 24 21:49:29 2015'
- time.localtime():當(dāng)前時(shí)間的struct_time形式 比如:tm_year=2015,tm_mon=10,tm_mday=24,..........等等。
- time.strftime("%Y_%m_%d %H:%M:%s"):用來(lái)獲得當(dāng)前時(shí)間,可以將時(shí)間格式化為字符串。比如:'2015_10_24 21:50:15'
方法:通過(guò)時(shí)間操作的方法以指定的格式獲取當(dāng)前時(shí)間,將當(dāng)前時(shí)間的字符串賦值給now變量,將now通過(guò)加號(hào)(+)拼接到生成的測(cè)試報(bào)告的文件名中,再次運(yùn)行測(cè)試用例,生成測(cè)試報(bào)告文件名。
項(xiàng)目集成測(cè)試報(bào)告
目前HTMLTestRunner只是針對(duì)單個(gè)測(cè)試文件生成測(cè)試報(bào)告,若要使其作用于整個(gè)測(cè)試項(xiàng)目,
要將它集成到runtest.py文件中,對(duì)其文件進(jìn)行修改。
認(rèn)識(shí)Page Object
Page Object設(shè)計(jì)模式的優(yōu)點(diǎn)
為web頁(yè)面編寫(xiě)測(cè)試時(shí),需要操作該web頁(yè)面上的元素,如果在測(cè)試代碼中直接操作HTML元素,那么你的代碼是極其脆弱的,因?yàn)閁I經(jīng)常變動(dòng)。我們可以將一個(gè)page對(duì)象封裝成一個(gè)HTML頁(yè)面,然后通過(guò)提供的應(yīng)用程序特定的API來(lái)操作頁(yè)面元素,而不是在HTML中四處搜尋。
page對(duì)象應(yīng)當(dāng)將在GUI控件上所有查詢和操作數(shù)據(jù)的行為封裝為方法,即使改變具體的控件,page對(duì)象的接口也不應(yīng)當(dāng)發(fā)生變化。
“頁(yè)面”對(duì)象不僅是針對(duì)每個(gè)頁(yè)面建立一個(gè)這樣的對(duì)象,對(duì)由重要意義的元素也可以獨(dú)立為一個(gè)page對(duì)象。
Page Object實(shí)例
轉(zhuǎn)載于:https://www.cnblogs.com/Detector/p/9157966.html
總結(jié)
以上是生活随笔為你收集整理的【Python】单元测试框架unitest及其高级应用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: BZOJ 1562 变换序列
- 下一篇: linux磁盘管理与分区 转载