Python 單元測試

測試

測試用例

對函數(shù) abs(),這個函數(shù)的作用就是取絕對值掺冠,我們可以編寫以下幾個測試用例:

  1. 輸入正數(shù),比如 1码党、 1.5德崭、 0.99,期待返回值與輸入相同
  2. 輸入負數(shù)揖盘,比如 -1眉厨、 -1.5、 -0.99扣讼, 期待返回值與輸入值相反
  3. 輸入0缺猛, 期待返回0缨叫;
  4. 輸入非數(shù)值類型椭符,比如 None荔燎、 []、 {}销钝, 期待拋出 TypeError
    把上面的測試用例有咨,放到測試模塊中,就是一個完整的單元測試蒸健。
    單元測試通過說明我們的函數(shù)能夠正常工作座享,要是不過,就說明函數(shù)還有bug似忧,
    那么就得修改渣叛,直到單元測試通過。
單元測試得意義
  • 一旦測試通過盯捌,以后的修改不會對abs()有影響淳衙,如果造成影響,測試就不能通過
  • 單元測試饺著,在重構中箫攀,也是經(jīng)常用到的,有了單元測試幼衰,就可以放心的重構

mydict.py 代碼:

class Dict(dict):
    def __init__(self, **kw):
        super().__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

編寫單元測試

我們需要引入 Python 自帶的 unittest 模塊靴跛,編寫 mydict_test 如下:

import  unittest

from learn.two.測試.mydict import Dict


class TestDict(unittest.TestCase):
    def test_init(self):
        d = Dict(a = 1, b = '測試')
        self.assertEqual(d.a, 1)
        self.assertEqual(d.b, '測試')
        self.assertTrue(isinstance(d, dict))

    # def test_key(self):        #這部分是測試用例通不過的例子
    #     d = Dict()
    #     d['key'] = 'value'
    #     self.assertSetEqual(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):
            value = d['empty']

    def test_attrerror(self):
        d = Dict()
        with self.assertRaises(AttributeError):
            value = d.empty

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

直接運行 mydict_test.py

Testing started at 22:54 ...
E:\py\venv\Scripts\python.exe "D:\JetBrains\PyCharm 2018.1.1\helpers\pycharm\_jb_unittest_runner.py" --target mydict_test.TestDict
Launching unittests with arguments python -m unittest mydict_test.TestDict in E:\pyplace\learn_python3\learn\two\測試


Ran 4 tests in 0.012s

OK

Process finished with exit code 0

以上這就說明單元測試通過了

下面是測試不通過的示范(將注釋的部分放開):

import  unittest

from learn.two.測試.mydict import Dict


class TestDict(unittest.TestCase):
    def test_init(self):
        d = Dict(a = 1, b = '測試')
        self.assertEqual(d.a, 1)
        self.assertEqual(d.b, '測試')
        self.assertTrue(isinstance(d, dict))

    def test_key(self):                  #這部分是測試用例通不過的例子
        d = Dict()
        d['key'] = 'value'
        self.assertSetEqual(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):
            value = d['empty']

    def test_attrerror(self):
        d = Dict()
        with self.assertRaises(AttributeError):
            value = d.empty

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

運行 mydict_test.py 結(jié)果:

Testing started at 22:58 ...
E:\py\venv\Scripts\python.exe "D:\JetBrains\PyCharm 2018.1.1\helpers\pycharm\_jb_unittest_runner.py" --target mydict_test.TestDict
Launching unittests with arguments python -m unittest mydict_test.TestDict in E:\pyplace\learn_python3\learn\two\測試


Ran 5 tests in 0.027s

FAILED (failures=1)

Failure
Traceback (most recent call last):
  File "D:\python\Python36\lib\unittest\case.py", line 1055, in assertSetEqual
    difference1 = set1.difference(set2)
AttributeError: 'str' object has no attribute 'difference'
  File "D:\python\Python36\lib\unittest\case.py", line 670, in fail
    raise self.failureException(msg)
AssertionError: first argument does not support set difference: 'str' object has no attribute 'difference'

可以看到昔善,控制臺輸入了紅色的錯誤日志朴摊,意味著單元測試不通過

單元測試的寫法

  • 需要編寫一個測試類恰聘,從 unittest.TestCase 繼承
  • 以 test 開頭的就是測試方法吠式,不是 test 開頭的不被認為是測試方法评姨,測試的時候不被執(zhí)行
  • 每個類測試都需要編寫 test_xxx() 方法奴曙,由于 unittest.TestCase 提供了很多內(nèi)置的條件判斷奶甘,我們只需要調(diào)用就可以了
常用方法
  • 常用的斷言就是 assertEqual();
 self.assertEqual(abs(-1), 1)    # 斷言返回的結(jié)果與1相等
  • 另一種是拋出指定類型的錯誤赛蔫,比如 d['empty']訪問不到存在的Key時裤唠,就拋出 KeyError
with self.assertRaises(KeyError):
    value = d['empty']

如果通過 d.empty 訪問不存在的 key 時挤牛,我們期待拋出 AttributeError:

with self.assertRaises(AttributeError):
    value = d.empty

運行單元測試

  • 在編寫好的單元測試中,添加以下兩行代碼种蘸,我們就可以運行單元測試
if __name__ == '__main___':
    unittest.main()
  • 這樣墓赴,我們就可以把 mydict_test.py 當作正常的 Python 腳本運行:
$ python mydict_test.py

總結(jié)

  1. 寫被測試的類
  2. 繼承 unittest.TestCase 寫單元測試類
  3. 通過會顯示綠色 Tests passed,并在輸出日志中顯示 OK
  4. 不通過顯示紅色 Tests failed航瞭,并在輸出日志中顯示 FAILD

github地址: https://github.com/shenshizhong/learn_python3

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末诫硕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子刊侯,更是在濱河造成了極大的恐慌章办,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異藕届,居然都是意外死亡挪蹭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門休偶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來梁厉,“玉大人,你說我怎么就攤上這事踏兜〈使耍” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵碱妆,是天一觀的道長肉盹。 經(jīng)常有香客問我,道長疹尾,這世上最難降的妖魔是什么垮媒? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮航棱,結(jié)果婚禮上睡雇,老公的妹妹穿的比我還像新娘。我一直安慰自己饮醇,他們只是感情好它抱,可當我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著朴艰,像睡著了一般观蓄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上祠墅,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天侮穿,我揣著相機與錄音,去河邊找鬼毁嗦。 笑死亲茅,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的狗准。 我是一名探鬼主播克锣,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼腔长!你這毒婦竟也來了袭祟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤捞附,失蹤者是張志新(化名)和其女友劉穎巾乳,沒想到半個月后您没,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡胆绊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年紊婉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辑舷。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖槽片,靈堂內(nèi)的尸體忽然破棺而出何缓,到底是詐尸還是另有隱情,我是刑警寧澤还栓,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布碌廓,位于F島的核電站,受9級特大地震影響剩盒,放射性物質(zhì)發(fā)生泄漏谷婆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一辽聊、第九天 我趴在偏房一處隱蔽的房頂上張望纪挎。 院中可真熱鬧,春花似錦跟匆、人聲如沸异袄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烤蜕。三九已至,卻和暖如春迹冤,著一層夾襖步出監(jiān)牢的瞬間讽营,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工泡徙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留橱鹏,地道東北人。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓堪藐,卻偏偏與公主長得像蚀瘸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子庶橱,可洞房花燭夜當晚...
    茶點故事閱讀 44,884評論 2 354

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

  • unittest作為一個python中的基本模塊贮勃,是其他框架和工具的基礎,官方文檔神馬的最實用了:https://...
    cheneydc閱讀 8,136評論 0 3
  • 單元測試 什么是單元 單元測試(unit testing)苏章,是指對軟件中的最小可測試單元(一個模塊寂嘉、一個函數(shù)或者一...
    PPMac閱讀 6,516評論 0 19
  • 讓我們用官網(wǎng)上的一個簡單的例子來先看看Unittest的使用方式: 一個測試用例是由unittest.Testca...
    CC先生之簡書閱讀 6,362評論 1 5
  • 本文試圖總結(jié)編寫單元測試的流程奏瞬,以及自己在寫單元測試時踩到的一些坑。如有遺漏泉孩,純屬必然硼端,歡迎補充。 目錄概覽: 編...
    蘇尚君閱讀 3,424評論 0 4
  • 什么是單元測試 單元測試是用來對最小可測試單元(如一個函數(shù)寓搬、一個類或者一個模塊)進行檢查和驗證珍昨。尤其是在對代碼進行...
    cuckoo5閱讀 5,425評論 0 5