当我们在做自动化测试的时候,发现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
实例代码:
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)
运行完后,有失败重运行的用例都会打印在测试报告里,方便查阅