python-unitest模塊總結

1、定義(copy自百度百科):
單元測試(unit testing),是指對軟件中的最小可測試單元進行檢查和驗證。對於單元測試中單元的含義,通常來講,要根據實際狀況去斷定其具體含義,如C語言中單元指一個函數,Java裏單元指一個類,圖形化的軟件中能夠指一個窗口或一個菜單等。總的來講,單元就是人爲規定的最小的被測功能模塊。單元測試是在軟件開發過程當中要進行的最低級別的測試活動,軟件的獨立單元將在與程序的其餘部分相隔離的狀況下進行測試。html


2、爲何寫單元測試:
寫測試的同時會對源碼有更深的理解,畢竟讀懂源碼大致邏輯才能寫測試(或別人告訴你代碼的功能和返回值等)
寫測試有點浪費感情,沒啥意思。沒有寫功能來的痛快。可是當你調整代碼或代碼重構的時候就明白沒有測試的痛苦了。
測試可讓問題更容易定位,通常的單元測試針對的是函數或方法這種小的代碼塊,不至於讓你出問題時像無頭的蒼蠅。
好處多多python

3、python的unittest模塊的一些名詞(官話讀起來有些懵逼,能夠大體看一下記住名詞,照着示例先敲一下看看結果。)
test fixture表示執行一個或多個測試所需的準備工做,以及任何關聯清理操做。這可能涉及例如建立臨時或代理數據庫,目錄或啓動服務器進程。
test case是單元測試的最小單位。它檢查對特定輸入集的特定響應。unittest 提供了一個基類, TestCase可用於建立新的測試用例。
test suite是test cases,test suites或者二者的集合。它用於聚合應該一塊兒執行的測試。
test runner 是一個協調測試執行並向用戶提供結果的組件。執行者可使用圖形界面,文本界面,或返回特殊值來指示執行測試的結果。數據庫

4、下面是unittest模塊的經常使用方法:(挑合適的用,也就幾個經常使用)
assertEqual(a, b) a == b
assertNotEqual(a, b) a != b
assertTrue(x) bool(x) is True
assertFalse(x) bool(x) is False
assertIs(a, b) a is b 2.7
assertIsNot(a, b) a is not b 2.7
assertIsNone(x) x is None 2.7
assertIsNotNone(x) x is not None 2.7
assertIn(a, b) a in b 2.7
assertNotIn(a, b) a not in b 2.7
assertIsInstance(a, b) isinstance(a, b) 2.7
assertNotIsInstance(a, b) not isinstance(a, b) 2.7服務器

其餘的unittest方法():
assertAlmostEqual(a, b) round(a-b, 7) == 0
assertNotAlmostEqual(a, b) round(a-b, 7) != 0
assertGreater(a, b) a > b 2.7
assertGreaterEqual(a, b) a >= b 2.7
assertLess(a, b) a < b 2.7
assertLessEqual(a, b) a <= b 2.7
assertRegexpMatches(s, re) regex.search(s) 2.7
assertNotRegexpMatches(s, re) not regex.search(s) 2.7
assertItemsEqual(a, b) sorted(a) == sorted(b) and works with unhashable objs 2.7
assertDictContainsSubset(a, b) all the key/value pairs in a exist in b 2.7
assertMultiLineEqual(a, b) strings 2.7
assertSequenceEqual(a, b) sequences 2.7
assertListEqual(a, b) lists 2.7
assertTupleEqual(a, b) tuples 2.7
assertSetEqual(a, b) sets or frozensets 2.7
assertDictEqual(a, b) dicts 2.7
assertMultiLineEqual(a, b) strings 2.7
assertSequenceEqual(a, b) sequences 2.7
assertListEqual(a, b) lists 2.7
assertTupleEqual(a, b) tuples 2.7
assertSetEqual(a, b) sets or frozensets 2.7
assertDictEqual(a, b) dicts 2.7框架

5、test case(copy自百度百科):
輸入數據及預期輸出。輸入數據是測試用例的核心,對輸入數據的定義是:被測試函數所讀取的外部數據及這些數據的初始值。外部數據是對於被測試函數來講的,實際上就是除了局部變量之外的其餘數據,把這些數據分爲幾類:參數、成員變量、全局變量、IO媒體。IO媒體是指文件、數據庫或其餘儲存或傳輸數據的媒體,例如,被測試函數要從文件或數據庫讀取數據,那麼,文件或數據庫中的原始數據也屬於輸入數據。一個函數不管多複雜,都無非是對這幾類數據的讀取、計算和寫入。預期輸出是指:返回值及被測試函數所寫入的外部數據的結果值。返回值就不用說了,被測試函數進行了寫操做的參數(輸出參數)、成員變量、全局變量、IO媒體,它們的預期的結果值都是預期輸出。一個測試用例,就是設定輸入數據,運行被測試函數,而後判斷實際輸出是否符合預期。
測試用例的核心是輸入數據。選擇有表明性的數據做爲輸入數據,主要有三種:正常輸入,邊界輸入,非法輸入。less

6、一波實例:
一、基本使用
(1)先拿官方的一個內置函數坐下演示
import unittest
class TestCmp(unittest.TestCase): # 寫一個類而後繼承TestCase類
def test_a_greater_b(self): # 這是一個測試用例(test case).
self.assertEqual(1, cmp(10, 1)) # self.assertEqual是測試框架提供的方法,用於標膠兩個值是否相等。函數

def test_a_less_b(self):
self.assertEqual(-1, cmp(1, 5))單元測試

def test_a_equal_b(self):
self.assertEqual(0, cmp(2, 2))測試

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

執行:python scipy_name
output:Ran 3 tests in 0.000s
OK
There are three test cases, OK on behalf of all the test successfully.

(2)本身寫的一個功能函數
被測試函數(功能:保證輸入路徑最終是目錄。 若是路徑存在但不是目錄,可選擇是否備份。)
def ensure_dir(path, backup = True):
tmp = path
while True:
if os.path.lexists(tmp):
if not os.path.isdir(tmp) and backup:
bak = tmp + ".%s" % (int(time.time()))
logger.warning("Ensure '%s' as directory, '%s' exists and is not directory, about to rename it as '%s'" % (path, tmp, bak))
os.rename(tmp, bak)
elif not os.path.isdir(tmp):
logger.warning("Ensure '%s' as directory, '%s' exists and is not directory, about to remove" % (path, tmp))
os.remove(tmp)
break
else:
tmp = os.path.dirname(tmp)

if path and not os.path.exists(path):
logger.info("creating directory '%s'" % path)
os.makedirs(path)

import util
import unittest
import os
import shutil


class TestEnsureDir(unittest.TestCase):
TEST_BASE_DIR = "/tmp/unittest/" # 測試文件的根目錄
def setUp(self):
if not os.path.isdir(TestEnsureDir.TEST_BASE_DIR):
os.makedirs(TestEnsureDir.TEST_BASE_DIR)

def test_regular(self):
dir = os.path.join(TestEnsureDir.TEST_BASE_DIR, 'a/b/c')
util.EnsureDir(dir)
self.assertTrue(os.path.isdir)

def tearDown(self):
if os.path.isdir(TestEnsureDir.TEST_BASE_DIR):
shutil.rmtree(TestEnsureDir.TEST_BASE_DIR)


if __name__ == "__main__":
unittest.main()
單元測試中編寫兩個特殊的setUp()和tearDown()方法。這兩個方法會分別在每調用一個測試方法的先後分別被執行。

2進階-mock
官方:http://www.voidspace.org.uk/python/mock/index.html
測試自己就是對當前函數或方法的測試。若是要測試的函數裏包含的函數會鏈接數據庫,或者發起http請求。你不想出發真實的操做,或者你純粹就是不行調用這個函數。那這時候就用到mock模塊了。
(1)patch
做用:找出模塊裏的一個函數用mock的對象替換掉
解決問題:當被測試函數內部調用其餘對象時,不想調用其餘對象,用mock的對象替換掉其餘對象

from mock import patch
import module
@patch('module.ClassName2')
@patch('module.ClassName1')
def test(MockClass1, MockClass2):
MockClass1

(2)MagicMock
做用:模擬一個對象的返回值(能夠是函數和方法)
class ProductionClass(object):
pass
from mock import MagicMock
thing = ProductionClass()
thing.method = MagicMock(return_value=3)

3實戰

 

未完待續。。。

相關文章
相關標籤/搜索