Revision: 3162
Author: janne.t.harkonen
Date: Wed May 5 00:15:11 2010
Log: Refactored toward observer-based approach to report failures
http://code.google.com/p/robotframework/source/detail?r=3162
Modified:
/trunk/src/robot/running/fixture.py
/trunk/src/robot/running/model.py
/trunk/src/robot/running/runerrors.py
=======================================
--- /trunk/src/robot/running/fixture.py Tue May 4 09:11:17 2010
+++ /trunk/src/robot/running/fixture.py Wed May 5 00:15:11 2010
@@ -30,13 +30,12 @@
return None
return Keyword(kwdata[0], kwdata[1:],
type=self.__class__.__name__.lower())
- def run(self, output, namespace):
+ def run(self, output, namespace, error_listener):
if self._keyword:
try:
self._keyword.run(output, namespace)
except ExecutionFailed, err:
- return err
- return None
+ error_listener.notify(err)
def serialize(self, serializer):
serializer.start_keyword(self._keyword)
@@ -45,3 +44,37 @@
class Setup(_Fixture): pass
class Teardown(_Fixture): pass
+
+
+
+class SuiteTearDownListener(object):
+ def __init__(self, suite):
+ self._suite = suite
+ def notify(self, error):
+ self._suite.suite_teardown_failed('Suite teardown failed:\n%s'
+ % unicode(error))
+
+
+class SuiteSetupListener(object):
+ def __init__(self, suite):
+ self._suite = suite
+ def notify(self, error):
+ self._suite.run_errors.suite_setup_err(error)
+
+
+class _TestListener(object):
+ def __init__(self, test):
+ self._test = test
+ def notify(self, error):
+ self._test.keyword_failed(error)
+ self._notify_run_errors(error)
+
+
+class TestSetupListener(_TestListener):
+ def _notify_run_errors(self, error):
+ self._test.run_errors.setup_err(error)
+
+
+class TestTeardownListener(_TestListener):
+ def _notify_run_errors(self, error):
+ self._test.run_errors.teardown_err(error)
=======================================
--- /trunk/src/robot/running/model.py Tue May 4 07:58:35 2010
+++ /trunk/src/robot/running/model.py Wed May 5 00:15:11 2010
@@ -19,7 +19,8 @@
from robot.variables import GLOBAL_VARIABLES
from robot.output import LOGGER
-from fixture import Setup, Teardown
+from fixture import Setup, Teardown, SuiteSetupListener,
SuiteTearDownListener,\
+ TestSetupListener, TestTeardownListener
from timeouts import TestTimeout
from keywords import Keywords
from namespace import Namespace
@@ -69,8 +70,8 @@
def _start_run(self, output, parent, errors):
if not errors:
errors = SuiteRunErrors(self._run_mode_exit_on_failure)
- self._run_errors = errors
- self._run_errors.start_suite()
+ self.run_errors = errors
+ self.run_errors.start_suite()
self._init_run(parent)
self._set_variable_dependent_metadata(self.namespace.variables)
output.start_suite(self)
@@ -91,23 +92,21 @@
for name, value in self.metadata.items():
self.metadata[name] = variables.replace_meta(name, value,
errors)
if errors:
- self._run_errors.suite_init_err('Suite initialization
failed:\n%s'
+ self.run_errors.suite_init_err('Suite initialization
failed:\n%s'
% '\n'.join(errors))
def _run_setup(self, output):
- if self._run_errors.is_suite_setup_allowed():
- self._run_errors.suite_setup_err(self.setup.run(output,
-
self.namespace))
+ if self.run_errors.is_suite_setup_allowed():
+ self.setup.run(output, self.namespace,
SuiteSetupListener(self))
+ self.run_errors.setup_executed()
def _run_teardown(self, output):
- if self._run_errors.is_suite_teardown_allowed():
- td_err = self.teardown.run(output, self.namespace)
- if td_err:
- self.suite_teardown_failed('Suite teardown failed:\n%s' %
unicode(td_err))
+ if self.run_errors.is_suite_teardown_allowed():
+ self.teardown.run(output, self.namespace,
SuiteTearDownListener(self))
def _run_sub_suites(self, output):
for suite in self.suites:
- suite.run(output, self, self._run_errors)
+ suite.run(output, self, self.run_errors)
def _run_tests(self, output):
executed_tests = []
@@ -117,12 +116,12 @@
LOGGER.warn("Multiple test cases with name '%s' executed
in "
"test suite '%s'"% (test.name, self.longname))
executed_tests.append(normname)
- test.run(output, self.namespace, self._run_errors)
+ test.run(output, self.namespace, self.run_errors)
self._set_prev_test_variables(self.namespace.variables, test)
def _report_status(self, output):
self.set_status()
- self.message = self._run_errors.suite_error()
+ self.message = self.run_errors.suite_error()
self.namespace.variables['${SUITE_STATUS}'] = self.status
self.namespace.variables['${SUITE_MESSAGE}'] =
self.get_full_message()
@@ -132,7 +131,7 @@
self._set_prev_test_variables(GLOBAL_VARIABLES,
varz=self.namespace.variables)
output.end_suite(self)
self.namespace.end_suite()
- self._run_errors.end_suite()
+ self.run_errors.end_suite()
def _set_prev_test_variables(self, destination, test=None, varz=None):
if test:
@@ -162,17 +161,17 @@
def run(self, output, namespace, suite_errors):
self._suite_errors = suite_errors
self._start_run(output, namespace)
- if self._run_errors.is_allowed_to_run():
+ if self.run_errors.is_allowed_to_run():
self._run(output, namespace)
else:
self._not_allowed_to_run()
self._end_run(output, namespace)
def _start_run(self, output, namespace):
- self._run_errors = TestRunErrors(self._suite_errors)
+ self.run_errors = TestRunErrors(self._suite_errors)
self.status = 'RUNNING'
self.starttime = utils.get_timestamp()
- self._run_errors.init_err(self._init_test(namespace.variables))
+ self.run_errors.init_err(self._init_test(namespace.variables))
namespace.start_test(self)
output.start_test(self)
@@ -195,27 +194,29 @@
self._init_context(namespace)
self.timeout.start()
self._run_setup(output, namespace)
- if not self._run_errors.setup_failed():
+ if not self.run_errors.setup_failed():
try:
self.keywords.run(output, namespace)
except ExecutionFailed, err:
- self._run_errors.kw_err(unicode(err))
- self.timeout.set_keyword_timeout(err.timeout)
- self._suite_errors.test_failed(exit=err.exit)
+ self.run_errors.kw_err(unicode(err))
+ self.keyword_failed(err)
self._report_status(namespace)
self._run_teardown(output, namespace)
self._report_status_after_teardown()
+ def keyword_failed(self, err):
+ self.timeout.set_keyword_timeout(err.timeout)
+ self._suite_errors.test_failed(exit=err.exit)
+
def _init_context(self, namespace):
namespace.variables['${TEST_NAME}'] = self.name
namespace.variables['@{TEST_TAGS}'] = self.tags
def _run_setup(self, output, namespace):
- self._run_fixture(self.setup, output, namespace,
- self._run_errors.setup_err)
+ self.setup.run(output, namespace, TestSetupListener(self))
def _report_status(self, namespace):
- message = self._run_errors.get_message()
+ message = self.run_errors.get_message()
if message:
self.status = 'FAIL'
self.message = message
@@ -225,13 +226,12 @@
namespace.variables['${TEST_STATUS}'] = self.status
def _run_teardown(self, output, namespace):
- self._run_fixture(self.teardown, output, namespace,
- self._run_errors.teardown_err)
+ self.teardown.run(output, namespace, TestTeardownListener(self))
def _report_status_after_teardown(self):
- if self._run_errors.teardown_failed():
+ if self.run_errors.teardown_failed():
self.status = 'FAIL'
- self.message =
self._run_errors.get_teardown_message(self.message)
+ self.message =
self.run_errors.get_teardown_message(self.message)
if self.status == 'PASS' and self.timeout.timed_out():
self.status = 'FAIL'
self.message = self.timeout.get_message()
@@ -240,7 +240,7 @@
def _not_allowed_to_run(self):
self.status = 'FAIL'
- self.message = self._run_errors.parent_or_init_error()
+ self.message = self.run_errors.parent_or_init_error()
def _end_run(self, output, namespace):
self.endtime = utils.get_timestamp()
@@ -248,13 +248,6 @@
output.end_test(self)
namespace.end_test()
- def _run_fixture(self, fixture, output, namespace, error_reporter):
- error = fixture.run(output, namespace)
- if error:
- self.timeout.set_keyword_timeout(error.timeout)
- self._suite_errors.test_failed(exit=error.exit)
- error_reporter(unicode(error))
-
class _TestCaseDefaults:
=======================================
--- /trunk/src/robot/running/runerrors.py Tue May 4 07:58:35 2010
+++ /trunk/src/robot/running/runerrors.py Wed May 5 00:15:11 2010
@@ -66,9 +66,11 @@
def suite_init_err(self, err):
self._current_init_err = err
- def suite_setup_err(self, err):
+ def setup_executed(self):
self._current_suite_setup_executed = True
- self._current_setup_err = unicode(err) if err else self._NO_ERROR
+
+ def suite_setup_err(self, err):
+ self._current_setup_err = unicode(err)
def suite_error(self):
if self._earlier_init_erros_occurred():