unittest單元測試框架教程6-unittest.TestCase類詳解


unittest.TestCase(methodName ='runTest' )

TestCase類的實例,作為編寫的測試類的基類,具體測試由具體的子類(就是我們寫的測試類)實現。此類實現測試運行程序所需的接口,以使其能夠驅動測試,以及測試代碼可用於檢查和報告各種失敗的方法。

每個TestCase實例(就是我們寫的測試類)將運行一個基本方法:我們編寫的測試方法TestCase 實例提供了三組方法:一組用於運行測試,另一組由測試實現用於檢查條件和報告故障,還有一些查詢方法允許收集有關測試本身的信息。

第一組的方法是:

setUp()

 

在調用測試方法之前立即調用該方法。除了AssertionErrorSkipTest之外,此方法引發的任何異常都將被視為錯誤而不是測試失敗。默認實現不執行任何操作。

 

tearDown()

調用測試方法並記錄結果后立即調用的方法。即使測試方法引發了異常,也將調用此方法,因此子類中的實現可能需要特別注意檢查內部狀態。除了AssertionErrorSkipTest之外,此方法引發的任何異常都將被視為錯誤(errors)而不是測試失敗(Failures)setUp()無論測試方法的結果如何,僅在成功的情況下才調用此方法(wasSuccessful()==True)。默認實現不執行任何操作。

 

setUpClass()

 

在運行單個類中的測試之前調用的類方法。setUpClass以類作為唯一參數調用,並且必須修飾為classmethod()

@classmethod
def setUpClass(cls):
    ...

 

tearDownClass()

與setUpClass原理一致

 

run(result = None)

運行測試,將結果收集到TestResult作為result傳遞對象中如果省略resultNone,則創建一個臨時結果對象(通過調用該defaultTestResult() 方法)並使用它。結果對象返回給run()的調用者。

通過簡單地調用TestCase 實例

result = TestAdd('test_add1').run()
result = TestAdd('test_chengfa').run()
print(result)

會生成一個測試結果

<unittest.result.TestResult run=1 errors=0 failures=1>

 

skipTest(reason)

@ unittest. skip (reason)

跳過被此裝飾器裝飾的測試。 reason 為測試被跳過的原因。

@ unittest. skipIf (conditionreason)

當 condition 為真時,跳過被裝飾的測試。

@ unittest. skipUnless (conditionreason)

跳過被裝飾的測試,除非 condition 為真。

@ unittest. expectedFailure

把測試標記為預計失敗。如果測試不通過,會被認為測試成功;如果測試通過了,則被認為是測試失敗。

exception  unittest. SkipTest (reason)

引發此異常以跳過一個測試。

通常來說,你可以使用 TestCase.skipTest() 或其中一個跳過測試的裝飾器實現跳過測試的功能,而不是直接引發此異常。

被跳過的測試的 setUp() 和 tearDown() 不會被運行。被跳過的類的 setUpClass() 和 tearDownClass() 不會被運行。被跳過的模組的 setUpModule() 和 tearDownModule() 不會被運行。

    def test_chengfa(self):
        '''測試乘法程序'''
        self.skipTest('暫不測試')
        ...

加入后運行,就會跳過

1
2
1
2
1
2
<unittest.runner.TextTestResult run=3 errors=0 failures=0>
.s.
----------------------------------------------------------------------
Ran 3 tests in 0.041s

OK (skipped=1)

 

subTest(msg = None** params)

可參考unittest單元測試框架教程5-使用subTest進行循環測試

 

debug()

 

運行測試而不收集結果。這樣可以將測試引發的異常傳播到調用方,並可以用於支持在調試器下運行測試。

result = TestAdd('test_add1').debug()
result = TestAdd('test_chengfa').debug()
print(result)

運行后會詳細的輸出錯誤信息,便於定位

1
2
Traceback (most recent call last):
  File "D:\PycharmProjects\untitled\testrunner.py", line 13, in <module>
    result = TestAdd('test_chengfa').debug()
  File "C:\Users\MZM\AppData\Local\Programs\Python\Python37-32\lib\unittest\case.py", line 681, in debug
    getattr(self, self._testMethodName)()
  File "D:\PycharmProjects\untitled\testmath.py", line 53, in test_chengfa
    self.assertEqual(resp['data'], self.a * self.b)
  File "C:\Users\MZM\AppData\Local\Programs\Python\Python37-32\lib\unittest\case.py", line 852, in assertEqual
    assertion_func(first, second, msg=msg)
  File "C:\Users\MZM\AppData\Local\Programs\Python\Python37-32\lib\unittest\case.py", line 845, in _baseAssertEqual
    raise self.failureException(msg)
AssertionError: 3 != 2

第二組方法提供了一些斷言方法來檢查並報告故障。

 

 

assertRaises(exceptioncallable* args** kwds)

測試除法分母為0報異常

class TestMath(unittest.TestCase):
def setUp(self):
pass

def tearDown(self):
pass


def test_chufa(self):
'''測試乘法程序'''
self.assertEqual(chufa(0,0), 0)

E
======================================================================
ERROR: test_chufa (testmath.TestMath)
測試乘法程序
----------------------------------------------------------------------
Traceback (most recent call last):
File "D:\PycharmProjects\unitest\testmath.py", line 87, in test_chufa
self.assertEqual(chufa(0,0), 0)
File "D:\PycharmProjects\unitest\testmath.py", line 74, in chufa
return a/b
ZeroDivisionError: division by zero

----------------------------------------------------------------------
Ran 1 test in 0.001s

加入assertraise斷言后不會報錯

        with self.assertRaises(ZeroDivisionError):
            self.assertEqual(resp['data'], self.a / self.b)

 

assertRaisesRegex(exceptionregexcallable* args** kwds )

也是一樣的操作

with self.assertRaisesRegex(ZeroDivisionError, 'ok'):
self.assertEqual(resp['data'], self.a / self.b)

F
======================================================================
FAIL: test_chufa (testmath.TestMath)
測試乘法程序
----------------------------------------------------------------------
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "D:\PycharmProjects\unitest\testmath.py", line 89, in test_chufa
self.assertEqual(chufa(0,0), 0)
AssertionError: "ok" does not match "division by zero"

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

with self.assertRaisesRegex(ZeroDivisionError, 'by'):
    self.assertEqual(resp['data'], self.a / self.b)
1
0
<unittest.runner.TextTestResult run=1 errors=0 failures=0>
.
----------------------------------------------------------------------
Ran 1 test in 0.028s

OK

 

用於執行更具體檢查的方法

 

 

 

 assertAlmostEqual(a, b)

舉個例子self.assertAlmostEqual(1.00000002,1.00000001)第八位不報錯,self.assertAlmostEqual(1.0000001,1.0000002)第七位就會報錯,因為默認比的是第七位之前

self.assertAlmostEqual(1.02,1.01,1)不報錯self.assertAlmostEqual(1.02,1.01,2)報錯,因為默認比的是第二位之前

place參數表示第n位前都相等,之后無所謂

 

assertRegex(textregexmsg = None)

測試正則表達式搜索是否匹配(或不匹配)text

 

 

assertCountEqual(firstsecondmsg = None)

測試第一個序列是否包含與第二個相同的元素,而不管它們的順序如何。否則,將生成一條錯誤消息,列出序列之間的差異。

 

下表總結了自動比較使用的特定類型方法的列表

 

 

 

最后,TestCase提供以下方法和屬性:

failmsg = None 

failureException

此類屬性給出了測試方法引發的異常。如果測試框架需要使用專門的異常(可能帶有其他信息),則它必須將該異常子類化,以便與框架“公平競爭”。此屬性的初始值為 AssertionError

使用msgNone錯誤消息無條件地指示測試失敗

代碼中加入

        if resp['status'] == 0:
            raise self.failureException(ConnectionError)

並修改測試程序使其返回0

F
======================================================================
FAIL: test_chufa (testmath.TestMath)
測試乘法程序
----------------------------------------------------------------------
Traceback (most recent call last):
File "D:\PycharmProjects\unitest\testmath.py", line 89, in test_chufa
raise self.failureException(ConnectionError)
AssertionError: <class 'ConnectionError'>

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

 

測試框架可以使用以下方法來收集有關測試的信息:

countTestCases()

返回此測試對象表示的測試數量。

print(TestAdd('test_chengfa').countTestCases())
loader = unittest.TestLoader()
suite = loader.loadTestsFromTestCase(TestAdd)
print(suite.countTestCases())
suite.addTest(TestAdd('test_chengfa'))
print(suite.countTestCases())

1
4
5

 

id()

返回標識特定測試用例的字符串。這通常是測試方法的全名,包括模塊和類名。

print(TestAdd('test_chengfa').id())

返回testmath.TestAdd.test_chengfa

 

shortDescription()

返回測試的描述,或者None沒有提供描述。此方法的默認實現返回測試方法docstring的第一行(如果有),或None

 

doCleanups()

tearDown()或在setUp()引發異常之后無條件調用此方法

如果使setup方法報錯

def setUp(self):
self.file = open('testtext.txt','w+',encoding='utf-8')
self.file.write('測試開始')
self.a = 1/0
self.b = 2/0

def tearDown(self):
print(self.a)
print(self.b)
self.file.write('測試結束')
self.file.close()


...

runner = unittest.TextTestRunner()
suite = unittest.TestSuite()
suite.addTest(TestAdd('test_add1'))
result = runner.run(suite)

出現錯誤,且不會運行tearDown

E
======================================================================
ERROR: test_add1 (testmath.TestAdd)
測試加法程序
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\PycharmProjects\untitled\testmath.py", line 11, in setUp
    self.a = 1/0
ZeroDivisionError: division by zero

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)
<unittest.runner.TextTestResult run=1 errors=1 failures=0>

加入doCleanups()后

    def doCleanups(self):
        self.file.write('測試結束')
        self.file.close()

就會將"測試結束"寫入文件了

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM