zoukankan      html  css  js  c++  java
  • 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())+ '
    ')
                    #深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('
    ')
            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('
    ')
            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('
    ')
            else:
                sys.stderr.write('F')
    
        def stop(self) -> None:
            pass

    这样改造完毕了,我们可以去试试

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

    执行的结果如下:

    image.png

    目前改造满足我们重试用例的需求,改造完毕。

    上面只是一个简单的改造,满足了对于失败的测试用例的重试,其实很简单,我们有了需求,去根据我们的需求去查找需要改造的代码即可,我们直接继承原来的类,对需要修改的地方 进行修改,已满足我们的需求。

    欢迎关注我的个人公众号



  • 相关阅读:
    js 树型数据 转 数组
    js 数组转树型结构数据
    计算 手机端页面高度和宽度
    解密优酷智能生产技术,看 AI 赋能内容数字化
    从 FFmpeg 性能加速到端云一体媒体系统优化
    导播上云,把 “虚拟演播厅” 搬到奥运村
    揭秘阿里云 RTS SDK 是如何实现直播降低延迟和卡顿
    迈入 8K 时代,AI 驱动超高清 “视” 界到来
    千亿级市场赛道,阿里云视频云拿下 “三连冠”
    50 亿观众的 “云上奥运”,顶级媒体背后的数智化力量
  • 原文地址:https://www.cnblogs.com/leiziv5/p/15106824.html
Copyright © 2011-2022 走看看