Unittest 單元測試框架1 - 基本使用和命令行選項

unittest --- 單元測試框架

源代碼:https://github.com/python/cpython/tree/3.9/Lib/unittest/_init_.py


unittest 單元測試框架是受到Junit的啟發(fā),與其他語言中的主流單元測試框架有著相似的風(fēng)格困肩。其支持測試自動化,配置共享和關(guān)機代碼測試崩溪。支持將測試樣例聚合到測試集中捶索,并將測試與報告框架獨立陈症。

為了實現(xiàn)這些逛薇,unittest通過面向?qū)ο蟮姆绞街С至艘恍┲匾母拍睢?/p>

  • test fixture

    test fixture表示為了開展一項或多項測試所需要進行的準備工作狼犯,以及所有相關(guān)的清理操作。舉個例子窃植,這可能包含創(chuàng)建臨時或代理的數(shù)據(jù)庫帝蒿,目錄,再或者啟動一個服務(wù)器進程巷怜。

  • test case

    一個test case是一個獨立的測試單元葛超。它檢查輸入特定的數(shù)據(jù)時的響應(yīng)。 unittest提供一個基類:TestCase ,用于新建測試用例延塑。

  • test suite

    test suite是一系列的測試用例绣张,或測試套件,或兩者皆有关带。它用于歸檔需要一起執(zhí)行的測試侥涵。

  • test runner

    test runner 是一個用于執(zhí)行和輸出測試結(jié)果的組件。這個云運行可能使用圖形接口宋雏,文本接口芜飘,或返回一個特定的值表示運行測試的結(jié)果。

基本實例

unittest模塊提供了一系列創(chuàng)建和運行測試的工具磨总。這一段演示了這些工具的一小部分嗦明,但也足以滿足大部分用戶的需求。

這是一段剪短的代碼舍败,來測試三種字符串方法:

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')
    
    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertRqual(s.split(), ['Hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.ssertRaises(TypeError):
            s.split(2)

if __name__ == '__main__':
    unittest.main()

集成unittest.TestCase 就創(chuàng)建了一個測試用例招狸。上述三個獨立的測試時三個類方法,這些方法的命名都以test開頭邻薯。 這個命名約定告訴test runner類的哪些方法表示測試。

每個測試的用例是:調(diào)用assertEqual() 來檢查預(yù)期的輸出乘凸; 調(diào)用assertTrue()assertFalse()來驗證一個條件厕诡;調(diào)用assertRaises()來驗證跑出了一個特定的異常。使用這些方法而不是assert語句是為了讓test runner 能聚合所有的測試結(jié)果并產(chǎn)生結(jié)果報告营勤。

通過setUp()tearDown()方法灵嫌,可以設(shè)置測試開始前與完成后需要執(zhí)行的指令。

最后的代碼中演示了運行測試的一個簡單的方法葛作。unittest.main()提供了一個測試腳本的命令行接口寿羞。當在命令行運行該測試腳本,上文的腳本生成如以下格式的輸出:

# python script.py

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

在調(diào)用測試腳本時添加-v參數(shù)使unittest.main()顯示更為詳細的信息赂蠢,生成如以下形式的輸入:

# python script.py -v
# python -m unittest -v script.py

test_isupper (__main__.TestStringMethods) ... ok
test_split (__main__.TestStringMethods) ... ok
test_upper (__main__.TestStringMethods) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

命令行界面

unitetst模塊可以通過命令行運行模塊绪穆,類和獨立測試方法的測試:

python -m unitest test_module1 test_module2
python -m unitest test_module.TestClass
python -m unitest testmodule.TestClass.test_method

你可以傳入模塊名,類或方法名或他們的任意組合。
同樣的玖院,測試模塊可以通過文件路徑指定:

python -m unittest tests/test_something.py

這樣就可以使用shell的文件名補全指定測試模塊菠红。所指定的文件仍需要可以被作為模塊導(dǎo)入。路徑通過去除'.py'难菌、把分隔符轉(zhuǎn)換為'.'轉(zhuǎn)換為模塊名试溯。若你需要執(zhí)行不能被作為模塊導(dǎo)入的測試文件,你需要直接執(zhí)行該測試文件郊酒。

在運行測試時遇绞,你可以通過添加-v參數(shù)獲取更詳細(更多的冗余)的信息。

python -m unitest -v test module

當運行時不包含參數(shù)燎窘,開始測試發(fā)現(xiàn):

python -m unittest # 等價于 python -m unittest discover

用于獲取命令行選項列表:

python -m unittest -h

在3.2版本中更改:在早期版本中试读,只支持運行獨立的測試方法,而不支持模塊和類荠耽。

命令行選項

uniitest支持以下命令行選項:

  • -b, --buffer

    在測試運行時钩骇,標準輸出流與標準錯誤流會被放入緩沖區(qū)。成功的測試的運行時輸出會被丟棄铝量;測試不通過時倘屹,測試運行中的輸出會正常顯示,錯誤會被加入到測試失敗信息慢叨。

  • -c, --catch

    當測試正在運行時纽匙, Control-C(即Ctrl+C)會等待當前測試完成,并在完成后報告已執(zhí)行的測試的結(jié)果拍谐。當再次按下Control-C時烛缔,引發(fā)平常的KeyboardInterrupt異常。

  • -f, --failfast

    當出現(xiàn)第一個錯誤或者失敗時轩拨,停止運行測試践瓷。

  • -k

    只運行匹配模式或子串的測試方法和類⊥鋈兀可以多次使用這個選項晕翠,以便包含匹配子串的所有測試用例。
    包含通配符(*)的模式使用fnmatch.fnmatchcase()對測試名稱進行匹配砍濒。另外淋肾,該匹配是大小寫敏感的。
    模式對testloader導(dǎo)入的測試方法全名進行匹配爸邢。
    例如樊卓, -k foo可以匹配到foo_tests.SomeTest.test_somethingbar_tests.SomeTest.test_foo,但是不能匹配到bar_tests.FooTest.test_something杠河。

  • --locals

    在回溯中顯示局部變量碌尔。

3.2新版本功能:添加命令行選項 -b,-c-f浇辜。
3.5新版本功能:添加命令行選項 --locals
3.7新版本功能:添加命令行選項 -k七扰。

測試

3.2新版本功能
unittest 支持簡單的測試發(fā)現(xiàn)奢赂。為了與測試發(fā)現(xiàn)兼容,所有測試文件必須是可從項目鼎城目錄導(dǎo)入的模塊或者(包括名稱空間包)(這意味著他們的文件名必須是有效的標識符)颈走。

Test discovery已經(jīng)在TestLoader.discover()中實現(xiàn)膳灶, 但也可以從命令行中使用×⒂桑基本的命令行用法是:

cd project_directory
python -m unittest discover
筆記:方便起見轧钓,python -m unittest 等效于 python -m unittest discover. 如果你需要向test discover傳入?yún)?shù),必須顯式地使用discover子命令

discover 有一下選項:

  • -v, --verbose

    更詳細地輸出結(jié)果锐膜。

  • -s, --start-directory directory
    開始進行搜索的目錄(默認值為當前目錄.)

  • -p, --pattern pattern
    用于匹配測試文件的模式(默認為test*.py)

  • -t, --top-level-directory directory
    指定項目的最上層目錄(通常為開始時坐在目錄)

-s毕箍,-p-t選項可以按順序作為位置參數(shù)傳入。以下兩條命令是等價的

python -m unittest discover -s project_directory -p "*_test.py"
python -m unittest discover project_directory "*_test.py"

正如可以傳入路徑那樣道盏,傳入一個包名作為起始目錄也是可行的而柑,如myproject.subprockage.test。你提供的包名會被導(dǎo)入荷逞,它在文件系統(tǒng)中的位置會被作為起始目錄媒咳。

警告: 測試發(fā)現(xiàn)通過導(dǎo)入測試對測試進行加載。在找到所有你指定的開始目錄下的所有測試文件后种远,它把路徑轉(zhuǎn)換為包名并進行導(dǎo)入涩澡。如foo/bar/baz.py會被導(dǎo)入為foo.bar.baz

如果你有一個全局安裝的包坠敷,并嘗試對這個包的副本進行測試發(fā)現(xiàn)妙同。可能會從錯誤的地方開始導(dǎo)入膝迎。如果出現(xiàn)這種情況粥帚,測試會輸出警告并退出。

如果你使用包名而不是路徑作為開始目錄弄抬,搜索時假定它導(dǎo)入的是你想要的目錄茎辐,所以你不會收到警告。

在3.4版本更改:Test discovery support namespace packages for start directory. Note that you need to the top level directory too.(e.g. python -m unittest discover -s root/namespace -t root).

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末掂恕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子弛槐,更是在濱河造成了極大的恐慌懊亡,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乎串,死亡現(xiàn)場離奇詭異店枣,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門鸯两,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闷旧,“玉大人,你說我怎么就攤上這事钧唐∶ψ疲” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵钝侠,是天一觀的道長该园。 經(jīng)常有香客問我,道長帅韧,這世上最難降的妖魔是什么里初? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮忽舟,結(jié)果婚禮上双妨,老公的妹妹穿的比我還像新娘。我一直安慰自己叮阅,他們只是感情好刁品,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著帘饶,像睡著了一般哑诊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上及刻,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天镀裤,我揣著相機與錄音,去河邊找鬼缴饭。 笑死暑劝,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的颗搂。 我是一名探鬼主播担猛,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼丢氢!你這毒婦竟也來了傅联?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤疚察,失蹤者是張志新(化名)和其女友劉穎蒸走,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體貌嫡,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡比驻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年该溯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片别惦。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡狈茉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出掸掸,到底是詐尸還是另有隱情氯庆,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布猾漫,位于F島的核電站点晴,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏悯周。R本人自食惡果不足惜粒督,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望禽翼。 院中可真熱鬧屠橄,春花似錦、人聲如沸闰挡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽长酗。三九已至溪北,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間夺脾,已是汗流浹背之拨。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留咧叭,地道東北人蚀乔。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像菲茬,于是被迫代替她去往敵國和親吉挣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容