Revision: 3167
Author: KariHusa
Date: Wed May 5 02:37:55 2010
Log: fix continue on failure in for loops
http://code.google.com/p/robotframework/source/detail?r=3167
Modified:
/trunk/atest/robot/running/continue_on_failure.txt
/trunk/atest/testdata/running/continue_on_failure.txt
/trunk/src/robot/running/keywords.py
=======================================
--- /trunk/atest/robot/running/continue_on_failure.txt Tue May 4 09:27:04
2010
+++ /trunk/atest/robot/running/continue_on_failure.txt Wed May 5 02:37:55
2010
@@ -73,6 +73,22 @@
${suite}= Get Test Suite Continue On Failure In Suite Setup
Check Log Message ${suite.setup.kws[1].msgs[0]} This should be
executed in Suite Setup (with ∏ön ÄßÇïï €§)
+Continue in for loop
+ ${tc}= Check Test Case ${TESTNAME}
+ Check Log Message ${tc.kws[0].kws[0].kws[0].msgs[0]}
ContinuableApocalypseException: 0 FAIL
+ Check Log Message ${tc.kws[0].kws[0].kws[1].msgs[0]} This should be
executed inside for loop
+ Check Log Message ${tc.kws[0].kws[1].kws[0].msgs[0]}
ContinuableApocalypseException: 1 FAIL
+ Check Log Message ${tc.kws[0].kws[1].kws[1].msgs[0]} This should be
executed inside for loop
+ Check Log Message ${tc.kws[0].kws[2].kws[0].msgs[0]}
ContinuableApocalypseException: 2 FAIL
+ Check Log Message ${tc.kws[0].kws[2].kws[1].msgs[0]} This should be
executed inside for loop
+ Check Log Message ${tc.kws[0].kws[3].kws[0].msgs[0]}
ContinuableApocalypseException: 3 FAIL
+ Check Log Message ${tc.kws[0].kws[3].kws[1].msgs[0]} This should be
executed inside for loop
+ Check Log Message ${tc.kws[0].kws[4].kws[0].msgs[0]}
ContinuableApocalypseException: 4 FAIL
+ Check Log Message ${tc.kws[0].kws[4].kws[1].msgs[0]} This should be
executed inside for loop
+ Check Log Message ${tc.kws[1].msgs[0]} This should be executed after
for loop
+
+Continuable and regular failure in for loop
+ Check Test Case ${TESTNAME}
*** Keywords ***
Verify all failures in user keyword [Arguments] ${kw} ${where}
=======================================
--- /trunk/atest/testdata/running/continue_on_failure.txt Tue May 4
09:27:04 2010
+++ /trunk/atest/testdata/running/continue_on_failure.txt Wed May 5
02:37:55 2010
@@ -130,6 +130,29 @@
Fail This should not be executed
[Teardown] Several Continuable Failures In User Keyword In Test
Teardown
+Continue in for loop
+ [Documentation] FAIL ${HEADER}\n\n
+ ... 1) ContinuableApocalypseException: 0\n\n
+ ... 2) ContinuableApocalypseException: 1\n\n
+ ... 3) ContinuableApocalypseException: 2\n\n
+ ... 4) ContinuableApocalypseException: 3\n\n
+ ... 5) ContinuableApocalypseException: 4\n\n${TEARDOWN ERROR}
+ :FOR ${i} IN RANGE 0 5
+ \ Raise Continuable Failure ${i}
+ \ Log This should be executed inside for loop
+ Log This should be executed after for loop
+
+Continuable and regular failure in for loop
+ [Documentation] FAIL ${HEADER}\n\n
+ ... 1) ContinuableApocalypseException: janne\n\n
+ ... 2) ContinuableApocalypseException: jussi\n\n
+ ... 3) ContinuableApocalypseException: keijo\n\n
+ ... 4) keijo == keijo\n\n${TEARDOWN ERROR}
+ :FOR ${name} IN janne jussi keijo juha jooseppi
+ \ Raise Continuable Failure ${name}
+ \ Should Not Be Equal ${name} keijo
+ Fail Should not be executed
+
*** User Keywords ***
=======================================
--- /trunk/src/robot/running/keywords.py Tue May 4 06:41:36 2010
+++ /trunk/src/robot/running/keywords.py Wed May 5 02:37:55 2010
@@ -227,7 +227,7 @@
self.items = kwdata.items
self.range = kwdata.range
BaseKeyword.__init__(self, kwdata.name, type='for')
- self.keywords = [ _KeywordFactory(kw) for kw in kwdata.keywords ]
+ self.keywords = Keywords(kwdata.keywords)
def run(self, output, namespace):
self.starttime = utils.get_timestamp()
@@ -242,34 +242,40 @@
error = ExecutionFailed(msg)
else:
error = None
- self.status = error is None and 'PASS' or 'FAIL'
+ self.status = 'PASS' if not error else 'FAIL'
self.endtime = utils.get_timestamp()
self.elapsedtime = utils.get_elapsed_time(self.starttime,
self.endtime)
output.end_keyword(self)
- if error is not None:
+ if error:
raise error
def _run(self, output, namespace):
items = self._replace_vars_from_items(namespace.variables)
+ errors = []
for i in range(0, len(items), len(self.vars)):
values = items[i:i+len(self.vars)]
- self._run_one_round(output, namespace, self.vars, values)
+ error = self._run_one_round(output, namespace, self.vars,
values)
+ if error:
+ errors.extend(error.get_errors())
+ if not error.cont:
+ break
+ if errors:
+ raise ExecutionFailures(errors)
def _run_one_round(self, output, namespace, variables, values):
foritem = ForItemKeyword(variables, values)
output.start_keyword(foritem)
for var, value in zip(variables, values):
namespace.variables[var] = value
- error = None
- for kw in self.keywords:
- try:
- kw.run(output, namespace)
- except ExecutionFailed, error:
- break
- foritem.end(error is None and 'PASS' or 'FAIL')
+ try:
+ self.keywords.run(output, namespace)
+ except ExecutionFailed, error:
+ pass
+ else:
+ error = None
+ foritem.end('PASS' if not error else 'FAIL')
output.end_keyword(foritem)
- if error is not None:
- raise error
+ return error
def _replace_vars_from_items(self, variables):
items = variables.replace_list(self.items)