def test_formatter_background_not_called_when_feature_has_no_background( self): feature = Feature('foo.feature', 1, u'Feature', u'foo') feature.run(self.runner) assert not self.formatters[0].background.called
def test_run_runs_named_scenarios(self): scenarios = [Mock(Scenario), Mock(Scenario)] scenarios[0].name = 'first scenario' scenarios[1].name = 'second scenario' scenarios[0].tags = [] scenarios[1].tags = [] # -- FAKE-CHECK: scenarios[0].should_run_with_name_select.return_value = True scenarios[1].should_run_with_name_select.return_value = False for scenario in scenarios: scenario.run.return_value = False self.config.tags.check.return_value = True # pylint: disable=no-member self.config.name = ['first', 'third'] self.config.name_re = Configuration.build_name_re(self.config.name) feature = Feature('foo.feature', 1, u'Feature', u'foo', scenarios=scenarios) feature.run(self.runner) scenarios[0].run.assert_called_with(self.runner) assert not scenarios[1].run.called scenarios[0].should_run_with_name_select.assert_called_with( self.config) scenarios[1].should_run_with_name_select.assert_called_with( self.config)
def test_run_exclude_named_scenarios_with_regexp(self): # -- NOTE: Works here only because it is run against Mocks. scenarios = [Mock(), Mock(), Mock()] scenarios[0].name = "Alice in Florida" scenarios[1].name = "Alice and Bob" scenarios[2].name = "Bob in Paris" scenarios[0].tags = [] scenarios[1].tags = [] scenarios[2].tags = [] # -- FAKE-CHECK: scenarios[0].should_run_with_name_select.return_value = False scenarios[1].should_run_with_name_select.return_value = False scenarios[2].should_run_with_name_select.return_value = True for scenario in scenarios: scenario.run.return_value = False self.config.tags.check.return_value = True # pylint: disable=no-member self.config.name = ["(?!Alice)"] # Exclude all scenarios with "Alice" self.config.name_re = Configuration.build_name_re(self.config.name) feature = Feature('foo.feature', 1, u'Feature', u'foo', scenarios=scenarios) feature.run(self.runner) assert not scenarios[0].run.called scenarios[0].should_run_with_name_select.assert_called_with(self.config) scenarios[1].should_run_with_name_select.assert_called_with(self.config) scenarios[2].should_run_with_name_select.assert_called_with(self.config) scenarios[0].run.assert_not_called() scenarios[1].run.assert_not_called() scenarios[2].run.assert_called_with(self.runner)
def test_run_runs_named_scenarios(self): scenarios = [Mock(Scenario), Mock(Scenario)] scenarios[0].name = "first scenario" scenarios[1].name = "second scenario" scenarios[0].tags = [] scenarios[1].tags = [] # -- FAKE-CHECK: scenarios[0].should_run_with_name_select.return_value = True scenarios[1].should_run_with_name_select.return_value = False for scenario in scenarios: scenario.run.return_value = False self.config.tag_expression.check.return_value = True # pylint: disable=no-member self.config.name = ["first", "third"] self.config.name_re = Configuration.build_name_re(self.config.name) feature = Feature("foo.feature", 1, u"Feature", u"foo", scenarios=scenarios) feature.run(self.runner) scenarios[0].run.assert_called_with(self.runner) assert not scenarios[1].run.called scenarios[0].should_run_with_name_select.assert_called_with(self.config) scenarios[1].should_run_with_name_select.assert_called_with(self.config)
def test_formatter_feature_called(self): feature = Feature("foo.feature", 1, u"Feature", u"foo", background=Mock()) feature.run(self.runner) self.formatters[0].feature.assert_called_with(feature)
def test_formatter_background_called_when_feature_has_background(self): feature = Feature('foo.feature', 1, u'Feature', u'foo', background=Mock()) feature.run(self.runner) self.formatters[0].background.assert_called_with(feature.background)
def test_run_runs_named_scenarios(self): scenarios = [Mock(Scenario), Mock(Scenario)] scenarios[0].name = 'first scenario' scenarios[1].name = 'second scenario' scenarios[0].tags = [] scenarios[1].tags = [] # -- FAKE-CHECK: scenarios[0].should_run_with_name_select.return_value = True scenarios[1].should_run_with_name_select.return_value = False for scenario in scenarios: scenario.run.return_value = False self.config.tags.check.return_value = True # pylint: disable=no-member self.config.name = ['first', 'third'] self.config.name_re = Configuration.build_name_re(self.config.name) feature = Feature('foo.feature', 1, u'Feature', u'foo', scenarios=scenarios) feature.run(self.runner) scenarios[0].run.assert_called_with(self.runner) assert not scenarios[1].run.called scenarios[0].should_run_with_name_select.assert_called_with(self.config) scenarios[1].should_run_with_name_select.assert_called_with(self.config)
def test_run_runs_named_scenarios(self): scenarios = [Mock(Scenario), Mock(Scenario)] scenarios[0].name = "first scenario" scenarios[1].name = "second scenario" scenarios[0].tags = [] scenarios[1].tags = [] # -- FAKE-CHECK: scenarios[0].should_run_with_name_select.return_value = True scenarios[1].should_run_with_name_select.return_value = False for scenario in scenarios: scenario.run.return_value = False self.config.tag_expression.check.return_value = True # pylint: disable=no-member self.config.name = ["first", "third"] self.config.name_re = Configuration.build_name_re(self.config.name) feature = Feature("foo.feature", 1, u"Feature", u"foo", scenarios=scenarios) feature.run(self.runner) scenarios[0].run.assert_called_with(self.runner) assert not scenarios[1].run.called scenarios[0].should_run_with_name_select.assert_called_with( self.config) scenarios[1].should_run_with_name_select.assert_called_with( self.config)
def before_feature(context: Context, feature: Feature): for tag in feature.tags: parts = tag.split(".") if parts[0] == "uses": val = context for attr in parts[1:]: val = getattr(val, attr, None) if val is None: feature.skip( reason="Skipped because tag value was None: {}".format( tag))
def _feature( self, keyword=u'k\xe9yword', name=u'name', tags=None, location=u'location', # pylint: disable=unused-argument description=None, scenarios=None, background=None): if tags is None: tags = [u'spam', u'ham'] if description is None: description = [u'description'] if scenarios is None: scenarios = [] line = self.line tags = [Tag(name, line) for name in tags] return Feature('<string>', line, keyword, name, tags=tags, description=description, scenarios=scenarios, background=background)
def test_run_runs_scenarios(self): scenarios = [Mock(), Mock()] for scenario in scenarios: scenario.tags = [] scenario.run.return_value = False self.config.tag_expression.check.return_value = True # pylint: disable=no-member self.config.name = [] feature = Feature("foo.feature", 1, u"Feature", u"foo", scenarios=scenarios) feature.run(self.runner) for scenario in scenarios: scenario.run.assert_called_once_with(self.runner)
def _feature( self, keyword=u"k\xe9yword", name=u"name", tags=None, location=u"location", # pylint: disable=unused-argument description=None, scenarios=None, background=None): if tags is None: tags = [u"spam", u"ham"] if description is None: description = [u"description"] if scenarios is None: scenarios = [] line = self.line tags = [Tag(name, line) for name in tags] return Feature("<string>", line, keyword, name, tags=tags, description=description, scenarios=scenarios, background=background)
def run_setup_teardown_tags(ctx: Context, feature: Feature) -> None: """ Finds setup and teardown tags on scenarios in feature files. If present it handles them separately than normal tags Args: ctx: The behave context feature: The behave feature """ remaining_scenarios = [] ctx.teardown_scenarios = [] # Check each feature to see if we have setup or teardown tags. Else they are normal scenarios for scenario in feature.scenarios: # Pipe the feature and scenario into the context so we can use it downstream in child steps ctx.feature = feature ctx.scenario = scenario if "setup" in scenario.tags: LOGGER.info( "Setup scenario detected. Running it before the rest of the feature." ) # Run the steps in the setup scenario as setup execute_scenario_by_steps(ctx, scenario) elif "teardown" in scenario.tags: LOGGER.info( "Teardown scenario detected. Saving it so we can run as cleanup after the rest of the feature." ) ctx.teardown_scenarios.append(scenario) else: remaining_scenarios.append(scenario) feature.scenarios = remaining_scenarios
def test_run_runs_scenarios(self): scenarios = [Mock(), Mock()] for scenario in scenarios: scenario.tags = [] scenario.run.return_value = False self.config.tags.check.return_value = True # pylint: disable=no-member self.config.name = [] feature = Feature('foo.feature', 1, u'Feature', u'foo', scenarios=scenarios) feature.run(self.runner) for scenario in scenarios: scenario.run.assert_called_with(self.runner)
def _feature(self, keyword=u'k\xe9yword', name=u'name', tags=[u'spam', u'ham'], location=u'location', description=[u'description'], scenarios=[], background=None): line = self.line tags = [Tag(name, line) for name in tags] return Feature('<string>', line, keyword, name, tags=tags, description=description, scenarios=scenarios, background=background)
def build_feature(self, name=u"", tags=None): if not name: return None filename = u"%s.feature" % name line = 1 feature = Feature(filename, line, u"Feature", name, tags=tags) self.features.append(feature) self.current_feature = feature return feature
def iter_queue(self): """Iterator fetching features from the queue Note that this iterator is lazy and multiprocess-affected: it cannot know its set of features in advance, will dynamically yield ones as found in the queue """ while True: try: job_id = self.jobsq.get(timeout=0.5) except queue.Empty: break job = self.jobs_map.get(job_id, None) if job is None: print(("ERROR: missing job id=%s from map" % job_id)) self.jobsq.task_done() continue if isinstance(job, Feature): yield job try: self.resultsq.put((job_id, job.send_status())) except Exception as e: print(("ERROR: cannot send result: {0}".format(e))) elif isinstance(job, Scenario): # construct a dummy feature, having only this scenario kwargs = {} for k in ('filename', 'line', 'keyword', 'name', 'tags', 'description', 'background', 'language'): kwargs[k] = getattr(job.feature, k) kwargs['scenarios'] = [job] orig_parser = job.feature.parser feature = Feature(**kwargs) feature.parser = orig_parser yield feature try: self.resultsq.put((job_id, job.send_status())) except Exception as e: print(("ERROR: cannot send result: {0}".format(e))) else: raise TypeError("Don't know how to process: %s" % type(job)) self.jobsq.task_done()
def test_run_exclude_named_scenarios_with_regexp(self): # -- NOTE: Works here only because it is run against Mocks. scenarios = [Mock(), Mock(), Mock()] scenarios[0].name = "Alice in Florida" scenarios[1].name = "Alice and Bob" scenarios[2].name = "Bob in Paris" scenarios[0].tags = [] scenarios[1].tags = [] scenarios[2].tags = [] # -- FAKE-CHECK: scenarios[0].should_run_with_name_select.return_value = False scenarios[1].should_run_with_name_select.return_value = False scenarios[2].should_run_with_name_select.return_value = True for scenario in scenarios: scenario.run.return_value = False self.config.tags.check.return_value = True # pylint: disable=no-member self.config.name = ["(?!Alice)"] # Exclude all scenarios with "Alice" self.config.name_re = Configuration.build_name_re(self.config.name) feature = Feature('foo.feature', 1, u'Feature', u'foo', scenarios=scenarios) feature.run(self.runner) assert not scenarios[0].run.called scenarios[0].should_run_with_name_select.assert_called_with( self.config) scenarios[1].should_run_with_name_select.assert_called_with( self.config) scenarios[2].should_run_with_name_select.assert_called_with( self.config) scenarios[0].run.assert_not_called() scenarios[1].run.assert_not_called() scenarios[2].run.assert_called_with(self.runner)
def run_setup_tags(ctx: Context, feature: Feature) -> None: """Handles setup and teardown tags on scenarios in feature files. If @setup or @teardown is present it handles them separately than normal tags. These tags will be run before and after entire feature by inserting the steps into behave runner via the step executor attached to the context. This is the only way to do this so the setup and teardown "scenario" is not counted towards the test results. @setup tags are run now in this function. @teardown tags are placed on the context in the root layer to be run in the `after feature` hook Args: ctx: The behave context feature: The behave feature """ remaining_scenarios = [] ctx.teardown_scenarios = [] # Check each feature to see if we have setup or teardown tags. Else they are normal scenarios for scenario in feature.scenarios: # Pipe the feature and scenario into the context so we can use it downstream in child steps ctx.feature = feature ctx.scenario = scenario if "setup" in scenario.tags: LOGGER.debug( "Setup scenario detected. Running it before the rest of the feature." ) print( f"\n {ansicolor.yellow('@setup')}\n Scenario: {scenario.name}" ) # noqa # Run the steps in the setup scenario as setup execute_scenario_by_steps(ctx, scenario) elif "teardown" in scenario.tags: LOGGER.debug( "Teardown scenario detected. Saving it so we can run as cleanup after the rest of the feature." ) ctx.teardown_scenarios.append(scenario) else: remaining_scenarios.append(scenario) feature.scenarios = remaining_scenarios
def test_formatter_background_not_called_when_feature_has_no_background(self): feature = Feature('foo.feature', 1, u'Feature', u'foo') feature.run(self.runner) assert not self.formatters[0].background.called
def test_feature_hooks_not_run_if_feature_not_being_run(self): self.config.tags.check.return_value = False # pylint: disable=no-member feature = Feature('foo.feature', 1, u'Feature', u'foo') feature.run(self.runner) assert not self.run_hook.called
def test_feature_hooks_not_run_if_feature_not_being_run(self): self.config.tag_expression.check.return_value = False # pylint: disable=no-member feature = Feature("foo.feature", 1, u"Feature", u"foo") feature.run(self.runner) assert not self.run_hook.called
def before_feature(context: Context, feature: Feature): reason = _should_skip_tags(context, feature.tags) if reason: feature.skip(reason=reason)