日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python单元测试之unittest框架使用

發(fā)布時間:2025/3/20 python 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python单元测试之unittest框架使用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、什么是單元測試

單元測試是用來對一個模塊、一個函數(shù)或者一個類來進(jìn)行正確性檢驗(yàn)的測試工作。

比如對于函數(shù)abs(),我們可以編寫的測試用例為:

(1)輸入正數(shù),比如1、1.2、0.99,期待返回值與輸入相同

(2)輸入復(fù)數(shù),比如-1、-1.2、-0.99,期待返回值與輸入相反

(3)輸入0,期待返回0

(4)輸入非數(shù)值類型,比如None、[]、{}、期待拋出TypeError

把上面這些測試用例放到一個測試模塊里,就是一個完整的單元測試

?

二、unittest工作原理

unittest中最核心的四部分是:TestCase,TestSuite,TestRunner,TestFixture

(1)一個TestCase的實(shí)例就是一個測試用例。測試用例就是指一個完整的測試流程,包括測試前準(zhǔn)備環(huán)境的搭建(setUp),執(zhí)行測試代碼(run),以及測試后環(huán)境的還原(tearDown)。元測試(unit test)的本質(zhì)也就在這里,一個測試用例是一個完整的測試單元,通過運(yùn)行這個測試單元,可以對某一個問題進(jìn)行驗(yàn)證。

(2)而多個測試用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite。

(3)TestLoader是用來加載TestCase到TestSuite中的。

(4)TextTestRunner是來執(zhí)行測試用例的,其中的run(test)會執(zhí)行TestSuite/TestCase中的run(result)方法

(5)測試的結(jié)果會保存到TextTestResult實(shí)例中,包括運(yùn)行了多少測試用例,成功了多少,失敗了多少等信息。

?

綜上,整個流程就是首先要寫好TestCase,然后由TestLoader加載TestCase到TestSuite,然后由TextTestRunner來運(yùn)行TestSuite,運(yùn)行的結(jié)果保存在TextTestResult中,整個過程集成在unittest.main模塊中。

?

三、下面舉兩個實(shí)例,來看看unittest如何測試一個簡單的函數(shù)

(1)編寫一個Dict類,這個類的行為和dict一致,但是可以通過屬性來訪問例如

[python] view plaincopy
  • >>>?d?=?Dict(a=1,?b=2)??
  • >>>?d['a']??
  • 1??
  • >>>?d.a??
  • 1??
  • ?

    mydict.py代碼如下:

    [python] view plaincopy
  • class?Dict(dict):??
  • ????def?__init__(self,?**kw):??
  • ????????super(Dict,?self).__init__(**kw)??
  • ???
  • ????def?__getattr__(self,?key):??
  • ????????try:??
  • ????????????return?self[key]??
  • ????????except?KeyError:??
  • ????????????raise?AttributeError(r"'Dict'?object?has?no?attribute?'%s'"?%?key)??
  • ???
  • ????def?__setattr__(self,?key,?value):??
  • ????????self[key]?=?value??
  • ???


  • 用于測試的文件mydict_test.py代碼如下:

    [python] view plaincopy
  • import?unittest??
  • from?mydict?import?Dict??
  • ???
  • ???
  • class?TestDict(unittest.TestCase):??
  • ????def?test_init(self):??
  • ????????d?=?Dict(a=1,?b='test')??
  • ????????self.assertEqual(d.a,?1)??#?判斷d.a是否等于1??
  • ????????self.assertEqual(d.b,?'test')??#?判斷d.b是否等于test??
  • ????????self.assertTrue(isinstance(d,?dict))??#?判斷d是否是dict類型??
  • ???
  • ????def?test_key(self):??
  • ????????d?=?Dict()??
  • ????????d['key']?=?'value'??
  • ????????self.assertEqual(d.key,?'value')??
  • ???
  • ????def?test_attr(self):??
  • ????????d?=?Dict()??
  • ????????d.key?=?'value'??
  • ????????self.assertTrue('key'?in?d)??
  • ????????self.assertEqual(d['key'],?'value')??
  • ???
  • ????def?test_keyerror(self):??
  • ????????d?=?Dict()??
  • ????????with?self.assertRaises(KeyError):??#?通過d['empty']訪問不存在的key時,斷言會拋出keyerror??
  • ????????????value?=?d['empty']??
  • ???
  • ????def?test_attrerror(self):??
  • ????????d?=?Dict()??
  • ????????with?self.assertRaises(AttributeError):??#?通過d.empty訪問不存在的key時,我們期待拋出AttributeError??
  • ????????????value?=?d.empty??
  • ???
  • ???
  • if?__name__?==?'__main__':??
  • ????unittest.main()??


  • 直接把mydict_test.py當(dāng)普通的Python腳本運(yùn)行即可

    輸出:

    [python] view plaincopy
  • .....??
  • ----------------------------------------------------------------------??
  • Ran?5?tests?in?0.000s??
  • ???
  • OK??


  • (2)測一個簡單的加減乘除接口

    mathfunc.py文件代碼如下:

    [python] view plaincopy
  • def?add(a,?b):??
  • ????return?a?+?b??
  • ???
  • def?minus(a,?b):??
  • ????return?a?-?b??
  • ???
  • def?multi(a,?b):??
  • ????return?a?*?b??
  • ???
  • def?divide(a,?b):??
  • ????return?a?/?b??

  • test_mathfunc.py文件代碼如下:

    [python] view plaincopy
  • import?unittest??
  • from?mathfunc?import?*??
  • ???
  • ???
  • class?TestMathFunc(unittest.TestCase):??
  • ???
  • ????def?test_add(self):??
  • ????????self.assertEqual(3,?add(1,?2))??
  • ????????self.assertNotEqual(3,?add(2,?2))??
  • ???
  • ????def?test_minus(self):??
  • ????????self.assertEqual(1,?minus(3,?2))??
  • ???
  • ????def?test_multi(self):??
  • ????????self.assertEqual(6,?multi(3,?2))??
  • ???
  • ????def?test_divide(self):??
  • ????????self.assertEqual(2,?divide(6,?3))??
  • ????????self.assertEqual(2.5,?divide(5,?2))??
  • ???
  • if?__name__?==?'__main__':??
  • <span?style="white-space:pre;">?</span>unittest.main()??

  • 輸出:

    [python] view plaincopy
  • .F..??
  • ======================================================================??
  • FAIL:?test_divide?(__main__.TestDict)??
  • ----------------------------------------------------------------------??
  • Traceback?(most?recent?call?last):??
  • ??File?"D:/pythonWorkspace/test_mathfunc.py",?line?20,?in?test_divide??
  • ????self.assertEqual(2.5,?divide(5,?2))??
  • AssertionError:?2.5?!=?2??
  • ???
  • ----------------------------------------------------------------------??
  • Ran?4?tests?in?0.000s??
  • ???
  • FAILED?(failures=1)??

  • 可以看到一共運(yùn)行了4個測試,失敗了1個,并且給出了失敗原因,2.5!=2,也就是說我們的divide方法是有問題的。

    ?

    關(guān)于輸出的幾點(diǎn)說明:

    1、在第一行給出了每一個用例執(zhí)行的結(jié)果的標(biāo)識,成功是.,失敗是F,出錯是E,跳過是S。從上面可以看出,測試的執(zhí)行跟方法的順序沒有關(guān)系,divide方法寫在了第4個,但是卻在第2個執(zhí)行。

    2、每個測試方法均以test開頭,否則不能被unittest識別

    3、在uniitest.main()中加verbosity參數(shù)可以控制輸出的錯誤報告的詳細(xì)程度,默認(rèn)是1,如果設(shè)為0, 則不輸出每一用例的執(zhí)行結(jié)果,即沒有上面的結(jié)果中的第1行,如果設(shè)為2,則輸出詳細(xì)的執(zhí)行結(jié)果,如下所示:

    ?

    [python] view plaincopy
  • test_add?(__main__.TestMathFunc)?...?ok??
  • test_divide?(__main__.TestMathFunc)?...?FAIL??
  • test_minus?(__main__.TestMathFunc)?...?ok??
  • test_multi?(__main__.TestMathFunc)?...?ok??
  • ???
  • ======================================================================??
  • FAIL:?test_divide?(__main__.TestMathFunc)??
  • ----------------------------------------------------------------------??
  • Traceback?(most?recent?call?last):??
  • ??File?"D:/pythonWorkspace/test_mathfunc.py",?line?20,?in?test_divide??
  • ????self.assertEqual(2.5,?divide(5,?2))??
  • AssertionError:?2.5?!=?2??
  • ???
  • ----------------------------------------------------------------------??
  • Ran?4?tests?in?0.000s??
  • ???
  • FAILED?(failures=1)??


  • 四、組織TestSuite

    上面的測試用例在執(zhí)行的時候沒有按照順序執(zhí)行,如果想要讓用例按照你設(shè)置的順序執(zhí)行就用到了TestSuite。我們添加到TestSuite中的case是會按照添加的順序執(zhí)行的。

    現(xiàn)在我們只有一個測試文件,如果有多個測試文件,也可以用TestSuite組織起來。

    繼續(xù)上面第二加減乘除的例子,現(xiàn)在再新建一個文件,test_suite.py,代碼如下:

    [python] view plaincopy
  • #?coding=utf-8??
  • import?unittest??
  • from?test_mathfunc?import?TestMathFunc??
  • ???
  • if?__name__?==?'__main__':??
  • ????suite?=?unittest.TestSuite()??
  • ???
  • ????tests?=?[TestMathFunc("test_add"),?TestMathFunc("test_minus"),?TestMathFunc("test_divide")]??
  • ????suite.addTests(tests)??
  • ???
  • ????runner?=?unittest.TextTestRunner(verbosity=2)??
  • ????runner.run(suite)??

  • 執(zhí)行結(jié)果如下:

    [python] view plaincopy
  • test_add?(test_mathfunc.TestMathFunc)?...?ok??
  • test_minus?(test_mathfunc.TestMathFunc)?...?ok??
  • test_divide?(test_mathfunc.TestMathFunc)?...?FAIL??
  • ???
  • ======================================================================??
  • FAIL:?test_divide?(test_mathfunc.TestMathFunc)??
  • ----------------------------------------------------------------------??
  • Traceback?(most?recent?call?last):??
  • ??File?"D:\pythonWorkspace\HTMLTest\test_mathfunc.py",?line?20,?in?test_divide??
  • ????self.assertEqual(2.5,?divide(5,?2))??
  • AssertionError:?2.5?!=?2??
  • ???
  • ----------------------------------------------------------------------??
  • Ran?3?tests?in?0.000s??
  • ???
  • FAILED?(failures=1)??

  • 五、將結(jié)果輸出到文件

    現(xiàn)在我們的測試結(jié)果只能輸出到控制臺,現(xiàn)在我們想將結(jié)果輸出到文件中以便后續(xù)可以查看。

    將test_suite.py進(jìn)行一點(diǎn)修改,代碼如下:

    [python] view plaincopy
  • #?coding=utf-8??
  • ???
  • import?unittest??
  • from?test_mathfunc?import?TestMathFunc??
  • ???
  • if?__name__?==?'__main__':??
  • ????suite?=?unittest.TestSuite()??
  • ???
  • ????tests?=?[TestMathFunc("test_add"),?TestMathFunc("test_minus"),?TestMathFunc("test_divide")]??
  • ????suite.addTests(tests)??
  • ???
  • ????with?open('UnittestTextReport.txt',?'a')?as??f:??
  • ????????runner?=?unittest.TextTestRunner(stream=f,?verbosity=2)??
  • ????????runner.run(suite)??
  • ???

  • 運(yùn)行該文件,就會發(fā)現(xiàn)目錄下生成了'UnittestTextReport.txt,所有的執(zhí)行報告均輸出到了此文件中。

    ?

    六、test fixture的setUp和tearDown

    當(dāng)遇到要啟動一個數(shù)據(jù)庫這種情況時,只想在開始時連接上數(shù)據(jù)庫,在結(jié)束時關(guān)閉連接。那么可以使用setUp和tearDown函數(shù)。

    [python] view plaincopy
  • class?TestDict(unittest.TestCase):??
  • ???
  • ????def?setUp(self):??
  • ????????print?'setUp...'??
  • ???
  • ????def?tearDown(self):??
  • ????????print?'tearDown...'??


  • 這兩個方法在每個測試方法執(zhí)行前以及執(zhí)行后執(zhí)行一次,setUp用來為測試準(zhǔn)備環(huán)境,tearDown用來清理環(huán)境,以備后續(xù)的測試。

    ?

    如果想要在所有case執(zhí)行之前準(zhǔn)備一次環(huán)境,并在所有case執(zhí)行結(jié)束之后再清理環(huán)境,我們可以用setUpClass()與tearDownClass(),代碼格式如下:

    [python] view plaincopy
  • class?TestMathFunc(unittest.TestCase):??
  • ????@classmethod??
  • ????def?setUpClass(cls):??
  • ????????print?"setUp"??
  • ??
  • ????@classmethod??
  • ????def?tearDownClass(cls):??
  • ????????print?"tearDown"??


  • 七、跳過某個case

    unittest提供了幾種方法可以跳過case

    (1)skip裝飾器

    ?

    代碼如下

    [python] view plaincopy
  • #?coding=utf-8??
  • import?unittest??
  • from?mathfunc?import?*??
  • ???
  • class?TestMathFunc(unittest.TestCase):??
  • ???
  • ?????.....??
  • ??
  • ????@unittest.skip("i?don't?want?to?run?this?case.")??
  • ????def?test_minus(self):??
  • ????????self.assertEqual(1,?minus(3,?2))??


  • 輸出:

    [python] view plaincopy
  • test_add?(test_mathfunc.TestMathFunc)?...?ok??
  • test_minus?(test_mathfunc.TestMathFunc)?...?skipped?"i?don't?want?to?run?this?case."??
  • test_divide?(test_mathfunc.TestMathFunc)?...?FAIL??
  • ???
  • ======================================================================??
  • FAIL:?test_divide?(test_mathfunc.TestMathFunc)??
  • ----------------------------------------------------------------------??
  • Traceback?(most?recent?call?last):??
  • ??File?"D:\pythonWorkspace\HTMLTest\test_mathfunc.py",?line?28,?in?test_divide??
  • ????self.assertEqual(2.5,?divide(5,?2))??
  • AssertionError:?2.5?!=?2??
  • ???
  • ----------------------------------------------------------------------??
  • Ran?3?tests?in?0.000s??
  • ???
  • FAILED?(failures=1,?skipped=1)??

  • skip裝飾器一共有三個

    unittest,skip(reason):無條件跳過

    unittest.skipIf(condition, reason):當(dāng)condition為True時跳過

    unittest.skipUnless(condition, reason):當(dāng)condition為False時跳過

    ?

    (2)TestCase.skipTest()方法

    ?

    [python] view plaincopy
  • class?TestMathFunc(unittest.TestCase):??
  • ...??
  • def?test_minus(self):??
  • ????????self.skipTest('do?not?run?this.')??
  • ????????self.assertEqual(1,?minus(3,?2))??
  • ?

    輸出:

    [python] view plaincopy
  • test_add?(test_mathfunc.TestMathFunc)?...?ok??
  • test_minus?(test_mathfunc.TestMathFunc)?...?skipped?'do?not?run?this.'??
  • test_divide?(test_mathfunc.TestMathFunc)?...?FAIL??
  • ???
  • ======================================================================??
  • FAIL:?test_divide?(test_mathfunc.TestMathFunc)??
  • ----------------------------------------------------------------------??
  • Traceback?(most?recent?call?last):??
  • ??File?"D:\pythonWorkspace\HTMLTest\test_mathfunc.py",?line?20,?in?test_divide??
  • ????self.assertEqual(2.5,?divide(5,?2))??
  • AssertionError:?2.5?!=?2??
  • ???
  • ----------------------------------------------------------------------??
  • Ran?3?tests?in?0.000s??
  • ???
  • FAILED?(failures=1,?skipped=1)??


  • 八、用HTMLTestRunner輸出漂亮的HTML報告

    txt格式的文本執(zhí)行報告過于簡陋,這里我們學(xué)習(xí)一下借助HTMLTestRunner生成HTML報告。首先需要下載HTMLTestRunner.py,并放到當(dāng)前目錄下,或者python目錄下的Lib中,就可以導(dǎo)入運(yùn)行了。

    下載地址:http://tungwaiyip.info/software/HTMLTestRunner.html

    ?

    將test_suite.py代碼修改如下:

    [python] view plaincopy
  • #?coding=utf-8??
  • ???
  • import?unittest??
  • from?test_mathfunc?import?TestMathFunc??
  • from?HTMLTestRunner?import?HTMLTestRunner??
  • ???
  • ???
  • if?__name__?==?'__main__':??
  • ????suite?=?unittest.TestSuite()??
  • ???
  • ????tests?=?[TestMathFunc("test_add"),?TestMathFunc("test_minus"),?TestMathFunc("test_divide")]??
  • ????suite.addTests(tests)??
  • ???
  • ????with?open('HTMLReport.html',?'w')?as?f:??
  • ????????runner?=?HTMLTestRunner(stream=f,??
  • ????????????????????????????????title?=?'MathFunc?Test?Report',??
  • ????????????????????????????????description='generated?by?HTMLTestRunner.',??
  • ????????????????????????????????verbosity=2??
  • ????????????????????????????????)??
  • ????????runner.run(suite)??


  • 執(zhí)行后,控制臺輸出如下:

    [python] view plaincopy
  • ok?test_add?(test_mathfunc.TestMathFunc)??
  • F??test_divide?(test_mathfunc.TestMathFunc)??
  • ???
  • Time?Elapsed:?0:00:00.001000??

  • 生成的html:

    ?

    ?

    九、總結(jié)

    1、unittest是python自帶的單元測試框架,我們可以用其來作為我們自動化測試框架的用例組織執(zhí)行框架。

    2、unittest的流程:寫好TestCase,然后由TestLoader加載TestCase到TestSuite,然后由TextTestRunner來運(yùn)行TestSuite,運(yùn)行的結(jié)果保存在TextTestResult中,我們通過命令行或者unittest.main()執(zhí)行時,main會調(diào)用TextTestRunner中的run來執(zhí)行,或者我們可以直接通過TextTestRunner來執(zhí)行用例。

    3、一個class繼承unittest.TestCase即是一個TestCase,其中以 test 開頭的方法在load時被加載為一個真正的TestCase。

    4、verbosity參數(shù)可以控制執(zhí)行結(jié)果的輸出,0 是簡單報告、1 是一般報告、2 是詳細(xì)報告。

    5、可以通過addTest和addTests向suite中添加case或suite,可以用TestLoader的loadTestsFrom__()方法。

    6、用 setUp()、tearDown()、setUpClass()以及 tearDownClass()可以在用例執(zhí)行前布置環(huán)境,以及在用例執(zhí)行后清理環(huán)境

    7、我們可以通過skip,skipIf,skipUnless裝飾器跳過某個case,或者用TestCase.skipTest方法。

    8、參數(shù)中加stream,可以將報告輸出到文件:可以用TextTestRunner輸出txt報告,以及可以用HTMLTestRunner輸出html報告。

    轉(zhuǎn)載于:https://www.cnblogs.com/qidongbo/p/8558720.html

    總結(jié)

    以上是生活随笔為你收集整理的python单元测试之unittest框架使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美片免费网站 | 韩国成人在线 | 日本不卡一区二区三区视频 | 在线观看欧美亚洲 | 国产高清日韩 | 五月激情片 | 成人午夜精品视频 | 在线色亚洲| 国产精品视频一二区 | 日本少妇作爱视频 | 超碰免费av | h片免费观看| 中文字幕在线观看第二页 | 欧美成人综合一区 | 中文av一区二区 | 99久久99久久| 99国产在线视频 | 亚洲精品二三区 | 视频在线观看 | 日本啪啪啪一区二区 | 久久国产亚洲精品无码 | 一本—道久久a久久精品蜜桃 | 色干综合 | 无码人妻精品一区二区三区99日韩 | 激情综合五月 | 老司机深夜福利网站 | 美女裸体跪姿扒开屁股无内裤 | aa一级黄色片 | 日韩精品中文字幕在线观看 | 亚洲一区二区在线免费观看 | 丁香花电影高清在线阅读免费 | 中文字幕123| 鬼眼| 久久综合亚洲 | 亚洲精品白浆 | 国产又粗又猛又爽又黄的视频在线观看动漫 | 少妇全黄性生交片 | 久热精品在线观看视频 | 欧美yyy| 波多野结衣视频免费在线观看 | 国自产拍偷拍精品啪啪一区二区 | 欧美丰满老妇性猛交 | 亚洲婷婷综合网 | 国产成人毛毛毛片 | 国产精品久久久久久久免费大片 | 欧美成人精品激情在线观看 | 国产精品成人免费视频 | 在线免费中文字幕 | 天天射视频 | 国产福利资源 | 欧美成人国产精品一区二区 | 色老大影院 | 中文字幕在线视频免费播放 | 欧美zozo | 国产精品刘玥久久一区 | 日韩wwww | 黑人性视频 | 欧美又大又硬又粗bbbbb | 天天射,天天干 | 欧美一级一级 | 精品在线视频播放 | 91.xxx.高清在线 | 91午夜视频在线观看 | 亚洲av无码国产精品永久一区 | 可以在线看的av | 亚洲精品久久夜色撩人男男小说 | 日操干| 四季av国产一区二区三区 | 久久中文免费视频 | 国产露脸150部国语对白 | 亚洲av无码专区在线 | 成年人在线免费观看 | a级黄色片 | 香蕉视频在线网站 | 日韩精品一区二区三区电影 | 男人午夜天堂 | 色爽黄| 欧美黑人欧美精品刺激 | 天天干,天天爽 | 日韩欧美视频免费观看 | 美女网站在线看 | 国内精品福利视频 | 男人的天堂免费视频 | 国产黄网站| 国产小视频免费在线观看 | 日韩欧美综合视频 | 国产在线播放av | 国内视频一区二区三区 | 天堂av观看 | a级一级黄色片 | 国产网站无遮挡 | 欧美一a| 女同hd系列中文字幕 | 在线综合av| 玖玖伊人 | 水密桃av | 色老板av | 国产乱码精品一区二区三区亚洲人 | 希岛婚前侵犯中文字幕在线 |