unittest中最核心的四個(gè)概念是:
test case, test suite, test runner, test fixture色解。
(1)一個(gè)TestCase的實(shí)例就是一個(gè)測(cè)試用例。什么是測(cè)試用例呢?就是一個(gè)完整的測(cè)試流程,包括測(cè)試前準(zhǔn)備環(huán)境的搭建(setUp),執(zhí)行測(cè)試代碼(run),以及測(cè)試后環(huán)境的還原(tearDown)歌径。元測(cè)試(unit test)的本質(zhì)也就在這里,一個(gè)測(cè)試用例是一個(gè)完整的測(cè)試單元亲茅,通過運(yùn)行這個(gè)測(cè)試單元回铛,可以對(duì)某一個(gè)問題進(jìn)行驗(yàn)證。
(2)而多個(gè)測(cè)試用例集合在一起克锣,就是TestSuite勺届,而且TestSuite也可以嵌套TestSuite。
(3)TestLoader是用來加載TestCase到TestSuite中的娶耍,其中有幾個(gè)loadTestsFrom__()方法,就是從各個(gè)地方尋找TestCase饼酿,創(chuàng)建它們的實(shí)例榕酒,然后add到TestSuite中,再返回一個(gè)TestSuite實(shí)例故俐。
(4)TextTestRunner是來執(zhí)行測(cè)試用例的想鹰,其中的run(test)會(huì)執(zhí)行TestSuite/TestCase中的run(result)方法。
測(cè)試的結(jié)果會(huì)保存到TextTestResult實(shí)例中药版,包括運(yùn)行了多少測(cè)試用例辑舷,成功了多少,失敗了多少等信息槽片。
(5)而對(duì)一個(gè)測(cè)試用例環(huán)境的搭建和銷毀何缓,是一個(gè)fixture肢础。
1.基本案例
test_mathfunc.py
# -*- coding:utf-8 -*-
import unittest
from mathfunc import *
'''
mathfunc.py
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
'''
# 創(chuàng)建測(cè)試類
class TestMathFunc(unittest.TestCase):
""" 用于測(cè)試mathfunc.py """
def test_add(self):
# add(a, b) 測(cè)試
self.assertEqual(6, add(2, 4)) # 判斷6 與 add(2,4)的結(jié)果是否一致
self.assertNotEqual(3, add(2, 2)) # 判斷3 與add(2,2)結(jié)果是否不一致
def test_minus(self):
# minus(a, b)測(cè)試
self.assertEqual(3, minus(9, 6)) # 判斷3 與 minus(9,6))的結(jié)果是否一致
def test_multi(self):
# multi(a, b)測(cè)試
self.assertEqual(6, multi(2, 3)) # 判斷6 與 minus(2,3))的結(jié)果是否一致
def test_divide(self):
# divide(a, b) 測(cè)試
self.assertEqual(3, divide(6, 2)) # 判斷3 與 minus(6,2))的結(jié)果是否一致
self.assertEqual(2.5, divide(5, 2)) # 判斷2.5 與 minus(5,2))的結(jié)果是否一致
if __name__ == '__main__':
unittest.main() # 執(zhí)行測(cè)試
2.TestSuite案例
按照順序執(zhí)行測(cè)試用例,并將測(cè)試結(jié)果輸出到指定文件
test_suite.py
# -*- coding:utf-8 -*-
import unittest
from unit_pro import TestMathFunc
if __name__ == '__main__':
suite = unittest.TestSuite() # 創(chuàng)建測(cè)試集合
tests = [TestMathFunc("test_add"), TestMathFunc("test_minus"), TestMathFunc("test_divide")] # 測(cè)試函數(shù)列表
suite.addTests(tests) # 將測(cè)試函數(shù)列表添加到測(cè)試集合中
# 控制臺(tái)輸出測(cè)試結(jié)果
# runner = unittest.TextTestRunner(verbosity=2)
# verbosity=0 只顯示執(zhí)行的用例的總數(shù)和全局的執(zhí)行結(jié)果碌廓。
# verbosity=1 默認(rèn)值传轰,顯示執(zhí)行的用例的總數(shù)和全局的執(zhí)行結(jié)果,并對(duì)每個(gè)用例的執(zhí)行結(jié)果(成功T或失敗F)有個(gè)標(biāo)注谷婆。
# verbosity=2 顯示執(zhí)行的用例的總數(shù)和全局的執(zhí)行結(jié)果慨蛙,并輸出每個(gè)用例的詳細(xì)的執(zhí)行結(jié)果。
# runner.run(suite) # 運(yùn)行單元測(cè)試
# 將測(cè)試結(jié)果輸出到文件
with open('unit_test_report.txt','a') as f:
runner = unittest.TextTestRunner(stream=f, verbosity=2)
runner.run(suite)
3.測(cè)試前后的環(huán)境準(zhǔn)備和清理
setUp用來為測(cè)試準(zhǔn)備環(huán)境纪挎,tearDown用來清理環(huán)境 注意:每次執(zhí)行case前后都執(zhí)行了一次
setUpClass期贫,tearDownClass在整個(gè)測(cè)試中只執(zhí)行一次
案例
# -*- coding:utf-8 -*-
import unittest
from mathfunc import *
'''
mathfunc.py
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
'''
# 創(chuàng)建測(cè)試類
class TestMathFunc(unittest.TestCase):
""" 用于測(cè)試mathfunc.py """
# setUp用來為測(cè)試準(zhǔn)備環(huán)境,tearDown用來清理環(huán)境 注意:每次執(zhí)行case前后都執(zhí)行了一次
# def setUp(self):
# print('執(zhí)行測(cè)試之前异袄,先準(zhǔn)備好環(huán)境 test.Prepare environment')
#
# def tearDown(self):
# print('執(zhí)行完成后的清理 test.Clean up')
@classmethod
def setUpClass(cls):
print('測(cè)試中通砍,只在開始時(shí)被調(diào)用一次')
@classmethod
def tearDownClass(cls):
print('測(cè)試中,只在結(jié)束時(shí)被調(diào)用一次')
def test_add(self):
# add(a, b) 測(cè)試
self.assertEqual(6, add(2, 4)) # 判斷6 與 add(2,4)的結(jié)果是否一致
self.assertNotEqual(3, add(2, 2)) # 判斷3 與add(2,2)結(jié)果是否不一致
def test_minus(self):
# minus(a, b)測(cè)試
self.assertEqual(3, minus(9, 6)) # 判斷3 與 minus(9,6))的結(jié)果是否一致
def test_multi(self):
# multi(a, b)測(cè)試
self.assertEqual(6, multi(2, 3)) # 判斷6 與 minus(2,3))的結(jié)果是否一致
def test_divide(self):
# divide(a, b) 測(cè)試
self.assertEqual(3, divide(6, 2)) # 判斷3 與 minus(6,2))的結(jié)果是否一致
self.assertEqual(2.5, divide(5, 2)) # 判斷2.5 與 minus(5,2))的結(jié)果是否一致
if __name__ == '__main__':
unittest.main() # 執(zhí)行測(cè)試
4.跳過某個(gè)case(實(shí)例)
skip無條件跳過隙轻,skipIf當(dāng)condition為True時(shí)跳過埠帕,skipUnless當(dāng)condition為False時(shí)跳過。
@unittest.skip("我要跳過這個(gè)測(cè)試實(shí)例") # 跳過該實(shí)例
def test_divide(self):
# divide(a, b) 測(cè)試
self.assertEqual(3, divide(6, 2)) # 判斷3 與 minus(6,2))的結(jié)果是否一致
self.assertEqual(2.5, divide(5, 2)) # 判斷2.5 與 minus(5,2))的結(jié)果是否一致