unittest系統(八)一文搞定unittest重試功能


在前面的介紹中,我們對unittest進行了分享介紹,那么在實際的應用中,因為客觀原因需要對失敗,錯誤的測試用例進行重試,所以呢,現有的unittest的框架無法滿足,那么我們可以去改造下是否能夠滿足呢。本文帶領大家去剖析如何改寫?

首先呢,我們去試着去找下,我們運行時在BSTestRunner、TextTestRunner或者main,都可以執行用例,那么我們可以看下這些類或者方法里面如何實現的。

BSTestRunner調用方式如下

 

TextTestRunner的方法是,

 

使用main方法最后的調用也是這個函數。詳細的我們可以看下,首先調用這個函數,然后在看實際的調用.

 

 

最后的調用也是這個函數

 

 

 

所以我們就要在里面的方法去查找適合我們使用的方法。

在注釋中,我們可以發現在stopTest的方法中可以對其進行改寫。
def stopTest(self, test):        
    """Called when the given test has been run"""        
    self._restoreStdout()        
    self._mirrorOutput = False

  

那么我們應該如何改寫呢,我們梳理下我們的思路。

  • 1.傳遞重試次數,默認不需要重試
  • 2.在用例執行的錯誤,標記為需要重試
  • 3.在該條用例執行完畢后,我們判斷是否需要重試,重試次數是否滿足
  • 4.如果需要重試,則保存最新的從測試結果。

那么我們開始按照上面的思路進行改造。

代碼如下

import  sys,copy
from io import StringIO as StringIO
TestResult = unittest.TestResult
class MyResult(TestResult):
    def __init__(self, verbosity=1, trynum=0):
        #默認次數是0
        TestResult.__init__(self)
        self.outputBuffer = StringIO()
        self.stdout0 = None
        self.stderr0 = None
        self.success_count = 0
        self.failure_count = 0
        self.error_count = 0
        self.verbosity = verbosity
        self.trynnum = trynum
        self.result = []
        self.trys=0#
        self.istry=False

    def startTest(self, test):
        TestResult.startTest(self, test)
        self.stdout0 = sys.stdout
        self.stderr0 = sys.stderr

    def complete_output(self):
        if self.stdout0:
            sys.stdout = self.stdout0
            sys.stderr = self.stderr0
            self.stdout0 = None
            self.stderr0 = None
        return self.outputBuffer.getvalue()

    def stopTest(self, test):
        #判斷是否要重試
        if self.istry is True :
            #如果執行的次數小於重試的次數 就重試
            if self.trys < self.trynnum :
                #刪除最后一個結果
                reslut = self.result.pop(-1)
                #判斷結果,如果是錯誤就把錯誤的個數減掉
                #如果是失敗,就把失敗的次數減掉
                if reslut[0] == 1:
                    self.failure_count -= 1
                else:
                    self.error_count -= 1
                sys.stderr.write('{}:用例正在重試中。。。' .format(test.id())+ '\n')
                #深copy用例
                test = copy.copy(test)
                #重試次數增加+1
                self.trys += 1
                #測試
                test(self)
            else:
                self.istry=False
                self.trys =0
        self.complete_output()

    def addSuccess(self, test):
        #成功就不要重試
        self.istry = False
        self.success_count += 1
        TestResult.addSuccess(self, test)
        output = self.complete_output()
        self.result.append((0, test, output, ''))
        if self.verbosity > 1:
            sys.stderr.write('ok ')
            sys.stderr.write(str(test))
            sys.stderr.write('\n')
        else:
            sys.stderr.write('.')

    def addError(self, test, err):
        #重試+1,錯誤次數+1
        self.istry = True
        self.error_count += 1
        TestResult.addError(self, test, err)
        _, _exc_str = self.errors[-1]
        output = self.complete_output()
        self.result.append((2, test, output, _exc_str))
        if self.verbosity > 1:
            sys.stderr.write('E  ')
            sys.stderr.write(str(test))
            sys.stderr.write('\n')
        else:
            sys.stderr.write('E')

    def addFailure(self, test, err):
        self.istry = True
        TestResult.startTestRun(self)
        self.failure_count += 1
        TestResult.addFailure(self, test, err)
        _, _exc_str = self.failures[-1]
        output = self.complete_output()
        self.result.append((1, test, output, _exc_str))
        if self.verbosity > 1:
            sys.stderr.write('F  ')
            sys.stderr.write(str(test))
            sys.stderr.write('\n')
        else:
            sys.stderr.write('F')

    def stop(self) -> None:
        pass

這樣改造完畢了,我們可以去試試

if __name__ == "__main__":   
    suitone=suite()   
    rse=MyResult(trynum=3)    
    suitone.run(rse)

執行的結果如下:

image.png

目前改造滿足我們重試用例的需求,改造完畢。

上面只是一個簡單的改造,滿足了對於失敗的測試用例的重試,其實很簡單,我們有了需求,去根據我們的需求去查找需要改造的代碼即可,我們直接繼承原來的類,對需要修改的地方 進行修改,已滿足我們的需求。

歡迎關注我的個人公眾號



 


免責聲明!

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



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