失败重试
方式一:源码扩展
使源代码增加--retry选项,实现Test Case级别的失败用例自动再执行:失败用例会重跑N次(默认3次),直至成功或 耗尽重试次数,生成的日志和报告文件中只会体现最后一次执行的结果。
修改代码如下:
Python Home = C:\Python27
Robot Framework库路径为${Python Home}\Lib\site-packages
1、修改robot库中run.py,文件路径为${Python Home}\Lib\site-packages\robot\run.py
- 增加编码注释
# -*-coding:utf-8 -*-
- 引入minidom模块,并设置系统编码
from xml.dom import minidom
reload(sys)
sys.setdefaultencoding('UTF-8')
- 在USAGE的Options中增加retry指令说明
-Y --retry retry Set the retry times if test failed.
- RobotFramework类中增加局部方法_make()
class RobotFramework(Application):
def _make(self,outxml):
xmldoc = minidom.parse(outxml)
suiteElementList = xmldoc.getElementsByTagName('suite')
mySuite = []
for suiteElement in suiteElementList:
if suiteElement.childNodes is not None:
for element in suiteElement.childNodes:
if element.nodeName == 'test':
mySuite.append(suiteElement)
break
for suite in mySuite:
testElements = {}
for element in suite.childNodes:
if element.nodeName == 'test':
name = element.getAttribute('name')
if testElements.get(name) == None:
testElements.update({name:[element]})
else:
testElements.get(name).append(element)
for n,el in testElements.iteritems():
for i in el[0:-1]:
textElement = i.nextSibling
suite.removeChild(i)
suite.removeChild(textElement)
savefile = open(outxml,'w')
root = xmldoc.documentElement
root.writexml(savefile)
savefile.close()
- RobotFramework类中main()方法调用_make()
#RobotFramwwork类完整代码如下
class RobotFramework(Application):
def __init__(self):
Application.__init__(self, USAGE, arg_limits=(1,),
env_options='ROBOT_OPTIONS', logger=LOGGER)
def main(self, datasources, **options):
settings = RobotSettings(options)
LOGGER.register_console_logger(**settings.console_output_config)
LOGGER.info('Settings:\n%s' % unic(settings))
suite = TestSuiteBuilder(settings['SuiteNames'],
settings['WarnOnSkipped'],
settings['Extension']).build(*datasources)
suite.configure(**settings.suite_config)
if settings.pre_run_modifiers:
suite.visit(ModelModifier(settings.pre_run_modifiers,
settings.run_empty_suite, LOGGER))
with pyloggingconf.robot_handler_enabled(settings.log_level):
result = suite.run(settings)
LOGGER.info("Tests execution ended. Statistics:\n%s"
% result.suite.stat_message)
self._make(settings.output)
if settings.log or settings.report or settings.xunit:
writer = ResultWriter(settings.output if settings.log
else result)
writer.write_results(settings.get_rebot_settings())
return result.return_code
def validate(self, options, arguments):
return self._filter_options_without_value(options), arguments
def _filter_options_without_value(self, options):
return dict((name, value) for name, value in options.items()
if value not in (None, []))
def _make(self,outxml):
xmldoc = minidom.parse(outxml)
suiteElementList = xmldoc.getElementsByTagName('suite')
mySuite = []
for suiteElement in suiteElementList:
if suiteElement.childNodes is not None:
for element in suiteElement.childNodes:
if element.nodeName == 'test':
mySuite.append(suiteElement)
break
for suite in mySuite:
testElements = {}
for element in suite.childNodes:
if element.nodeName == 'test':
name = element.getAttribute('name')
if testElements.get(name) == None:
testElements.update({name:[element]})
else:
testElements.get(name).append(element)
for n,el in testElements.iteritems():
for i in el[0:-1]:
textElement = i.nextSibling
suite.removeChild(i)
suite.removeChild(textElement)
savefile = open(outxml,'w')
root = xmldoc.documentElement
root.writexml(savefile)
savefile.close()
2、修改robot库中settings.py,文件路径为${Python Home}\Lib\site-packages\robot\conf\settings.py
- 在RobotSettings类中的_extra_cli_opts字典内增加Retry项
class RobotSettings(_BaseSettings):
_extra_cli_opts = {'Extension' : ('extension', None),
'Output' : ('output', 'output.xml'),
'LogLevel' : ('loglevel', 'INFO'),
'DryRun' : ('dryrun', False),
'ExitOnFailure' : ('exitonfailure', False),
'ExitOnError' : ('exitonerror', False),
'SkipTeardownOnExit' : ('skipteardownonexit', False),
'Randomize' : ('randomize', 'NONE'),
'RunEmptySuite' : ('runemptysuite', False),
'Retry' : ('retry',3),
'WarnOnSkipped' : ('warnonskippedfiles', False),
'Variables' : ('variable', []),
'VariableFiles' : ('variablefile', []),
3、修改robot库中itemlist.py,文件路径为${Python Home}\Lib\site-packages\robot\model\itemlist.py
- 修改visit()方法
# def visit(self, visitor):
# for item in self._items:
# item.visit(visitor)
def visit(self, visitor):
for item in self:
if self.__module__ == 'robot.model.testcase' and hasattr(visitor,"_context"):
testStatus = ''
for i in range(0,int(visitor._settings._opts['Retry'])):
if testStatus != 'PASS':
if item.name in visitor._executed_tests:
visitor._executed_tests.pop(item.name)
item.visit(visitor)
testStatus = visitor._context.variables['${PREV_TEST_STATUS}']
else:
break
else:
item.visit(visitor)
4、修改robotide库中usages.py,文件路径为${Python Home}\Lib\site-packages\robotide\contrib\testrunner\usages.py
- 在USAGE的Options中增加retry指令说明
-Y --retry retry Set the retry times if test failed.
方式二:自带功能
Robot Framework能够从上一次失败的output.xml文件中找出失败的Test Case然后再次执行。
-R --rerunfailed output Select failed tests from an earlier output file to be
re-executed. Equivalent to selecting same tests
individually using --test option.
-S --rerunfailedsuites output Select failed suite from an earlier output file
to be re-executed. New in RF 3.0.1.
-R 基于Test Case;-S 基于Test Suite。
Robot Framework的rebot组件可以合并测试结果。
-R --merge When combining results, merge outputs together
instead of putting them under a new top level suite.
Example: rebot --merge orig.xml rerun.xml
使用逻辑:
- 运行测试用例
robot -d testReport1 testDir
- 调用-R或-S运行第一次失败的用例
robot -d testReport2 -R testReport1\output.xml testDir
- 运用rebot组件合并测试结果
#合并测试结果,并将最终结果存放于testReport3
rebot -d testReport3 -R testReport1\output.xml testReport2\output.xml
#将最后一次的截图存放到testReport3
copy testReport2\*.png testReport3