python的unittest框架用例失败重运行解决方法

当我们在做自动化测试的时候,发现unittest不能支持用例失败自动重运行机制,需要做扩展,达到像java的testng一样支持失败重运行,提高测试质量。

第一个解决方法是,我们使用decorator创建一个失败重运行装饰器,然后在每个用例方法使用这个装饰器可以达到失败重运行,但是有两个缺点:一是写每个用例方法后都要加上装饰器,二是失败不能重运行setUp()和dearDown(),如果用例有这初始化和销毁的,不能重新运行这两部分。

实例代码:

def failrun(n=3):
    def decorator(func):
        def wrapper(*args,**kw):
            for i in range(n):
                try:
                    r=func(*args,**kw)
                    return r
                except AssertionError as err:
                    print '用例第一次失败原因:%s'%err
            raise AssertionError
        return wrapper
    return decorator

经过多次研读和调试unittest代码,后来发现一个也可以重运行setUp()和dearDown()的解决办法,那就是修改源码,我们重新建一个模块套件类来覆盖原来的TestSuite类

实例代码:

class Suit(unittest.TestSuite):
    def run(self, result, debug=False):
        failcount = 1#失败总运行次数
        class_num = 1
        topLevel = False
        if getattr(result, '_testRunEntered', False) is False:
            result._testRunEntered = topLevel = True

        for test in self:
            case_num = 1
            if result.shouldStop:
                break
            
            success_flag = True
            while success_flag:  
                if _isnotsuite(test):
                    self._tearDownPreviousClass(test, result)
                    self._handleModuleFixture(test, result)
                    self._handleClassSetUp(test, result)
                    result._previousTestClass = test.__class__
                    if (getattr(test.__class__, '_classSetupFailed', False) or
                        getattr(result, '_moduleSetUpFailed', False)):
                        if class_num > failcount:
                            success_flag = False
                        else:
                            time.sleep(5)
                            result._previousTestClass = None
                            print '类%s第%s次重新初始化执行'%(test.__class__,class_num)
                            class_num += 1
                        continue

                if not debug:
                    test(result)
                else:
                    test.debug()
                
                if result.result[-1][0]==1 or result.result[-1][0]==2:#结果为fail和err用例判断
                    if case_num > failcount:
                        success_flag = False
                    else:  
                        print '用例%s第%s次重新执行'%(test,case_num)
                        case_num += 1
                else:
                    success_flag = False
                    
        if topLevel:
            self._tearDownPreviousClass(None, result)
            self._handleModuleTearDown(result)
            result._testRunEntered = False
        return result


然后测试使用

alltests=suit.Suit()

alltests.addtest(WidgetTestCase("testDefaultSize"))

runner =HTMLTestRunner.HTMLTestRunner(stream=fp,verbosity=2,title='android测试报告',description='用例执行情况:',)
runner.run(alltests)

运行完后,有失败重运行的用例都会打印在测试报告里,方便查阅


你可能感兴趣的:(Python)