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)

Reply via email to