2 new revisions:
Revision: 7b737777349a
Author: Janne Härkönen <[email protected]>
Date: Fri May 6 06:28:25 2011
Log: keyword teardown: handle execution errors better...
http://code.google.com/p/robotframework/source/detail?r=7b737777349a
Revision: 637dec02dd10
Author: Janne Härkönen <[email protected]>
Date: Fri May 6 06:28:59 2011
Log: tests for keyword teardown
http://code.google.com/p/robotframework/source/detail?r=637dec02dd10
==============================================================================
Revision: 7b737777349a
Author: Janne Härkönen <[email protected]>
Date: Fri May 6 06:28:25 2011
Log: keyword teardown: handle execution errors better
We need to take into account that the already happened
execution errors may have contunuable or other flags configured
when generating the final error from user keyword
Update issue 711
http://code.google.com/p/robotframework/source/detail?r=7b737777349a
Modified:
/src/robot/errors.py
/src/robot/running/context.py
/src/robot/running/runerrors.py
/src/robot/running/userkeyword.py
=======================================
--- /src/robot/errors.py Sun Feb 6 01:24:10 2011
+++ /src/robot/errors.py Fri May 6 06:28:25 2011
@@ -72,7 +72,7 @@
class ExecutionFailed(RobotError):
"""Used for communicating failures in test execution."""
- def __init__(self, message, timeout=False, syntax=False, exit=False,
+ def __init__(self, message, timeout=False, syntax=False, exit=False,
cont=False, exit_for_loop=False):
RobotError.__init__(self, utils.cut_long_message(message))
self.timeout = timeout
@@ -121,7 +121,8 @@
class ExecutionFailures(ExecutionFailed):
def __init__(self, errors):
- ExecutionFailed.__init__(self, self._format_message(errors),
+ msg = self._format_message(*(unicode(e) for e in errors))
+ ExecutionFailed.__init__(self, msg,
any(err.timeout for err in errors),
any(err.syntax for err in errors),
any(err.exit for err in errors),
@@ -129,17 +130,35 @@
all(err.exit_for_loop for err in errors))
self._errors = errors
- def _format_message(self, errors):
- if len(errors) == 1:
- return unicode(errors[0])
+ def _format_message(self, *msgs):
+ if len(msgs) == 1:
+ return msgs[0]
lines = ['Several failures occurred:'] \
- + ['%d) %s' % (i+1, unicode(e)) for i, e in
enumerate(errors)]
+ + ['%d) %s' % (i+1, m) for i, m in enumerate(msgs)]
return '\n\n'.join(lines)
def get_errors(self):
return self._errors
+class UserKeywordExecutionFailed(ExecutionFailures):
+
+ def __init__(self, run_error, teardown_error):
+ no_error = ExecutionFailed('', cont=True, exit_for_loop=True)
+ errors = (run_error or no_error,
+ teardown_error or no_error)
+ ExecutionFailures.__init__(self, errors)
+ self._errors = run_error.get_errors() if \
+ (run_error and not teardown_error) else [self]
+
+ def _format_message(self, run_msg, td_msg):
+ if not td_msg:
+ return run_msg
+ if not run_msg:
+ return 'Keyword teardown failed:\n%s' % td_msg
+ return '%s\n\nAlso keyword teardown failed:\n%s' % (run_msg,
td_msg)
+
+
class RemoteError(RobotError):
"""Used by Remote library to report remote errors."""
=======================================
--- /src/robot/running/context.py Fri May 6 04:52:43 2011
+++ /src/robot/running/context.py Fri May 6 06:28:25 2011
@@ -21,7 +21,7 @@
self.namespace = namespace
self.output = output
self.dry_run = dry_run
- self._in_teardown = False
+ self._in_teardown = 0
@property
def teardown(self):
@@ -32,10 +32,10 @@
return test_or_suite.status != 'RUNNING'
def start_teardown(self):
- self._in_teardown = True
+ self._in_teardown += 1
def end_teardown(self):
- self._in_teardown = False
+ self._in_teardown -= 1
def get_current_vars(self):
return self.namespace.variables
=======================================
--- /src/robot/running/runerrors.py Fri May 6 04:52:43 2011
+++ /src/robot/running/runerrors.py Fri May 6 06:28:25 2011
@@ -168,8 +168,7 @@
class KeywordRunErrors(object):
def __init__(self):
- self._kw_err = ''
- self._teardown_err = ''
+ self.teardown_error = None
def get_message(self):
if not self._teardown_err:
@@ -179,8 +178,8 @@
return '%s\n\nAlso keyword teardown failed:\n%s' % (self._kw_err,
self._teardown_err)
- def kw_err(self, error):
- self._kw_err = unicode(error)
+
def teardown_err(self, err):
- self._teardown_err = unicode(err)
+ self.teardown_error = err
+
=======================================
--- /src/robot/running/userkeyword.py Fri May 6 04:52:43 2011
+++ /src/robot/running/userkeyword.py Fri May 6 06:28:25 2011
@@ -16,7 +16,7 @@
import re
from robot.common import BaseLibrary, UserErrorHandler
-from robot.errors import DataError, ExecutionFailed
+from robot.errors import DataError, ExecutionFailed,
UserKeywordExecutionFailed
from robot.variables import is_list_var, VariableSplitter
from robot import utils
@@ -149,22 +149,26 @@
args_spec.set_variables(resolved_arguments, variables,
context.output)
self._verify_keyword_is_valid()
self.timeout.start()
- run_errors = KeywordRunErrors()
try:
self.keywords.run(context)
- except ExecutionFailed, err:
- run_errors.kw_err(err)
- self._run_teardown(context, run_errors)
- msg = run_errors.get_message()
- if msg:
- raise ExecutionFailed(msg)
-
- def _run_teardown(self, context, run_errors):
+ except ExecutionFailed, error:
+ pass
+ else:
+ error = None
+ td_error = self._run_teardown(context)
+ if error or td_error:
+ raise UserKeywordExecutionFailed(error, td_error)
+
+ def _run_teardown(self, context):
+ if not self.teardown:
+ return
teardown = Teardown(self.teardown.name, self.teardown.args)
teardown.replace_variables(context.get_current_vars(), [])
context.start_teardown()
+ run_errors = KeywordRunErrors()
teardown.run(context, KeywordTeardownListener(run_errors))
context.end_teardown()
+ return run_errors.teardown_error
def _verify_keyword_is_valid(self):
if self._errors:
@@ -226,9 +230,11 @@
raise TypeError('Does not match given name')
self.embedded_args = zip(template.embedded_args, match.groups())
self.name = name
+ self.teardown = None
self.origname = template.name
self._copy_attrs_from_template(template)
+
def run(self, context, args):
for name, value in self.embedded_args:
context.get_current_vars()[name] =
context.get_current_vars().replace_scalar(value)
==============================================================================
Revision: 637dec02dd10
Author: Janne Härkönen <[email protected]>
Date: Fri May 6 06:28:59 2011
Log: tests for keyword teardown
http://code.google.com/p/robotframework/source/detail?r=637dec02dd10
Added:
/atest/robot/core/keyword_teardown.txt
/atest/testdata/core/keyword_teardown.txt
=======================================
--- /dev/null
+++ /atest/robot/core/keyword_teardown.txt Fri May 6 06:28:59 2011
@@ -0,0 +1,55 @@
+*** Settings ***
+Resource atest_resource.txt
+Force Tags regression pybot jybot
+Suite Setup Run Tests ${EMPTY} core/keyword_teardown.txt
+
+*** Test Cases ***
+Passing Keyword with Teardown
+ ${tc}= Check Test Case ${TESTNAME}
+ Check Log Message ${tc.kws[0].kws[0].msgs[0]} In UK
+ Check Log Message ${tc.kws[0].kws[1].msgs[0]} In UK Teardown
+
+Failing Keyword with Teardown
+ ${tc}= Check Test Case ${TESTNAME}
+ Check Log Message ${tc.kws[0].kws[0].msgs[0]} Expected Failure! FAIL
+ Check Log Message ${tc.kws[0].kws[1].msgs[0]} In Failing UK Teardown
+
+Failure in Keyword Teardown
+ ${tc}= Check Test Case ${TESTNAME}
+ Check Log Message ${tc.kws[0].kws[0].msgs[0]} In UK
+ Check Log Message ${tc.kws[0].kws[1].msgs[0]} Failing in UK
Teardown FAIL
+
+Failures in Keyword and Teardown
+ ${tc}= Check Test Case ${TESTNAME}
+ Check Log Message ${tc.kws[0].kws[0].msgs[0]} Expected Failure! FAIL
+ Check Log Message ${tc.kws[0].kws[1].msgs[0]} Failing in UK
Teardown FAIL
+
+Multiple Failures in Keyword Teardown
+ ${tc}= Check Test Case ${TESTNAME}
+ Check Log Message ${tc.kws[0].kws[1].kws[0].msgs[0]} Failure in
Teardown FAIL
+ Check Log Message ${tc.kws[0].kws[1].kws[1].kws[0].msgs[0]} Expected
Failure! FAIL
+ Check Log Message ${tc.kws[0].kws[1].kws[1].kws[1].msgs[0]} Executed
if in nested Teardown
+ Check Log Message ${tc.kws[0].kws[1].kws[2].msgs[0]} Third failure
in Teardown FAIL
+
+Nested Keyword Teardowns
+ ${tc}= Check Test Case ${TESTNAME}
+ Check Log Message ${tc.kws[0].kws[0].kws[0].msgs[0]} In UK
+ Check Log Message ${tc.kws[0].kws[0].kws[1].msgs[0]} In UK Teardown
+ Check Log Message ${tc.kws[0].kws[1].kws[0].msgs[0]} In UK
+ Check Log Message ${tc.kws[0].kws[1].kws[1].msgs[0]} In UK Teardown
+
+Nested Keyword Teardown Failures
+ ${tc}= Check Test Case ${TESTNAME}
+ Check Log Message ${tc.kws[0].kws[0].kws[1].msgs[0]} Failing in UK
Teardown FAIL
+ Check Log Message ${tc.kws[0].kws[1].msgs[0]} Failing in outer UK
Teardown FAIL
+
+Continuable Failure in Keyword
+ ${tc}= Check Test Case ${TESTNAME}
+ Check Log Message ${tc.kws[0].kws[0].kws[0].msgs[0]} Please
continue FAIL
+ Check Log Message ${tc.kws[0].kws[1].msgs[0]} After continuable
failure
+ Check Log Message ${tc.kws[0].kws[2].msgs[0]} In UK Teardown
+
+Replacing Variables in Keyword Teardown Fails
+ Check Test Case ${TESTNAME}
+
+
=======================================
--- /dev/null
+++ /atest/testdata/core/keyword_teardown.txt Fri May 6 06:28:59 2011
@@ -0,0 +1,81 @@
+*** Test Cases ***
+
+Passing Keyword with Teardown
+ Keyword with Teardown
+
+Failing Keyword with Teardown
+ [Documentation] FAIL Expected Failure!
+ Failing Keyword with Teardown
+
+Failure in Keyword Teardown
+ [Documentation] FAIL Keyword teardown failed:\nFailing in UK Teardown
+ Failure in Keyword Teardown
+ Fail This should never be run
+
+Failures in Keyword and Teardown
+ [Documentation] FAIL Expected Failure!\n\nAlso keyword teardown
failed:\nFailing in UK Teardown
+ Failures in Keyword and Teardown
+
+Multiple Failures in Keyword Teardown
+ [Documentation] FAIL Keyword teardown failed:\nSeveral failures
occurred:\n\n1) Failure in Teardown\n\n2) Expected Failure!\n\n3) Third
failure in Teardown
+ Multiple Failures in Keyword Teardown
+
+Nested Keyword Teardowns
+ Nested Keyword Teardowns
+
+Nested Keyword Teardown Failures
+ [Documentation] FAIL Keyword teardown failed:\nFailing in UK
Teardown\n\nAlso keyword teardown failed:\nFailing in outer UK Teardown
+ Nested Keyword Teardown Failures
+
+Continuable Failure in Keyword
+ [Documentation] FAIL Please continue
+ Continuable Failure in Keyword
+
+Replacing Variables in Keyword Teardown Fails
+ [Documentation] FAIL Keyword teardown failed:\nNo keyword with
name '${NON EXISTING}' found.
+ Replacing Variables in Keyword Teardown Fails
+
+
+*** Keywords ***
+Keyword with Teardown
+ Log In UK
+ [Teardown] Log In UK Teardown
+
+Failing Keyword with Teardown
+ Fail Expected Failure!
+ Log Executed if in nested Teardown
+ [Teardown] Log In Failing UK Teardown
+
+Failure in Keyword Teardown
+ Log In UK
+ [Teardown] Fail Failing in UK Teardown
+
+Failures in Keyword and Teardown
+ Fail Expected Failure!
+ [Teardown] Fail Failing in UK Teardown
+
+Nested Keyword Teardowns
+ Keyword with Teardown
+ [Teardown] Keyword with Teardown
+
+Nested Keyword Teardown Failures
+ Failure in Keyword Teardown
+ [Teardown] Fail Failing in outer UK Teardown
+
+Continuable Failure in Keyword
+ Run Keyword and Continue on Failure Fail Please continue
+ Log After continuable failure
+ [Teardown] Log In UK Teardown
+
+Multiple Failures in Keyword Teardown
+ Log In UK
+ [Teardown] Multiple Failures
+
+Multiple Failures
+ Fail Failure in Teardown
+ Failing keyword with Teardown
+ Fail Third failure in Teardown
+
+Replacing Variables in Keyword Teardown Fails
+ Log In UK
+ [Teardown] ${NON EXISTING}