1. 程式人生 > 實用技巧 >unittest單元測試框架教程8-unittest.TestResult類詳解

unittest單元測試框架教程8-unittest.TestResult類詳解

unittest.TestResult用於編譯有關哪些測試成功和失敗的資訊。一個TestResult物件儲存一組測試的結果。TestRunner.run()方法返回一個TestResult例項以便於生成測試報告。

TestResult例項具有以下屬性

依然測試此類

class TestAdd(unittest.TestCase):

    def setUp(self):
        self.a = 1
        self.b = 2

    def tearDown(self):
        print(self.a)
        print(self.b)

    
def test_add1(self): '''測試加法程式''' headers = { 'Content-Type': "application/json", } reqdata = {'a':self.a,'b':self.b} resp = requests.request(method='POST', url='http://127.0.0.1:8000/testapi/add/', verify=False, headers=headers, json=reqdata) # warnings.warn('這是個警告', category=None, stacklevel=1, source=None)
resp = json.loads(resp.text) self.assertEqual(resp['status'],1) self.assertEqual('請求成功',resp['message']) self.assertEqual(resp['data'], self.a + self.b) return resp['data'] def test_minus(self): '''測試減法程式''' headers = { 'Content-Type
': "application/json", } reqdata = {'a':self.a,'b':self.b} resp = requests.request(method='POST', url='http://127.0.0.1:8000/testapi/minus/', verify=False, headers=headers, json=reqdata) resp = json.loads(resp.text) self.assertEqual(resp['status'],1) self.assertEqual(resp['message'], '請求成功') self.assertEqual(resp['data'], self.a - self.b) return resp['data'] def test_chengfa(self): '''測試乘法程式''' headers = { 'Content-Type': "application/json", } reqdata = {'a':self.a,'b':self.b} resp = requests.request(method='POST', url='http://127.0.0.1:8000/testapi/chengfa/', verify=False, headers=headers, json=reqdata) resp = json.loads(resp.text) self.assertEqual(resp['status'],1) self.assertEqual(resp['message'], '請求成功') self.assertEqual(resp['data'], self.a * self.b,msg='乘法程式錯誤') return resp['data'] def test_chufa(self): '''測試除法程式''' self.b = 0 headers = { 'Content-Type': "application/json", } reqdata = {'a':self.a,'b':self.b} resp = requests.request(method='POST', url='http://127.0.0.1:8000/testapi/chengfa/', verify=False, headers=headers, json=reqdata) resp = json.loads(resp.text) self.assertEqual(resp['status'],1) self.assertEqual(resp['message'], '請求成功') self.assertEqual(resp['data'], self.a / self.b) return resp['data']

其中乘法程式是有問題,預期會返回錯誤

errors

包含2個元組的TestCase例項和包含格式化回溯的字串的列表每個元組代表一個引發意外異常的測試。

runner = unittest.TextTestRunner(verbosity=0)
suite = unittest.TestSuite()
suite.addTest(TestAdd('test_chufa'))
result = runner.run(suite)
print(result.errors)
1
0
[(<testmath.TestAdd testMethod=test_chufa>, 'Traceback (most recent call last):\n  File "D:\\PycharmProjects\\untitled\\testmath.py", line 71, in test_chufa\n    self.assertEqual(resp[\'data\'], self.a / self.b)\nZeroDivisionError: division by zero\n')]
======================================================================
ERROR: test_chufa (testmath.TestAdd)
測試除法程式
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\PycharmProjects\untitled\testmath.py", line 71, in test_chufa
    self.assertEqual(resp['data'], self.a / self.b)
ZeroDivisionError: division by zero

----------------------------------------------------------------------
Ran 1 test in 0.028s

FAILED (errors=1)

failures

包含2個元組的TestCase例項和包含格式化回溯的字串的列表每個元組代表一個測試,其中使用這些TestCase.assert*()方法明確指示了失敗

runner = unittest.TextTestRunner(verbosity=0)
suite = unittest.TestSuite()
suite.addTest(TestAdd('test_chengfa'))
result = runner.run(suite)
print(result.failures)
1
2
[(<testmath.TestAdd testMethod=test_chengfa>, 'Traceback (most recent call last):\n  File "D:\\PycharmProjects\\untitled\\testmath.py", line 57, in test_chengfa\n    self.assertEqual(resp[\'data\'], self.a * self.b,msg=\'乘法程式錯誤\')\nAssertionError: 3 != 2 : 乘法程式錯誤\n')]
======================================================================
FAIL: test_chengfa (testmath.TestAdd)
測試乘法程式
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\PycharmProjects\untitled\testmath.py", line 57, in test_chengfa
    self.assertEqual(resp['data'], self.a * self.b,msg='乘法程式錯誤')
AssertionError: 3 != 2 : 乘法程式錯誤

----------------------------------------------------------------------
Ran 1 test in 0.029s

FAILED (failures=1)

skipped

包含2元組的TestCase例項和字串的列表,其中包含跳過測試的原因。

@unittest.skip的方法

expectedFailures

包含2個元組的TestCase例項和包含格式化回溯的字串的列表每個元組代表測試用例的預期失敗。

@unittest.expectedFailure的方法

unexpectedSuccesses

包含TestCase標記為預期失敗但成功的例項的列表。

@unittest.expectedFailure的但是執行成功的方法

shouldStop

設定為何True時suite.run(result)不進行測試以及不記錄執行次數。

result = unittest.TestResult()
unittest.registerResult(result)
loader = unittest.TestLoader()
testmethod = loader.getTestCaseNames(TestAdd)
for t in testmethod:
    result.shouldStop = False
    if t == 'test_chufa':
        result.shouldStop = True
    suite = unittest.TestSuite()
    suite.addTest(TestAdd(t))
    result = suite.run(result)
print(result)
1
2
1
2
1
2
<unittest.result.TestResult run=3 errors=0 failures=1>

test_chufa沒有執行

testsRun

到目前為止,測試總數。

result = unittest.TestResult()
unittest.registerResult(result)
loader = unittest.TestLoader()
testmethod = loader.getTestCaseNames(TestAdd)
for t in testmethod:
    suite = unittest.TestSuite()
    suite.addTest(TestAdd(t))
    result = suite.run(result)
    print('測試總數為'+str(result.testsRun))
1
2
測試總數為1
1
2
測試總數為2
1
0
測試總數為3
1
2
測試總數為4

buffer

同TextTestRunner物件的buffer引數

failfast

同TextTestRunner物件的failfast引數

tb_locals

同TextTestRunner物件的tb_locals引數

wasSuccessful()

如果所有的測試執行通過返回True,否則返回FalseexpectedFailure()返回成功為不通過

result = unittest.TestResult()
unittest.registerResult(result)
loader = unittest.TestLoader()
suite = loader.loadTestsFromTestCase(TestAdd)
result = suite.run(result)
print('測試是否全部通過'+str(result.wasSuccessful()))
1
2
1
2
1
0
1
2
測試是否全部通過False

TestResult類的以下方法用於維護內部資料結構,並且可以在子類中擴充套件以支援其他報告要求。這對於在執行測試時支援互動式報告的構建工具特別有用。

下面以在某檔案寫入測試過程為例

class MyTestResult(unittest.TestResult):
    def __init__(self, *args, **kwds):
        super(MyTestResult,self).__init__(self)
        try:
            self.resultfile = open('testtext.txt','w+',encoding='utf-8')
        except Exception as e:
            pass

    def startTestRun(self):
        '''在執行任何測試之前呼叫一次。'''
        super(MyTestResult, self).startTestRun()
        if self.resultfile.writable():
            self.resultfile.writelines('單元測試開始!')
            self.resultfile.writelines('\n')

    def stopTestRun(self):
        '''執行完所有測試後呼叫一次。'''
        super(MyTestResult, self).stopTestRun()
        if self.resultfile.writable():
            self.resultfile.writelines('單元測試開始!')
            self.resultfile.writelines('\n')

    def startTest(self,test):
        '''在測試用例測試即將執行時呼叫。'''
        super(MyTestResult,self).startTest(test)
        if self.resultfile.writable():
            self.resultfile.writelines('開始執行' + test.shortDescription())
            self.resultfile.writelines('\n')

    def stopTest(self, test):
        '''不管結果如何,在執行完測試用例測試之後呼叫。'''
        super(MyTestResult, self).stopTest(test)
        if self.resultfile.writable():
            self.resultfile.writelines('結束執行' + test.shortDescription())
            self.resultfile.writelines('\n')

loader = unittest.TestLoader()
suite = loader.loadTestsFromTestCase(TestAdd)
runner = unittest.TextTestRunner(resultclass=MyTestResult)
result = runner.run(suite)
print(result)

執行後檢視testtext.txt檔案

單元測試開始!
開始執行測試加法程式
結束執行測試加法程式
開始執行測試乘法程式
結束執行測試乘法程式
開始執行測試除法程式
結束執行測試除法程式
開始執行測試減法程式
結束執行測試減法程式
單元測試開始!