Revision: 3112
Author: janne.t.harkonen
Date: Mon May 3 00:10:16 2010
Log: Handle continuable errors properly in user keywords, cleanup
http://code.google.com/p/robotframework/source/detail?r=3112
Modified:
/trunk/src/robot/running/model.py
/trunk/src/robot/running/runerrors.py
/trunk/src/robot/running/userkeyword.py
=======================================
--- /trunk/src/robot/running/model.py Fri Apr 30 04:09:21 2010
+++ /trunk/src/robot/running/model.py Mon May 3 00:10:16 2010
@@ -213,15 +213,16 @@
namespace.variables['@{TEST_TAGS}'] = self.tags
def _run_setup(self, output, namespace):
- setup_err = self._run_fixture(self.setup, output, namespace)
- self._run_errors.setup_err(setup_err)
+ error = self._run_fixture(self.setup, output, namespace)
+ if error:
+ self._run_errors.setup_err(error.msg)
def _run_keywords(self, output, namespace):
for kw in self.keywords:
- kw_err, can_continue = self._run_with_error_handling(kw,
output, namespace)
- if kw_err:
- self._run_errors.kw_err(kw_err)
- if not can_continue:
+ error = self._run_with_error_handling(kw, output, namespace)
+ if error:
+ self._run_errors.kw_err(error.msg)
+ if not error.cont:
return
def _report_status(self, namespace):
@@ -231,8 +232,9 @@
namespace.variables['${TEST_STATUS}'] = self.status
def _run_teardown(self, output, namespace):
- td_err = self._run_fixture(self.teardown, output, namespace)
- self._run_errors.teardown_err(td_err)
+ error = self._run_fixture(self.teardown, output, namespace)
+ if error:
+ self._run_errors.teardown_err(error.msg)
def _report_status_after_teardown(self):
if self._run_errors.teardown_failed():
@@ -256,16 +258,16 @@
def _run_fixture(self, fixture, output, namespace):
if fixture:
- return self._run_with_error_handling(fixture, output,
namespace)[0]
+ return self._run_with_error_handling(fixture, output,
namespace)
def _run_with_error_handling(self, runnable, output, namespace):
try:
runnable.run(output, namespace)
- return '', True
+ return None
except ExecutionFailed, err:
self.timeout.set_keyword_timeout(err.timeout)
self._suite_errors.test_failed(exit=err.exit)
- return err.msg, err.cont
+ return err
class _TestCaseDefaults:
=======================================
--- /trunk/src/robot/running/runerrors.py Fri Apr 30 04:09:21 2010
+++ /trunk/src/robot/running/runerrors.py Mon May 3 00:10:16 2010
@@ -138,14 +138,7 @@
def get_message(self):
if self._setup_err:
return 'Setup failed:\n%s' % self._setup_err
- if len(self._kw_errs) > 0:
- if len(self._kw_errs) > 1:
- errors = [ 'Error %d: %s' % (i+1, err)
- for i, err in enumerate(self._kw_errs) ]
- else:
- errors = self._kw_errs
- return '\n\n'.join(errors)
- return ''
+ return _form_error_message(self._kw_errs)
def get_teardown_message(self, message):
if message == '':
@@ -154,3 +147,24 @@
def parent_or_init_error(self):
return self._parent_err or self._init_err
+
+
+class UserKeywordRunErrors(object):
+
+ def __init__(self):
+ self._errors = []
+
+ def add(self, msg):
+ self._errors.append(msg)
+
+ def has_errors(self):
+ return bool(self._errors)
+
+ def get_message(self):
+ return _form_error_message(self._errors)
+
+
+def _form_error_message(errors):
+ """Returns list of errors formatted as a string (empty string is
returned if list is empty)"""
+ return '\n\n'.join(errors if len(errors) == 1 else [ 'Error %d: %s' %
(i+1, err)
+ for i, err in
enumerate(errors) ])
=======================================
--- /trunk/src/robot/running/userkeyword.py Fri Apr 30 04:09:21 2010
+++ /trunk/src/robot/running/userkeyword.py Mon May 3 00:10:16 2010
@@ -23,6 +23,7 @@
from keywords import KeywordFactory
from timeouts import KeywordTimeout
from arguments import UserKeywordArguments
+from runerrors import UserKeywordRunErrors
def PublicUserLibrary(path):
@@ -49,7 +50,7 @@
try:
handler = EmbeddedArgsTemplate(handler, self.name)
except TypeError:
- handler = UserHandler(handler, self.name)
+ handler = UserKeywordHandler(handler, self.name)
else:
self.embedded_arg_handlers.append(handler)
if self.handlers.has_key(handler.name):
@@ -99,13 +100,12 @@
"Found: %s" % (where, name, names))
-class UserHandler(object):
+class UserKeywordHandler(object):
type = 'user'
longname = property(lambda self: not self._libname and self.name
or '%s.%s' % (self._libname, self.name))
shortdoc = property(lambda self: self.doc.splitlines()[0] if self.doc
else '')
-
def __init__(self, handlerdata, libname):
self.name = utils.printable_name(handlerdata.name)
self._libname = libname
@@ -141,23 +141,14 @@
def _run(self, output, namespace, arguments):
argument_values = self.arguments.resolve(arguments,
namespace.variables)
self.arguments.set_variables(argument_values, namespace.variables,
- output)
+ output)
self._verify_keyword_is_valid()
self.timeout.start()
- errors = []
+ self._errors = UserKeywordRunErrors()
for kw in self.keywords:
- try:
- kw.run(output, namespace)
- except ExecutionFailed, err:
- if not err.cont:
- raise
- else:
- errors.append(err.msg)
- if errors:
- if len(errors) > 1:
- errors = [ 'Error %d: %s' % (i+1, err)
- for i, err in enumerate(errors) ]
- raise ExecutionFailed('\n\n'.join(errors))
+ self._run_with_error_handling(kw, output, namespace)
+ if self._errors.has_errors():
+ raise ExecutionFailed(self._errors.get_message(), cont=True)
return self._get_return_value(namespace.variables)
def _verify_keyword_is_valid(self):
@@ -168,6 +159,14 @@
raise DataError("User keyword '%s' contains no keywords"
% self.name)
+ def _run_with_error_handling(self, kw, output, namespace):
+ try:
+ kw.run(output, namespace)
+ except ExecutionFailed, err:
+ self._errors.add(err.msg)
+ if not err.cont:
+ raise ExecutionFailed(self._errors.get_message())
+
def _get_return_value(self, variables):
if not self.return_value:
return None
@@ -177,7 +176,7 @@
return ret[0]
-class EmbeddedArgsTemplate(UserHandler):
+class EmbeddedArgsTemplate(UserKeywordHandler):
def __init__(self, handlerdata, libname):
if handlerdata.args:
@@ -186,7 +185,7 @@
= self._read_embedded_args_and_regexp(handlerdata.name)
if not self.embedded_args:
raise TypeError('Must have embedded arguments')
- UserHandler.__init__(self, handlerdata, libname)
+ UserKeywordHandler.__init__(self, handlerdata, libname)
def _read_embedded_args_and_regexp(self, string):
args = []
@@ -208,7 +207,7 @@
return string[:var.start], string[var.start:var.end],
string[var.end:]
-class EmbeddedArgs(UserHandler):
+class EmbeddedArgs(UserKeywordHandler):
def __init__(self, name, template):
match = template.name_regexp.match(name)
@@ -222,7 +221,7 @@
def run(self, output, namespace, args):
for name, value in self.embedded_args:
namespace.variables[name] =
namespace.variables.replace_scalar(value)
- return UserHandler.run(self, output, namespace, args)
+ return UserKeywordHandler.run(self, output, namespace, args)
def _copy_attrs_from_template(self, template):
self._libname = template._libname