예제 #1
0
 def start_suite(self, suite):
     variables = GLOBAL_VARIABLES.copy()
     variables.set_from_variable_table(suite.variables)
     result = TestSuite(source=suite.source,
                        name=suite.name,
                        doc=suite.doc,
                        metadata=suite.metadata,
                        starttime=get_timestamp())
     if not self.result:
         result.set_criticality(self._settings.critical_tags,
                                self._settings.non_critical_tags)
         self.result = Result(root_suite=result)
         self.result.configure(status_rc=self._settings.status_rc,
                               stat_config=self._settings.statistics_config)
     else:
         self._suite.suites.append(result)
     ns = Namespace(result, variables, self._variables, suite.user_keywords,
                    suite.imports)
     EXECUTION_CONTEXTS.start_suite(ns, self._output,
                                    self._settings.dry_run)
     self._context.set_suite_variables(result)
     if not (self._suite_status and self._suite_status.failures):
         ns.handle_imports()
     variables.resolve_delayed()
     result.doc = self._resolve_setting(result.doc)
     result.metadata = [(self._resolve_setting(n), self._resolve_setting(v))
                        for n, v in result.metadata.items()]
     self._context.set_suite_variables(result)
     self._suite = result
     self._suite_status = SuiteStatus(self._suite_status,
                                      self._settings.exit_on_failure,
                                      self._settings.skip_teardown_on_exit)
     self._output.start_suite(ModelCombiner(suite, self._suite))
     self._run_setup(suite.keywords.setup, self._suite_status)
     self._executed_tests = NormalizedDict(ignore='_')
예제 #2
0
 def start_suite(self, suite):
     variables = GLOBAL_VARIABLES.copy()
     variables.set_from_variable_table(suite.variables)
     result = TestSuite(source=suite.source,
                        name=suite.name,
                        doc=suite.doc,
                        metadata=suite.metadata,
                        starttime=get_timestamp())
     if not self.result:
         result.set_criticality(self._settings.critical_tags,
                                self._settings.non_critical_tags)
         self.result = Result(root_suite=result)
         self.result.configure(status_rc=self._settings.status_rc,
                               stat_config=self._settings.statistics_config)
     else:
         self._suite.suites.append(result)
     ns = Namespace(result, variables, self._variables,
                    suite.user_keywords, suite.imports)
     EXECUTION_CONTEXTS.start_suite(ns, self._output, self._settings.dry_run)
     self._context.set_suite_variables(result)
     if not (self._suite_status and self._suite_status.failures):
         ns.handle_imports()
     variables.resolve_delayed()
     result.doc = self._resolve_setting(result.doc)
     result.metadata = [(self._resolve_setting(n), self._resolve_setting(v))
                        for n, v in result.metadata.items()]
     self._context.set_suite_variables(result)
     self._suite = result
     self._suite_status = SuiteStatus(self._suite_status,
                                      self._settings.exit_on_failure,
                                      self._settings.skip_teardown_on_exit)
     self._output.start_suite(ModelCombiner(suite, self._suite))
     self._run_setup(suite.keywords.setup, self._suite_status)
     self._executed_tests = NormalizedDict(ignore='_')
예제 #3
0
 def start_suite(self, suite):
     if suite.name in self._executed[-1] and suite.parent.source:
         self._output.warn(
             f"Multiple suites with name '{suite.name}' executed in "
             f"suite '{suite.parent.longname}'.")
     self._executed[-1][suite.name] = True
     self._executed.append(NormalizedDict(ignore='_'))
     self._output.library_listeners.new_suite_scope()
     result = TestSuite(source=suite.source,
                        name=suite.name,
                        doc=suite.doc,
                        metadata=suite.metadata,
                        starttime=get_timestamp(),
                        rpa=self._settings.rpa)
     if not self.result:
         self.result = Result(root_suite=result, rpa=self._settings.rpa)
         self.result.configure(status_rc=self._settings.status_rc,
                               stat_config=self._settings.statistics_config)
     else:
         self._suite.suites.append(result)
     self._suite = result
     self._suite_status = SuiteStatus(self._suite_status,
                                      self._settings.exit_on_failure,
                                      self._settings.exit_on_error,
                                      self._settings.skip_teardown_on_exit)
     ns = Namespace(self._variables, result, suite.resource,
                    self._settings.languages)
     ns.start_suite()
     ns.variables.set_from_variable_table(suite.resource.variables)
     EXECUTION_CONTEXTS.start_suite(result, ns, self._output,
                                    self._settings.dry_run)
     self._context.set_suite_variables(result)
     if not self._suite_status.failed:
         ns.handle_imports()
         ns.variables.resolve_delayed()
     result.doc = self._resolve_setting(result.doc)
     result.metadata = [(self._resolve_setting(n), self._resolve_setting(v))
                        for n, v in result.metadata.items()]
     self._context.set_suite_variables(result)
     self._output.start_suite(
         ModelCombiner(suite,
                       result,
                       tests=suite.tests,
                       suites=suite.suites,
                       test_count=suite.test_count))
     self._output.register_error_listener(self._suite_status.error_occurred)
     self._run_setup(suite.setup, self._suite_status)
예제 #4
0
    def test_omit_keywords_during_xml_parsing(self):
        class NonVisitingSuite(TestSuite):
            def visit(self, visitor):
                pass

        result = Result(root_suite=NonVisitingSuite())
        builder = ExecutionResultBuilder(StringIO(GOLDEN_XML),
                                         include_keywords=False)
        builder.build(result)
        assert_equal(len(result.suite.tests[0].body), 0)
예제 #5
0
 def start_suite(self, suite):
     self._output.library_listeners.new_suite_scope()
     result = TestSuite(source=suite.source,
                        name=suite.name,
                        doc=suite.doc,
                        metadata=suite.metadata,
                        starttime=get_timestamp(),
                        rpa=self._settings.rpa)
     if not self.result:
         result.set_criticality(self._settings.critical_tags,
                                self._settings.non_critical_tags)
         self.result = Result(root_suite=result, rpa=self._settings.rpa)
         self.result.configure(status_rc=self._settings.status_rc,
                               stat_config=self._settings.statistics_config)
     else:
         self._suite.suites.append(result)
     self._suite = result
     self._suite_status = SuiteStatus(self._suite_status,
                                      self._settings.exit_on_failure,
                                      self._settings.exit_on_error,
                                      self._settings.skip_teardown_on_exit)
     ns = Namespace(self._variables, result, suite.resource)
     ns.start_suite()
     ns.variables.set_from_variable_table(suite.resource.variables)
     EXECUTION_CONTEXTS.start_suite(result, ns, self._output,
                                    self._settings.dry_run)
     self._context.set_suite_variables(result)
     if not self._suite_status.failures:
         ns.handle_imports()
         ns.variables.resolve_delayed()
     result.doc = self._resolve_setting(result.doc)
     result.metadata = [(self._resolve_setting(n), self._resolve_setting(v))
                        for n, v in result.metadata.items()]
     self._context.set_suite_variables(result)
     self._output.start_suite(
         ModelCombiner(suite,
                       result,
                       tests=suite.tests,
                       suites=suite.suites,
                       test_count=suite.test_count))
     self._output.register_error_listener(self._suite_status.error_occurred)
     self._run_setup(suite.keywords.setup, self._suite_status)
     self._executed_tests = NormalizedDict(ignore='_')
예제 #6
0
 def process_output(self, path):
     set_suite_variable = BuiltIn().set_suite_variable
     if not path or path.upper() == 'NONE':
         set_suite_variable('$SUITE', None)
         logger.info("Not processing output.")
         return
     path = path.replace('/', os.sep)
     try:
         logger.info("Processing output '%s'." % path)
         result = Result(root_suite=NoSlotsTestSuite())
         ExecutionResultBuilder(path).build(result)
     except:
         set_suite_variable('$SUITE', None)
         msg, details = utils.get_error_details()
         logger.info(details)
         raise RuntimeError('Processing output failed: %s' % msg)
     result.visit(ProcessResults())
     set_suite_variable('$SUITE', result.suite)
     set_suite_variable('$STATISTICS', result.statistics)
     set_suite_variable('$ERRORS', result.errors)
예제 #7
0
 def _get_execution_result(self):
     suite = TestSuite(name=self.EXPECTED_SUITE_NAME)
     tc = suite.tests.create(name=self.EXPECTED_TEST_NAME, status='PASS')
     tc.body.create_keyword(kwname=self.EXPECTED_KEYWORD_NAME, status='PASS')
     tc = suite.tests.create(name=self.EXPECTED_FAILING_TEST)
     kw = tc.body.create_keyword(kwname=self.EXPECTED_KEYWORD_NAME)
     kw.body.create_message(message=self.EXPECTED_DEBUG_MESSAGE,
                            level='DEBUG', timestamp='20201212 12:12:12.000')
     errors = ExecutionErrors()
     errors.messages.create(message=self.EXPECTED_ERROR_MESSAGE,
                            level='ERROR', timestamp='20201212 12:12:12.000')
     return Result(root_suite=suite, errors=errors)
예제 #8
0
파일: runner.py 프로젝트: mypstom/robotide
    def start_suite(self, suite):
        with open('Excute.txt', 'w') as f:
            f.write('TS=')
            f.write(str(suite.name))
            f.write('\n')

        self._output.library_listeners.new_suite_scope()
        result = TestSuite(source=suite.source,
                           name=suite.name,
                           doc=suite.doc,
                           metadata=suite.metadata,
                           starttime=get_timestamp())
        if not self.result:
            result.set_criticality(self._settings.critical_tags,
                                   self._settings.non_critical_tags)
            self.result = Result(root_suite=result)
            self.result.configure(status_rc=self._settings.status_rc,
                                  stat_config=self._settings.statistics_config)
        else:
            self._suite.suites.append(result)
        self._suite = result
        self._suite_status = SuiteStatus(self._suite_status,
                                         self._settings.exit_on_failure,
                                         self._settings.exit_on_error,
                                         self._settings.skip_teardown_on_exit)
        ns = Namespace(self._variables, result, suite.resource)
        ns.start_suite()
        ns.variables.set_from_variable_table(suite.resource.variables)
        EXECUTION_CONTEXTS.start_suite(result, ns, self._output,
                                       self._settings.dry_run)
        self._context.set_suite_variables(result)
        if not self._suite_status.failures:
            ns.handle_imports()
            ns.variables.resolve_delayed()
        result.doc = self._resolve_setting(result.doc)
        result.metadata = [(self._resolve_setting(n), self._resolve_setting(v))
                           for n, v in result.metadata.items()]
        self._context.set_suite_variables(result)
        self._output.start_suite(ModelCombiner(suite, result,
                                               tests=suite.tests,
                                               suites=suite.suites,
                                               test_count=suite.test_count))
        self._output.register_error_listener(self._suite_status.error_occurred)
        self._run_setup(suite.keywords.setup, self._suite_status)
        self._executed_tests = NormalizedDict(ignore='_')
예제 #9
0
 def process_output(self, path):
     set_suite_variable = BuiltIn().set_suite_variable
     if not path or path.upper() == 'NONE':
         set_suite_variable('$SUITE', None)
         print("Not processing output.")
         return
     path = path.replace('/', os.sep)
     try:
         print("Processing output '%s'." % path)
         result = Result(root_suite=NoSlotsTestSuite())
         ExecutionResultBuilder(path).build(result)
     except:
         set_suite_variable('$SUITE', None)
         raise RuntimeError('Processing output failed: %s' %
                            utils.get_error_message())
     set_suite_variable('$SUITE', process_suite(result.suite))
     set_suite_variable('$STATISTICS', result.statistics)
     set_suite_variable('$ERRORS', process_errors(result.errors))
예제 #10
0
class Runner(SuiteVisitor):

    def __init__(self, output, settings):
        self.result = None
        self._output = output
        self._settings = settings
        self._variables = VariableScopes(settings)
        self._suite = None
        self._suite_status = None
        self._executed_tests = None

    @property
    def _context(self):
        return EXECUTION_CONTEXTS.current

    def start_suite(self, suite):
        self._output.library_listeners.new_suite_scope()
        result = TestSuite(source=suite.source,
                           name=suite.name,
                           doc=suite.doc,
                           metadata=suite.metadata,
                           starttime=get_timestamp(),
                           rpa=self._settings.rpa)
        if not self.result:
            result.set_criticality(self._settings.critical_tags,
                                   self._settings.non_critical_tags)
            self.result = Result(root_suite=result, rpa=self._settings.rpa)
            self.result.configure(status_rc=self._settings.status_rc,
                                  stat_config=self._settings.statistics_config)
        else:
            self._suite.suites.append(result)
        self._suite = result
        self._suite_status = SuiteStatus(self._suite_status,
                                         self._settings.exit_on_failure,
                                         self._settings.exit_on_error,
                                         self._settings.skip_teardown_on_exit)
        ns = Namespace(self._variables, result, suite.resource)
        ns.start_suite()
        ns.variables.set_from_variable_table(suite.resource.variables)
        EXECUTION_CONTEXTS.start_suite(result, ns, self._output,
                                       self._settings.dry_run)
        self._context.set_suite_variables(result)
        if not self._suite_status.failures:
            ns.handle_imports()
            ns.variables.resolve_delayed()
        result.doc = self._resolve_setting(result.doc)
        result.metadata = [(self._resolve_setting(n), self._resolve_setting(v))
                           for n, v in result.metadata.items()]
        self._context.set_suite_variables(result)
        self._output.start_suite(ModelCombiner(suite, result,
                                               tests=suite.tests,
                                               suites=suite.suites,
                                               test_count=suite.test_count))
        self._output.register_error_listener(self._suite_status.error_occurred)
        self._run_setup(suite.keywords.setup, self._suite_status)
        self._executed_tests = NormalizedDict(ignore='_')

    def _resolve_setting(self, value):
        if is_list_like(value):
            return self._variables.replace_list(value, ignore_errors=True)
        return self._variables.replace_string(value, ignore_errors=True)

    def end_suite(self, suite):
        self._suite.message = self._suite_status.message
        self._context.report_suite_status(self._suite.status,
                                          self._suite.full_message)
        with self._context.suite_teardown():
            failure = self._run_teardown(suite.keywords.teardown, self._suite_status)
            if failure:
                self._suite.suite_teardown_failed(unic(failure))
                if self._suite.statistics.critical.failed:
                    self._suite_status.critical_failure_occurred()
        self._suite.endtime = get_timestamp()
        self._suite.message = self._suite_status.message
        self._context.end_suite(ModelCombiner(suite, self._suite))
        self._suite = self._suite.parent
        self._suite_status = self._suite_status.parent
        self._output.library_listeners.discard_suite_scope()

    def visit_test(self, test):
        if test.name in self._executed_tests:
            self._output.warn("Multiple test cases with name '%s' executed in "
                              "test suite '%s'." % (test.name, self._suite.longname))
        self._executed_tests[test.name] = True
        result = self._suite.tests.create(name=test.name,
                                          doc=self._resolve_setting(test.doc),
                                          tags=self._resolve_setting(test.tags),
                                          starttime=get_timestamp(),
                                          timeout=self._get_timeout(test))
        self._context.start_test(result)
        self._output.start_test(ModelCombiner(test, result))
        status = TestStatus(self._suite_status, result.critical)
        if status.exit:
            self._add_exit_combine()
            result.tags.add('robot:exit')
        if not status.failures and not test.name:
            status.test_failed('Test case name cannot be empty.')
        if not status.failures and not test.keywords.normal:
            status.test_failed('Test case contains no keywords.')
        self._run_setup(test.keywords.setup, status, result)
        try:
            if not status.failures:
                StepRunner(self._context,
                           test.template).run_steps(test.keywords.normal)
            else:
                status.test_failed(status.message)
        except PassExecution as exception:
            err = exception.earlier_failures
            if err:
                status.test_failed(err)
            else:
                result.message = exception.message
        except ExecutionStatus as err:
            status.test_failed(err)
        result.status = status.status
        result.message = status.message or result.message
        if status.teardown_allowed:
            with self._context.test_teardown(result):
                failure = self._run_teardown(test.keywords.teardown, status,
                                             result)
                if failure and result.critical:
                    status.critical_failure_occurred()
        if not status.failures and result.timeout and result.timeout.timed_out():
            status.test_failed(result.timeout.get_message())
            result.message = status.message
        result.status = status.status
        result.endtime = get_timestamp()
        self._output.end_test(ModelCombiner(test, result))
        self._context.end_test(result)

    def _add_exit_combine(self):
        exit_combine = ('NOT robot:exit', '')
        if exit_combine not in self._settings['TagStatCombine']:
            self._settings['TagStatCombine'].append(exit_combine)

    def _get_timeout(self, test):
        if not test.timeout:
            return None
        return TestTimeout(test.timeout.value, test.timeout.message,
                           self._variables, rpa=test.parent.rpa)

    def _run_setup(self, setup, status, result=None):
        if not status.failures:
            exception = self._run_setup_or_teardown(setup)
            status.setup_executed(exception)
            if result and isinstance(exception, PassExecution):
                result.message = exception.message

    def _run_teardown(self, teardown, status, result=None):
        if status.teardown_allowed:
            exception = self._run_setup_or_teardown(teardown)
            status.teardown_executed(exception)
            failed = not isinstance(exception, PassExecution)
            if result and exception:
                result.message = status.message if failed else exception.message
            return exception if failed else None

    def _run_setup_or_teardown(self, data):
        if not data:
            return None
        try:
            name = self._variables.replace_string(data.name)
        except DataError as err:
            if self._settings.dry_run:
                return None
            return err
        if name.upper() in ('', 'NONE'):
            return None
        try:
            StepRunner(self._context).run_step(data, name=name)
        except ExecutionStatus as err:
            return err
예제 #11
0
class Runner(SuiteVisitor):
    def __init__(self, output, settings):
        self.result = None
        self._output = output
        self._settings = settings
        self._suite = None
        self._suite_status = None
        self._executed_tests = None

    @property
    def _context(self):
        return EXECUTION_CONTEXTS.current

    @property
    def _variables(self):
        ctx = self._context
        return ctx.variables if ctx else None

    def start_suite(self, suite):
        variables = GLOBAL_VARIABLES.copy()
        variables.set_from_variable_table(suite.variables)
        result = TestSuite(source=suite.source,
                           name=suite.name,
                           doc=suite.doc,
                           metadata=suite.metadata,
                           starttime=get_timestamp())
        if not self.result:
            result.set_criticality(self._settings.critical_tags,
                                   self._settings.non_critical_tags)
            self.result = Result(root_suite=result)
            self.result.configure(status_rc=self._settings.status_rc,
                                  stat_config=self._settings.statistics_config)
        else:
            self._suite.suites.append(result)
        ns = Namespace(result, variables, self._variables, suite.user_keywords,
                       suite.imports)
        EXECUTION_CONTEXTS.start_suite(ns, self._output,
                                       self._settings.dry_run)
        self._context.set_suite_variables(result)
        if not (self._suite_status and self._suite_status.failures):
            ns.handle_imports()
        variables.resolve_delayed()
        result.doc = self._resolve_setting(result.doc)
        result.metadata = [(self._resolve_setting(n), self._resolve_setting(v))
                           for n, v in result.metadata.items()]
        self._context.set_suite_variables(result)
        self._suite = result
        self._suite_status = SuiteStatus(self._suite_status,
                                         self._settings.exit_on_failure,
                                         self._settings.skip_teardown_on_exit)
        self._output.start_suite(ModelCombiner(suite, self._suite))
        self._run_setup(suite.keywords.setup, self._suite_status)
        self._executed_tests = NormalizedDict(ignore='_')

    def _resolve_setting(self, value):
        return self._variables.replace_string(value, ignore_errors=True)

    def end_suite(self, suite):
        self._suite.message = self._suite_status.message
        self._context.report_suite_status(self._suite.status,
                                          self._suite.full_message)
        with self._context.suite_teardown():
            failure = self._run_teardown(suite.keywords.teardown,
                                         self._suite_status)
            if failure:
                self._suite.suite_teardown_failed(unicode(failure))
        self._suite.endtime = get_timestamp()
        self._suite.message = self._suite_status.message
        self._context.end_suite(self._suite)
        self._suite = self._suite.parent
        self._suite_status = self._suite_status.parent

    def visit_test(self, test):
        if test.name in self._executed_tests:
            self._output.warn("Multiple test cases with name '%s' executed in "
                              "test suite '%s'." %
                              (test.name, self._suite.longname))
        self._executed_tests[test.name] = True
        result = self._suite.tests.create(name=test.name,
                                          doc=self._resolve_setting(test.doc),
                                          tags=test.tags,
                                          starttime=get_timestamp(),
                                          timeout=self._get_timeout(test))
        keywords = Keywords(test.keywords.normal, bool(test.template))
        status = TestStatus(self._suite_status)
        if not status.failures and not test.name:
            status.test_failed('Test case name cannot be empty.',
                               result.critical)
        if not status.failures and not keywords:
            status.test_failed('Test case contains no keywords.',
                               result.critical)
        try:
            result.tags = self._context.variables.replace_list(result.tags)
        except DataError, err:
            status.test_failed(
                'Replacing variables from test tags failed: %s' % unicode(err),
                result.critical)
        self._context.start_test(result)
        self._output.start_test(ModelCombiner(result, test))
        self._run_setup(test.keywords.setup, status, result)
        try:
            if not status.failures:
                keywords.run(self._context)
        except PassExecution, exception:
            err = exception.earlier_failures
            if err:
                status.test_failed(err, result.critical)
            else:
                result.message = exception.message
예제 #12
0
class Runner(SuiteVisitor):

    def __init__(self, output, settings):
        self.result = None
        self._output = output
        self._settings = settings
        self._suite = None
        self._suite_status = None
        self._executed_tests = None

    @property
    def _context(self):
        return EXECUTION_CONTEXTS.current

    @property
    def _variables(self):
        ctx = self._context
        return ctx.variables if ctx else None

    def start_suite(self, suite):
        variables = GLOBAL_VARIABLES.copy()
        variables.set_from_variable_table(suite.variables)
        result = TestSuite(source=suite.source,
                           name=suite.name,
                           doc=suite.doc,
                           metadata=suite.metadata,
                           starttime=get_timestamp())
        if not self.result:
            result.set_criticality(self._settings.critical_tags,
                                   self._settings.non_critical_tags)
            self.result = Result(root_suite=result)
            self.result.configure(status_rc=self._settings.status_rc,
                                  stat_config=self._settings.statistics_config)
        else:
            self._suite.suites.append(result)
        ns = Namespace(result, variables, self._variables,
                       suite.user_keywords, suite.imports)
        EXECUTION_CONTEXTS.start_suite(ns, self._output, self._settings.dry_run)
        self._context.set_suite_variables(result)
        if not (self._suite_status and self._suite_status.failures):
            ns.handle_imports()
        variables.resolve_delayed()
        result.doc = self._resolve_setting(result.doc)
        result.metadata = [(self._resolve_setting(n), self._resolve_setting(v))
                           for n, v in result.metadata.items()]
        self._context.set_suite_variables(result)
        self._suite = result
        self._suite_status = SuiteStatus(self._suite_status,
                                         self._settings.exit_on_failure,
                                         self._settings.skip_teardown_on_exit)
        self._output.start_suite(ModelCombiner(suite, self._suite))
        self._run_setup(suite.keywords.setup, self._suite_status)
        self._executed_tests = NormalizedDict(ignore='_')

    def _resolve_setting(self, value):
        return self._variables.replace_string(value, ignore_errors=True)

    def end_suite(self, suite):
        self._suite.message = self._suite_status.message
        self._context.report_suite_status(self._suite.status,
                                          self._suite.full_message)
        with self._context.suite_teardown():
            failure = self._run_teardown(suite.keywords.teardown, self._suite_status)
            if failure:
                self._suite.suite_teardown_failed(unicode(failure))
        self._suite.endtime = get_timestamp()
        self._suite.message = self._suite_status.message
        self._context.end_suite(self._suite)
        self._suite = self._suite.parent
        self._suite_status = self._suite_status.parent

    def visit_test(self, test):
        if test.name in self._executed_tests:
            self._output.warn("Multiple test cases with name '%s' executed in "
                              "test suite '%s'." % (test.name, self._suite.longname))
        self._executed_tests[test.name] = True
        result = self._suite.tests.create(name=test.name,
                                          doc=self._resolve_setting(test.doc),
                                          tags=test.tags,
                                          starttime=get_timestamp(),
                                          timeout=self._get_timeout(test))
        keywords = Keywords(test.keywords.normal, bool(test.template))
        status = TestStatus(self._suite_status)
        if not status.failures and not test.name:
            status.test_failed('Test case name cannot be empty.', result.critical)
        if not status.failures and not keywords:
            status.test_failed('Test case contains no keywords.', result.critical)
        try:
            result.tags = self._context.variables.replace_list(result.tags)
        except DataError, err:
            status.test_failed('Replacing variables from test tags failed: %s'
                               % unicode(err), result.critical)
        self._context.start_test(result)
        self._output.start_test(ModelCombiner(result, test))
        self._run_setup(test.keywords.setup, status, result)
        try:
            if not status.failures:
                keywords.run(self._context)
        except PassExecution, exception:
            err = exception.earlier_failures
            if err:
                status.test_failed(err, result.critical)
            else:
                result.message = exception.message
예제 #13
0
class Runner(SuiteVisitor):

    def __init__(self, output, settings):
        self.result = None
        self._output = output
        self._settings = settings
        self._variables = VariableScopes(settings)
        self._suite = None
        self._suite_status = None
        self._executed_tests = None

    @property
    def _context(self):
        return EXECUTION_CONTEXTS.current

    def start_suite(self, suite):
        result = TestSuite(source=suite.source,
                           name=suite.name,
                           doc=suite.doc,
                           metadata=suite.metadata,
                           starttime=get_timestamp())
        if not self.result:
            result.set_criticality(self._settings.critical_tags,
                                   self._settings.non_critical_tags)
            self.result = Result(root_suite=result)
            self.result.configure(status_rc=self._settings.status_rc,
                                  stat_config=self._settings.statistics_config)
        else:
            self._suite.suites.append(result)
        self._suite = result
        self._suite_status = SuiteStatus(self._suite_status,
                                         self._settings.exit_on_failure,
                                         self._settings.exit_on_error,
                                         self._settings.skip_teardown_on_exit)
        ns = Namespace(self._variables, result, suite.resource.keywords,
                       suite.resource.imports)
        ns.start_suite()
        ns.variables.set_from_variable_table(suite.resource.variables)
        EXECUTION_CONTEXTS.start_suite(ns, self._output, self._settings.dry_run)
        self._context.set_suite_variables(result)
        if not self._suite_status.failures:
            ns.handle_imports()
            ns.variables.resolve_delayed()
        result.doc = self._resolve_setting(result.doc)
        result.metadata = [(self._resolve_setting(n), self._resolve_setting(v))
                           for n, v in result.metadata.items()]
        self._context.set_suite_variables(result)
        self._output.start_suite(ModelCombiner(result, suite,
                                               tests=suite.tests,
                                               suites=suite.suites,
                                               test_count=suite.test_count))
        self._output.register_error_listener(self._suite_status.error_occurred)
        self._run_setup(suite.keywords.setup, self._suite_status)
        self._executed_tests = NormalizedDict(ignore='_')

    def _resolve_setting(self, value):
        return self._variables.replace_string(value, ignore_errors=True)

    def end_suite(self, suite):
        self._suite.message = self._suite_status.message
        self._context.report_suite_status(self._suite.status,
                                          self._suite.full_message)
        with self._context.suite_teardown():
            failure = self._run_teardown(suite.keywords.teardown, self._suite_status)
            if failure:
                self._suite.suite_teardown_failed(unicode(failure))
                if self._suite.statistics.critical.failed:
                    self._suite_status.critical_failure_occurred()
        self._suite.endtime = get_timestamp()
        self._suite.message = self._suite_status.message
        self._context.end_suite(self._suite)
        self._suite = self._suite.parent
        self._suite_status = self._suite_status.parent

    def visit_test(self, test):
        if test.name in self._executed_tests:
            self._output.warn("Multiple test cases with name '%s' executed in "
                              "test suite '%s'." % (test.name, self._suite.longname))
        self._executed_tests[test.name] = True
        result = self._suite.tests.create(name=test.name,
                                          doc=self._resolve_setting(test.doc),
                                          tags=test.tags,
                                          starttime=get_timestamp(),
                                          timeout=self._get_timeout(test))
        status = TestStatus(self._suite_status, result.critical)
        if not status.failures and not test.name:
            status.test_failed('Test case name cannot be empty.')
        if not status.failures and not test.keywords.normal:
            status.test_failed('Test case contains no keywords.')
        try:
            result.tags = self._context.variables.replace_list(result.tags)
        except DataError as err:
            status.test_failed('Replacing variables from test tags failed: %s'
                               % unicode(err))
        self._context.start_test(result)
        self._output.start_test(ModelCombiner(result, test))
        if status.exit:
            self._add_exit_combine()
            result.tags.add('robot-exit')
        self._run_setup(test.keywords.setup, status, result)
        try:
            if not status.failures:
                runner = KeywordRunner(self._context, bool(test.template))
                runner.run_keywords(test.keywords.normal)
            else:
                status.test_failed(status.message)
        except PassExecution as exception:
            err = exception.earlier_failures
            if err:
                status.test_failed(err)
            else:
                result.message = exception.message
        except ExecutionFailed as err:
            status.test_failed(err)
        result.status = status.status
        result.message = status.message or result.message
        if status.teardown_allowed:
            with self._context.test_teardown(result):
                failure = self._run_teardown(test.keywords.teardown, status,
                                             result)
                if failure and result.critical:
                    status.critical_failure_occurred()
        if not status.failures and result.timeout and result.timeout.timed_out():
            status.test_failed(result.timeout.get_message())
            result.message = status.message
        result.status = status.status
        result.endtime = get_timestamp()
        self._output.end_test(ModelCombiner(result, test))
        self._context.end_test(result)

    def _add_exit_combine(self):
        exit_combine = ('NOT robot-exit', '')
        if exit_combine not in self._settings['TagStatCombine']:
            self._settings['TagStatCombine'].append(exit_combine)

    def _get_timeout(self, test):
        if not test.timeout:
            return None
        timeout = TestTimeout(test.timeout.value, test.timeout.message,
                              self._variables)
        timeout.start()
        return timeout

    def _run_setup(self, setup, status, result=None):
        if not status.failures:
            exception = self._run_setup_or_teardown(setup)
            status.setup_executed(exception)
            if result and isinstance(exception, PassExecution):
                result.message = exception.message

    def _run_teardown(self, teardown, status, result=None):
        if status.teardown_allowed:
            exception = self._run_setup_or_teardown(teardown)
            status.teardown_executed(exception)
            failed = not isinstance(exception, PassExecution)
            if result and exception:
                result.message = status.message if failed else exception.message
            return exception if failed else None

    def _run_setup_or_teardown(self, data):
        if not data:
            return None
        try:
            name = self._variables.replace_string(data.name)
        except DataError as err:
            return err
        if name.upper() in ('', 'NONE'):
            return None
        runner = KeywordRunner(self._context)
        try:
            runner.run_keyword(data, name=name)
        except ExecutionFailed as err:
            return err
예제 #14
0
class SuiteRunner(SuiteVisitor):
    def __init__(self, output, settings):
        self.result = None
        self._output = output
        self._settings = settings
        self._variables = VariableScopes(settings)
        self._suite = None
        self._suite_status = None
        self._executed = [NormalizedDict(ignore='_')]
        self._skipped_tags = TagPatterns(settings.skip)

    @property
    def _context(self):
        return EXECUTION_CONTEXTS.current

    def start_suite(self, suite):
        if suite.name in self._executed[-1] and suite.parent.source:
            self._output.warn(
                f"Multiple suites with name '{suite.name}' executed in "
                f"suite '{suite.parent.longname}'.")
        self._executed[-1][suite.name] = True
        self._executed.append(NormalizedDict(ignore='_'))
        self._output.library_listeners.new_suite_scope()
        result = TestSuite(source=suite.source,
                           name=suite.name,
                           doc=suite.doc,
                           metadata=suite.metadata,
                           starttime=get_timestamp(),
                           rpa=self._settings.rpa)
        if not self.result:
            self.result = Result(root_suite=result, rpa=self._settings.rpa)
            self.result.configure(status_rc=self._settings.status_rc,
                                  stat_config=self._settings.statistics_config)
        else:
            self._suite.suites.append(result)
        self._suite = result
        self._suite_status = SuiteStatus(self._suite_status,
                                         self._settings.exit_on_failure,
                                         self._settings.exit_on_error,
                                         self._settings.skip_teardown_on_exit)
        ns = Namespace(self._variables, result, suite.resource,
                       self._settings.languages)
        ns.start_suite()
        ns.variables.set_from_variable_table(suite.resource.variables)
        EXECUTION_CONTEXTS.start_suite(result, ns, self._output,
                                       self._settings.dry_run)
        self._context.set_suite_variables(result)
        if not self._suite_status.failed:
            ns.handle_imports()
            ns.variables.resolve_delayed()
        result.doc = self._resolve_setting(result.doc)
        result.metadata = [(self._resolve_setting(n), self._resolve_setting(v))
                           for n, v in result.metadata.items()]
        self._context.set_suite_variables(result)
        self._output.start_suite(
            ModelCombiner(suite,
                          result,
                          tests=suite.tests,
                          suites=suite.suites,
                          test_count=suite.test_count))
        self._output.register_error_listener(self._suite_status.error_occurred)
        self._run_setup(suite.setup, self._suite_status)

    def _resolve_setting(self, value):
        if is_list_like(value):
            return self._variables.replace_list(value, ignore_errors=True)
        return self._variables.replace_string(value, ignore_errors=True)

    def end_suite(self, suite):
        self._suite.message = self._suite_status.message
        self._context.report_suite_status(self._suite.status,
                                          self._suite.full_message)
        with self._context.suite_teardown():
            failure = self._run_teardown(suite.teardown, self._suite_status)
            if failure:
                if failure.skip:
                    self._suite.suite_teardown_skipped(str(failure))
                else:
                    self._suite.suite_teardown_failed(str(failure))
        self._suite.endtime = get_timestamp()
        self._suite.message = self._suite_status.message
        self._context.end_suite(ModelCombiner(suite, self._suite))
        self._executed.pop()
        self._suite = self._suite.parent
        self._suite_status = self._suite_status.parent
        self._output.library_listeners.discard_suite_scope()

    def visit_test(self, test):
        settings = self._settings
        if test.tags.robot('exclude'):
            return
        if test.name in self._executed[-1]:
            self._output.warn(
                test_or_task(
                    f"Multiple {{test}}s with name '{test.name}' executed in "
                    f"suite '{test.parent.longname}'.", settings.rpa))
        self._executed[-1][test.name] = True
        result = self._suite.tests.create(self._resolve_setting(test.name),
                                          self._resolve_setting(test.doc),
                                          self._resolve_setting(test.tags),
                                          self._get_timeout(test),
                                          test.lineno,
                                          starttime=get_timestamp())
        self._context.start_test(result)
        self._output.start_test(ModelCombiner(test, result))
        status = TestStatus(self._suite_status, result,
                            settings.skip_on_failure, settings.rpa)
        if status.exit:
            self._add_exit_combine()
            result.tags.add('robot:exit')
        if status.passed:
            if not test.name:
                status.test_failed(
                    test_or_task('{Test} name cannot be empty.', settings.rpa))
            elif not test.body:
                status.test_failed(
                    test_or_task('{Test} contains no keywords.', settings.rpa))
            elif test.tags.robot('skip'):
                status.test_skipped(
                    test_or_task("{Test} skipped using 'robot:skip' tag.",
                                 settings.rpa))
            elif self._skipped_tags.match(test.tags):
                status.test_skipped(
                    test_or_task(
                        "{Test} skipped using '--skip' command line option.",
                        settings.rpa))
        self._run_setup(test.setup, status, result)
        if status.passed:
            try:
                BodyRunner(self._context,
                           templated=bool(test.template)).run(test.body)
            except PassExecution as exception:
                err = exception.earlier_failures
                if err:
                    status.test_failed(error=err)
                else:
                    result.message = exception.message
            except ExecutionStatus as err:
                status.test_failed(error=err)
        elif status.skipped:
            status.test_skipped(status.message)
        else:
            status.test_failed(status.message)
        result.status = status.status
        result.message = status.message or result.message
        with self._context.test_teardown(result):
            self._run_teardown(test.teardown, status, result)
        if status.passed and result.timeout and result.timeout.timed_out():
            status.test_failed(result.timeout.get_message())
            result.message = status.message
        if status.skip_on_failure_after_tag_changes:
            result.message = status.message or result.message
        result.status = status.status
        result.endtime = get_timestamp()
        failed_before_listeners = result.failed
        self._output.end_test(ModelCombiner(test, result))
        if result.failed and not failed_before_listeners:
            status.failure_occurred()
        self._context.end_test(result)

    def _add_exit_combine(self):
        exit_combine = ('NOT robot:exit', '')
        if exit_combine not in self._settings['TagStatCombine']:
            self._settings['TagStatCombine'].append(exit_combine)

    def _get_timeout(self, test):
        if not test.timeout:
            return None
        return TestTimeout(test.timeout, self._variables, rpa=test.parent.rpa)

    def _run_setup(self, setup, status, result=None):
        if status.passed:
            exception = self._run_setup_or_teardown(setup)
            status.setup_executed(exception)
            if result and isinstance(exception, PassExecution):
                result.message = exception.message
        elif status.parent and status.parent.skipped:
            status.skipped = True

    def _run_teardown(self, teardown, status, result=None):
        if status.teardown_allowed:
            exception = self._run_setup_or_teardown(teardown)
            status.teardown_executed(exception)
            failed = exception and not isinstance(exception, PassExecution)
            if result and exception:
                if failed or status.skipped or exception.skip:
                    result.message = status.message
                else:
                    # Pass execution used in teardown,
                    # and it overrides previous failure message
                    result.message = exception.message
            return exception if failed else None

    def _run_setup_or_teardown(self, data):
        if not data:
            return None
        try:
            name = self._variables.replace_string(data.name)
        except DataError as err:
            if self._settings.dry_run:
                return None
            return ExecutionFailed(message=err.message)
        if name.upper() in ('', 'NONE'):
            return None
        try:
            KeywordRunner(self._context).run(data, name=name)
        except ExecutionStatus as err:
            return err