16 from robot.errors import ExecutionFailed, ExecutionStatus, DataError, PassExecution
19 from robot.utils import get_timestamp, is_list_like, NormalizedDict, test_or_task
22 from .bodyrunner
import BodyRunner, KeywordRunner
23 from .context
import EXECUTION_CONTEXTS
24 from .modelcombiner
import ModelCombiner
25 from .namespace
import Namespace
26 from .status
import SuiteStatus, TestStatus
27 from .timeouts
import TestTimeout
39 self.
_executed_executed = [NormalizedDict(ignore=
'_')]
46 return EXECUTION_CONTEXTS.current
49 if suite.name
in self.
_executed_executed[-1]
and suite.parent.source:
50 self.
_output_output.
warn(f
"Multiple suites with name '{suite.name}' executed in "
51 f
"suite '{suite.parent.longname}'.")
52 self.
_executed_executed[-1][suite.name] =
True
53 self.
_executed_executed.append(NormalizedDict(ignore=
'_'))
54 self.
_output_output.library_listeners.new_suite_scope()
58 metadata=suite.metadata,
63 self.
resultresult.configure(status_rc=self.
_settings_settings.status_rc,
64 stat_config=self.
_settings_settings.statistics_config)
66 self.
_suite_suite.suites.append(result)
71 self.
_settings_settings.skip_teardown_on_exit)
74 ns.variables.set_from_variable_table(suite.resource.variables)
75 EXECUTION_CONTEXTS.start_suite(result, ns, self.
_output_output,
80 ns.variables.resolve_delayed()
83 for n, v
in result.metadata.items()]
88 test_count=suite.test_count))
94 return self.
_variables_variables.replace_list(value, ignore_errors=
True)
95 return self.
_variables_variables.replace_string(value, ignore_errors=
True)
100 self.
_suite_suite.full_message)
105 self.
_suite_suite.suite_teardown_skipped(str(failure))
107 self.
_suite_suite.suite_teardown_failed(str(failure))
114 self.
_output_output.library_listeners.discard_suite_scope()
118 if test.tags.robot(
'exclude'):
120 if test.name
in self.
_executed_executed[-1]:
122 test_or_task(f
"Multiple {{test}}s with name '{test.name}' executed in "
123 f
"suite '{test.parent.longname}'.", settings.rpa))
124 self.
_executed_executed[-1][test.name] =
True
137 result.tags.add(
'robot:exit')
141 test_or_task(
'{Test} name cannot be empty.', settings.rpa))
144 test_or_task(
'{Test} contains no keywords.', settings.rpa))
145 elif test.tags.robot(
'skip'):
151 test_or_task(
"{Test} skipped using '--skip' command line option.",
153 self.
_run_setup_run_setup(test.setup, status, result)
157 except PassExecution
as exception:
158 err = exception.earlier_failures
160 status.test_failed(error=err)
162 result.message = exception.message
163 except ExecutionStatus
as err:
164 status.test_failed(error=err)
166 status.test_skipped(status.message)
168 status.test_failed(status.message)
169 result.status = status.status
170 result.message = status.message
or result.message
172 self.
_run_teardown_run_teardown(test.teardown, status, result)
173 if status.passed
and result.timeout
and result.timeout.timed_out():
174 status.test_failed(result.timeout.get_message())
175 result.message = status.message
176 if status.skip_on_failure_after_tag_changes:
177 result.message = status.message
or result.message
178 result.status = status.status
180 failed_before_listeners = result.failed
182 if result.failed
and not failed_before_listeners:
183 status.failure_occurred()
187 exit_combine = (
'NOT robot:exit',
'')
188 if exit_combine
not in self.
_settings_settings[
'TagStatCombine']:
189 self.
_settings_settings[
'TagStatCombine'].append(exit_combine)
199 status.setup_executed(exception)
200 if result
and isinstance(exception, PassExecution):
201 result.message = exception.message
202 elif status.parent
and status.parent.skipped:
203 status.skipped =
True
206 if status.teardown_allowed:
208 status.teardown_executed(exception)
209 failed = exception
and not isinstance(exception, PassExecution)
210 if result
and exception:
211 if failed
or status.skipped
or exception.skip:
212 result.message = status.message
216 result.message = exception.message
217 return exception
if failed
else None
223 name = self.
_variables_variables.replace_string(data.name)
224 except DataError
as err:
228 if name.upper()
in (
'',
'NONE'):
232 except ExecutionStatus
as err:
Used for communicating failures in test execution.
Interface to ease traversing through a test suite structure.
def end_test(self, test)
Called when a test ends.
def start_test(self, test)
Called when a test starts.
Represents results of a single test suite.
def end_suite(self, suite)
Called when a suite ends.
def _run_setup_or_teardown(self, data)
def _resolve_setting(self, value)
def __init__(self, output, settings)
def _get_timeout(self, test)
def _add_exit_combine(self)
def _run_setup(self, setup, status, result=None)
def visit_test(self, test)
Implements traversing through tests.
def start_suite(self, suite)
Called when a suite starts.
def _run_teardown(self, teardown, status, result=None)
def warn(msg, html=False)
Writes the message to the log file using the WARN level.
def run(*tests, **options)
Programmatic entry point for running tests.
def test_or_task(str text, bool rpa)
Replace 'test' with 'task' in the given text depending on rpa.
def get_timestamp(daysep='', daytimesep=' ', timesep=':', millissep='.')