在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Python/ 單元測試
基礎(chǔ)
itertools
HTTP 服務(wù)
hashlib
閉包
文件和目錄
單元測試
使用 @property
標(biāo)準(zhǔn)模塊
陌生的 metaclass
Base64
進(jìn)程、線程和協(xié)程
讀寫二進(jìn)制文件
匿名函數(shù)
輸入和輸出
Click
元組
字符編碼
partial 函數(shù)
參考資料
collections
協(xié)程
類和實(shí)例
Python 之旅
定制類和魔法方法
常用數(shù)據(jù)類型
繼承和多態(tài)
ThreadLocal
HTTP 協(xié)議簡介
Requests 庫的使用
讀寫文本文件
列表
os 模塊
迭代器 (Iterator)
正則表達(dá)式
集合
上下文管理器
異常處理
你不知道的 super
定義函數(shù)
datetime
資源推薦
字典
slots 魔法
hmac
第三方模塊
進(jìn)程
類方法和靜態(tài)方法
函數(shù)參數(shù)
高階函數(shù)
函數(shù)
re 模塊
高級特性
線程
argparse
生成器
結(jié)束語
字符串
map/reduce/filter
函數(shù)式編程
Celery
裝飾器

單元測試

軟件系統(tǒng)的開發(fā)是一個(gè)很復(fù)雜的過程,隨著系統(tǒng)復(fù)雜性的提高,代碼中隱藏的 bug 也可能變得越來越多。為了保證軟件的質(zhì)量,測試是一個(gè)必不可少的部分,甚至還有測試驅(qū)動(dòng)開發(fā)(Test-driven development, TDD)的理念,也就是先測試再編碼。

在計(jì)算機(jī)編程中,單元測試(Unit Testing)又稱為模塊測試,是針對程序模塊(軟件設(shè)計(jì)的最小單位)來進(jìn)行正確性檢驗(yàn)的測試工作,所謂的單元是指一個(gè)函數(shù),一個(gè)模塊,一個(gè)類等。

在 Python 中,我們可以使用 unittest 模塊編寫單元測試。

下面以官方文檔的例子進(jìn)行介紹,該例子對字符串的一些方法進(jìn)行測試:

# -*- coding: utf-8 -*-

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')    # 判斷兩個(gè)值是否相等

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())          # 判斷值是否為 True
        self.assertFalse('Foo'.isupper())         # 判斷值是否為 False

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):         # 檢測異常
            s.split(2)

在上面,我們定義了一個(gè) TestStringMethods 類,它從 unittest.TestCase 繼承。注意到,我們的方法名都是以 test 開頭,表明該方法是測試方法,不以 test 開頭的方法測試的時(shí)候不會被執(zhí)行。

在方法里面,我們使用了斷言(assert)判斷程序運(yùn)行的結(jié)果是否和預(yù)期相符。其中:

  • assertEqual 用于判斷兩個(gè)值是否相等;
  • assertTrue/assertFalse 用于判斷表達(dá)式的值是 True 還是 False;
  • assertRaises 用于檢測異常;

斷言方法主要有三種類型:

  • 檢測兩個(gè)值的大小關(guān)系:相等,大于,小于等
  • 檢查邏輯表達(dá)式的值:True/Flase
  • 檢查異常

下面列舉了部分常用的斷言方法:

Method Checks that
assertEqual(a, b) a == b
assertNotEqual(a, b) a != b
assertGreater(a, b) a > b
assertGreaterEqual(a, b) a >= b
assertLess(a, b) a < b
assertLessEqual(a, b) a <= b
assertTrue(x) bool(x) is True
assertFalse(x) bool(x) is False
assertIs(a, b) a is b
assertIsNot(a, b) a is not b
assertIsNone(x) x is None
assertIsNotNone(x) x is not None
assertIn(a, b) a in b
assertNotIn(a, b) a not in b
assertIsInstance(a, b) isinstance(a, b)
assertNotIsInstance(a, b) not isinstance(a, b)

現(xiàn)在,讓我們來運(yùn)行上面的單元測試,將上面的代碼保存為文件 mytest.py,通過 -m unittest 參數(shù)運(yùn)行單元測試:

$ python -m unittest mytest
test_isupper (mytest.TestStringMethods) ... ok
test_split (mytest.TestStringMethods) ... ok
test_upper (mytest.TestStringMethods) ... ok

執(zhí)行結(jié)果:

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

OK

上面的結(jié)果表明測試通過,我們也可以加 -v 參數(shù)得到更加詳細(xì)的測試結(jié)果:

$ python -m unittest -v mytest
test_isupper (mytest.TestStringMethods) ... ok
test_split (mytest.TestStringMethods) ... ok
test_upper (mytest.TestStringMethods) ... ok

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

OK

上面這種運(yùn)行單元測試的方法是我們推薦的做法,當(dāng)然,你也可以在代碼的最后添加兩行:

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

然后再直接運(yùn)行:

$ python mytest.py

setUp 和 tearDown

在某些情況下,我們需要在每個(gè)測試方法執(zhí)行前和執(zhí)行后做一些相同的操作,比如我們想在每個(gè)測試方法執(zhí)行前連接數(shù)據(jù)庫,執(zhí)行后斷開數(shù)據(jù)庫連接,為了避免在每個(gè)測試方法中編寫同樣的代碼,我們可以使用 setUp 和 tearDown 方法,比如:

# -*- coding: utf-8 -*-

import unittest

class TestStringMethods(unittest.TestCase):

    def setUp(self):                              # 在每個(gè)測試方法執(zhí)行前被調(diào)用
        print 'setUp, Hello'

    def tearDown(self):                           # 在每個(gè)測試方法執(zhí)行后被調(diào)用
        print 'tearDown, Bye!'

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')    # 判斷兩個(gè)值是否相等

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())          # 判斷值是否為 True
        self.assertFalse('Foo'.isupper())         # 判斷值是否為 False

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):         # 檢測異常
            s.split(2)

看看執(zhí)行結(jié)果:

$ python -m unittest -v mytest
test_isupper (mytest.TestStringMethods) ... setUp, Hello
tearDown, Bye!
ok
test_split (mytest.TestStringMethods) ... setUp, Hello
tearDown, Bye!
ok
test_upper (mytest.TestStringMethods) ... setUp, Hello
tearDown, Bye!
ok

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

OK

小結(jié)

  • 通過從 unittest.TestCase 繼承來編寫測試類。
  • 使用斷言方法判斷程序運(yùn)行的結(jié)果是否和預(yù)期相符。
  • setUp 在每個(gè)測試方法執(zhí)行前被調(diào)用,tearDown 在每個(gè)測試方法執(zhí)行后被調(diào)用。

參考資料

上一篇:迭代器 (Iterator)下一篇:字符串