diff --git a/python/helpers/pycharm/behave_runner.py b/python/helpers/pycharm/behave_runner.py index 03460f556dc7..293005332e3d 100644 --- a/python/helpers/pycharm/behave_runner.py +++ b/python/helpers/pycharm/behave_runner.py @@ -15,6 +15,7 @@ import sys import traceback from behave.formatter.base import Formatter from behave.model import Step, ScenarioOutline, Feature, Scenario +from behave.formatter import _registry from behave.tag_expression import TagExpression from _jb_django_behave import run_as_django_behave import _bdd_utils @@ -238,7 +239,7 @@ class _BehaveRunner(_bdd_utils.BddRunner): for feature in features_to_run: assert isinstance(feature, Feature), feature scenarios = [] - for scenario in feature.scenarios: + for scenario in feature.walk_scenarios(): try: scenario.tags.extend(feature.tags) except AttributeError: @@ -252,7 +253,42 @@ class _BehaveRunner(_bdd_utils.BddRunner): return features_to_run -if __name__ == "__main__": +def _register_null_formatter(format_name): + class _Null(Formatter): + """ + Null formater to prevent stdout output + """ + pass + + _registry.register_as(format_name, _Null) + + +def _register_teamcity_formatter(format_name, base_dir): + custom_messages = tcmessages.TeamcityServiceMessages() + + # Not safe to import it in old mode + from teamcity.jb_behave_formatter import TeamcityFormatter + + class TeamcityFormatterWithLocation(TeamcityFormatter): + + def _report_suite_started(self, suite, suite_name): + location = suite.location + custom_messages.testSuiteStarted( + suite_name, + _bdd_utils.get_location(base_dir, location.filename, location.line) + ) + + def _report_test_started(self, test, test_name): + location = test.location + custom_messages.testStarted( + test_name, + _bdd_utils.get_location(base_dir, location.filename, location.line) + ) + + _registry.register_as(format_name, TeamcityFormatterWithLocation) + + +def main(): # TODO: support all other params instead command_args = list(filter(None, sys.argv[1:])) if command_args: @@ -269,40 +305,14 @@ if __name__ == "__main__": # New version supports 1.2.6 only use_old_runner = "PYCHARM_BEHAVE_OLD_RUNNER" in os.environ - from behave.formatter import _registry - FORMAT_NAME = "com.jetbrains.pycharm.formatter" + format_name = "com.jetbrains.pycharm.formatter" if use_old_runner: - class _Null(Formatter): - """ - Null formater to prevent stdout output - """ - pass - - - _registry.register_as(FORMAT_NAME, _Null) + _register_null_formatter(format_name) else: - custom_messages = tcmessages.TeamcityServiceMessages() - # Not safe to import it in old mode - from teamcity.jb_behave_formatter import TeamcityFormatter + _register_teamcity_formatter(format_name, base_dir) - - class TeamcityFormatterWithLocation(TeamcityFormatter): - - def _report_suite_started(self, suite, suite_name): - location = suite.location - custom_messages.testSuiteStarted(suite_name, - _bdd_utils.get_location(base_dir, location.filename, location.line)) - - def _report_test_started(self, test, test_name): - location = test.location - custom_messages.testStarted(test_name, - _bdd_utils.get_location(base_dir, location.filename, location.line)) - - - _registry.register_as(FORMAT_NAME, TeamcityFormatterWithLocation) - - my_config.format = [FORMAT_NAME] # To prevent output to stdout + my_config.format = [format_name] # To prevent output to stdout my_config.reporters = [] # To prevent summary to stdout my_config.stdout_capture = False # For test output my_config.stderr_capture = False # For test output @@ -318,5 +328,9 @@ if __name__ == "__main__": raise Exception("Nothing to run in {0}".format(what_to_run)) # Run as Django if supported, run plain otherwise - if not run_as_django_behave(FORMAT_NAME, what_to_run, command_args): + if not run_as_django_behave(format_name, what_to_run, command_args): _BehaveRunner(my_config, base_dir, use_old_runner).run() + + +if __name__ == "__main__": + main() diff --git a/python/helpers/testResources/behave_examples/feature_with_rules/rule.feature b/python/helpers/testResources/behave_examples/feature_with_rules/rule.feature new file mode 100644 index 000000000000..d37784921289 --- /dev/null +++ b/python/helpers/testResources/behave_examples/feature_with_rules/rule.feature @@ -0,0 +1,42 @@ +Feature: Gherkin v6 Example -- with Rules + Feature description line 1. + + Background: Feature.Background + Given feature background step_1 + + Rule: R1 (with Rule.Background) + Rule R1 description line 1. + + Background: R1.Background + Given rule R1 background step_1 + When rule R1 background step_2 + + Example: R1.Scenario_1 + When rule R1 scenario_1 step_1 + Then rule R1 scenario_1 step_2 + + Example: R1.Scenario_2 + Given rule R1 scenario_2 step_1 + Then rule R1 scenario_2 step_2 + + Rule: R2 (without Rule.Background) + Rule R2 description line 1. + + Example: R2.Scenario_1 + When rule R2 scenario_1 step_1 + Then rule R2 scenario_1 step_2 + + + Rule: R3 (with empty Rule.Background) + Rule R3 description line 1. + Rule R3 description line 2. + + Background: R3.EmptyBackground + + Scenario Template: R3.Scenario + Given a person named "" + + Examples: + | name | + | Alice | + | Bob | \ No newline at end of file diff --git a/python/helpers/testResources/behave_examples/feature_with_rules/steps/example_steps.py b/python/helpers/testResources/behave_examples/feature_with_rules/steps/example_steps.py new file mode 100644 index 000000000000..98604d37251e --- /dev/null +++ b/python/helpers/testResources/behave_examples/feature_with_rules/steps/example_steps.py @@ -0,0 +1,16 @@ +from behave import step + + +@step('feature background step_{step_id:d}') +def step_feature_background(ctx, step_id): + print("feature background step_{0}".format(step_id)) + + +@step('rule {rule_id:w} background step_{step_id:d}') +def step_rule_background(ctx, rule_id, step_id): + print("rule {0} background step_{1}".format(rule_id, step_id)) + + +@step('rule {rule_id:w} scenario_{scenario_id:d} step_{step_id:d}') +def step_rule_scenario(ctx, rule_id, scenario_id, step_id): + print("rule {0} scenario_{1} step_{2}".format(rule_id, scenario_id, step_id)) diff --git a/python/helpers/testResources/behave_examples/feature_with_rules/steps/person_steps.py b/python/helpers/testResources/behave_examples/feature_with_rules/steps/person_steps.py new file mode 100644 index 000000000000..da2489a31357 --- /dev/null +++ b/python/helpers/testResources/behave_examples/feature_with_rules/steps/person_steps.py @@ -0,0 +1,6 @@ +from behave import given + + +@given('a person named "{name}"') +def step_given_person_with_name(ctx, name): + pass diff --git a/python/helpers/tests/data/remote_sync/output_dir_cannot_be_inside_root/root/out/.keep b/python/helpers/tests/data/remote_sync/output_dir_cannot_be_inside_root/root/out/.keep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/python/helpers/tests/pycharm/test_behave_runner.py b/python/helpers/tests/pycharm/test_behave_runner.py new file mode 100644 index 000000000000..4a2cff220cfb --- /dev/null +++ b/python/helpers/tests/pycharm/test_behave_runner.py @@ -0,0 +1,24 @@ +from pathlib import Path + +from behave import configuration + +from pycharm.behave_runner import _BehaveRunner +from pycharm.behave_runner import _register_null_formatter + + +def test_scenarios_to_run(): + my_config = configuration.Configuration() + helpers_root = Path(__file__).parent.parent.parent + path = helpers_root / "testResources" / "behave_examples" / "feature_with_rules" + my_config.paths = [str(path / "rule.feature")] + base_dir = str(path) + + format_name = "com.jetbrains.pycharm.formatter" + _register_null_formatter(format_name) + my_config.format = [format_name] + + br = _BehaveRunner(my_config, base_dir, use_old_runner=False) + features = br._get_features_to_run() + + assert len(features) == 1 + assert len(list(features[0].scenarios)) == 5