busser-behave 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.cane +0 -0
- data/.gitignore +17 -0
- data/.tailor +4 -0
- data/.travis.yml +11 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +3 -0
- data/LICENSE +15 -0
- data/README.md +41 -0
- data/Rakefile +68 -0
- data/busser-behave.gemspec +30 -0
- data/features/plugin_install_command.feature +11 -0
- data/features/plugin_list_command.feature +8 -0
- data/features/support/env.rb +13 -0
- data/features/test_command.feature +31 -0
- data/lib/busser/behave/version.rb +26 -0
- data/lib/busser/runner_plugin/behave.rb +37 -0
- data/vendor/behave/CHANGES.rst +483 -0
- data/vendor/behave/LICENSE +23 -0
- data/vendor/behave/MANIFEST.in +37 -0
- data/vendor/behave/PROJECT_INFO.rst +21 -0
- data/vendor/behave/README.rst +112 -0
- data/vendor/behave/VERSION.txt +1 -0
- data/vendor/behave/behave.ini +22 -0
- data/vendor/behave/behave/__init__.py +30 -0
- data/vendor/behave/behave/__main__.py +187 -0
- data/vendor/behave/behave/_stepimport.py +185 -0
- data/vendor/behave/behave/_types.py +134 -0
- data/vendor/behave/behave/api/__init__.py +7 -0
- data/vendor/behave/behave/api/async_step.py +283 -0
- data/vendor/behave/behave/capture.py +227 -0
- data/vendor/behave/behave/compat/__init__.py +5 -0
- data/vendor/behave/behave/compat/collections.py +20 -0
- data/vendor/behave/behave/configuration.py +788 -0
- data/vendor/behave/behave/contrib/__init__.py +0 -0
- data/vendor/behave/behave/contrib/scenario_autoretry.py +73 -0
- data/vendor/behave/behave/formatter/__init__.py +12 -0
- data/vendor/behave/behave/formatter/_builtins.py +39 -0
- data/vendor/behave/behave/formatter/_registry.py +135 -0
- data/vendor/behave/behave/formatter/ansi_escapes.py +91 -0
- data/vendor/behave/behave/formatter/base.py +200 -0
- data/vendor/behave/behave/formatter/formatters.py +57 -0
- data/vendor/behave/behave/formatter/json.py +253 -0
- data/vendor/behave/behave/formatter/null.py +12 -0
- data/vendor/behave/behave/formatter/plain.py +158 -0
- data/vendor/behave/behave/formatter/pretty.py +351 -0
- data/vendor/behave/behave/formatter/progress.py +287 -0
- data/vendor/behave/behave/formatter/rerun.py +114 -0
- data/vendor/behave/behave/formatter/sphinx_steps.py +372 -0
- data/vendor/behave/behave/formatter/sphinx_util.py +118 -0
- data/vendor/behave/behave/formatter/steps.py +497 -0
- data/vendor/behave/behave/formatter/tags.py +178 -0
- data/vendor/behave/behave/i18n.py +614 -0
- data/vendor/behave/behave/importer.py +102 -0
- data/vendor/behave/behave/json_parser.py +264 -0
- data/vendor/behave/behave/log_capture.py +233 -0
- data/vendor/behave/behave/matchers.py +402 -0
- data/vendor/behave/behave/model.py +1737 -0
- data/vendor/behave/behave/model_core.py +416 -0
- data/vendor/behave/behave/model_describe.py +105 -0
- data/vendor/behave/behave/parser.py +615 -0
- data/vendor/behave/behave/reporter/__init__.py +0 -0
- data/vendor/behave/behave/reporter/base.py +45 -0
- data/vendor/behave/behave/reporter/junit.py +473 -0
- data/vendor/behave/behave/reporter/summary.py +94 -0
- data/vendor/behave/behave/runner.py +753 -0
- data/vendor/behave/behave/runner_util.py +417 -0
- data/vendor/behave/behave/step_registry.py +112 -0
- data/vendor/behave/behave/tag_expression.py +111 -0
- data/vendor/behave/behave/tag_matcher.py +465 -0
- data/vendor/behave/behave/textutil.py +137 -0
- data/vendor/behave/behave/userdata.py +130 -0
- data/vendor/behave/behave4cmd0/__all_steps__.py +12 -0
- data/vendor/behave/behave4cmd0/__init__.py +5 -0
- data/vendor/behave/behave4cmd0/__setup.py +11 -0
- data/vendor/behave/behave4cmd0/command_shell.py +216 -0
- data/vendor/behave/behave4cmd0/command_shell_proc.py +256 -0
- data/vendor/behave/behave4cmd0/command_steps.py +532 -0
- data/vendor/behave/behave4cmd0/command_util.py +147 -0
- data/vendor/behave/behave4cmd0/failing_steps.py +49 -0
- data/vendor/behave/behave4cmd0/log/__init__.py +1 -0
- data/vendor/behave/behave4cmd0/log/steps.py +395 -0
- data/vendor/behave/behave4cmd0/note_steps.py +29 -0
- data/vendor/behave/behave4cmd0/passing_steps.py +36 -0
- data/vendor/behave/behave4cmd0/pathutil.py +146 -0
- data/vendor/behave/behave4cmd0/setup_command_shell.py +24 -0
- data/vendor/behave/behave4cmd0/textutil.py +304 -0
- data/vendor/behave/bin/behave +44 -0
- data/vendor/behave/bin/behave.cmd +10 -0
- data/vendor/behave/bin/behave.junit_filter.py +85 -0
- data/vendor/behave/bin/behave.step_durations.py +163 -0
- data/vendor/behave/bin/behave2cucumber_json.py +63 -0
- data/vendor/behave/bin/behave_cmd.py +44 -0
- data/vendor/behave/bin/convert_i18n_yaml.py +77 -0
- data/vendor/behave/bin/explore_platform_encoding.py +24 -0
- data/vendor/behave/bin/i18n.yml +621 -0
- data/vendor/behave/bin/invoke +8 -0
- data/vendor/behave/bin/invoke.cmd +9 -0
- data/vendor/behave/bin/json.format.py +167 -0
- data/vendor/behave/bin/jsonschema_validate.py +122 -0
- data/vendor/behave/bin/make_localpi.py +279 -0
- data/vendor/behave/bin/project_bootstrap.sh +30 -0
- data/vendor/behave/bin/toxcmd.py +270 -0
- data/vendor/behave/bin/toxcmd3.py +270 -0
- data/vendor/behave/conftest.py +27 -0
- data/vendor/behave/docs/Makefile +154 -0
- data/vendor/behave/docs/_static/agogo.css +501 -0
- data/vendor/behave/docs/_static/behave_logo.png +0 -0
- data/vendor/behave/docs/_static/behave_logo1.png +0 -0
- data/vendor/behave/docs/_static/behave_logo2.png +0 -0
- data/vendor/behave/docs/_static/behave_logo3.png +0 -0
- data/vendor/behave/docs/_themes/LICENSE +45 -0
- data/vendor/behave/docs/_themes/kr/layout.html +17 -0
- data/vendor/behave/docs/_themes/kr/relations.html +19 -0
- data/vendor/behave/docs/_themes/kr/static/flasky.css_t +480 -0
- data/vendor/behave/docs/_themes/kr/static/small_flask.css +90 -0
- data/vendor/behave/docs/_themes/kr/theme.conf +7 -0
- data/vendor/behave/docs/_themes/kr_small/layout.html +22 -0
- data/vendor/behave/docs/_themes/kr_small/static/flasky.css_t +287 -0
- data/vendor/behave/docs/_themes/kr_small/theme.conf +10 -0
- data/vendor/behave/docs/api.rst +408 -0
- data/vendor/behave/docs/appendix.rst +19 -0
- data/vendor/behave/docs/behave.rst +640 -0
- data/vendor/behave/docs/behave.rst-template +86 -0
- data/vendor/behave/docs/behave_ecosystem.rst +81 -0
- data/vendor/behave/docs/comparison.rst +85 -0
- data/vendor/behave/docs/conf.py +293 -0
- data/vendor/behave/docs/context_attributes.rst +66 -0
- data/vendor/behave/docs/django.rst +192 -0
- data/vendor/behave/docs/formatters.rst +61 -0
- data/vendor/behave/docs/gherkin.rst +673 -0
- data/vendor/behave/docs/index.rst +57 -0
- data/vendor/behave/docs/install.rst +60 -0
- data/vendor/behave/docs/more_info.rst +184 -0
- data/vendor/behave/docs/new_and_noteworthy.rst +18 -0
- data/vendor/behave/docs/new_and_noteworthy_v1.2.4.rst +11 -0
- data/vendor/behave/docs/new_and_noteworthy_v1.2.5.rst +814 -0
- data/vendor/behave/docs/new_and_noteworthy_v1.2.6.rst +255 -0
- data/vendor/behave/docs/parse_builtin_types.rst +59 -0
- data/vendor/behave/docs/philosophy.rst +235 -0
- data/vendor/behave/docs/regular_expressions.rst +71 -0
- data/vendor/behave/docs/related.rst +14 -0
- data/vendor/behave/docs/test_domains.rst +62 -0
- data/vendor/behave/docs/tutorial.rst +636 -0
- data/vendor/behave/docs/update_behave_rst.py +100 -0
- data/vendor/behave/etc/json/behave.json-schema +172 -0
- data/vendor/behave/etc/junit.xml/behave_junit.xsd +103 -0
- data/vendor/behave/etc/junit.xml/junit-4.xsd +92 -0
- data/vendor/behave/examples/async_step/README.txt +8 -0
- data/vendor/behave/examples/async_step/behave.ini +14 -0
- data/vendor/behave/examples/async_step/features/async_dispatch.feature +8 -0
- data/vendor/behave/examples/async_step/features/async_run.feature +6 -0
- data/vendor/behave/examples/async_step/features/environment.py +28 -0
- data/vendor/behave/examples/async_step/features/steps/async_dispatch_steps.py +26 -0
- data/vendor/behave/examples/async_step/features/steps/async_steps34.py +10 -0
- data/vendor/behave/examples/async_step/features/steps/async_steps35.py +10 -0
- data/vendor/behave/examples/async_step/testrun_example.async_dispatch.txt +11 -0
- data/vendor/behave/examples/async_step/testrun_example.async_run.txt +9 -0
- data/vendor/behave/examples/env_vars/README.rst +26 -0
- data/vendor/behave/examples/env_vars/behave.ini +15 -0
- data/vendor/behave/examples/env_vars/behave_run.output_example.txt +12 -0
- data/vendor/behave/examples/env_vars/features/env_var.feature +6 -0
- data/vendor/behave/examples/env_vars/features/steps/env_var_steps.py +38 -0
- data/vendor/behave/features/README.txt +12 -0
- data/vendor/behave/features/background.feature +392 -0
- data/vendor/behave/features/capture_stderr.feature +172 -0
- data/vendor/behave/features/capture_stdout.feature +125 -0
- data/vendor/behave/features/cmdline.lang_list.feature +33 -0
- data/vendor/behave/features/configuration.default_paths.feature +116 -0
- data/vendor/behave/features/context.global_params.feature +35 -0
- data/vendor/behave/features/context.local_params.feature +17 -0
- data/vendor/behave/features/directory_layout.advanced.feature +147 -0
- data/vendor/behave/features/directory_layout.basic.feature +75 -0
- data/vendor/behave/features/directory_layout.basic2.feature +87 -0
- data/vendor/behave/features/environment.py +53 -0
- data/vendor/behave/features/exploratory_testing.with_table.feature +141 -0
- data/vendor/behave/features/feature.description.feature +0 -0
- data/vendor/behave/features/feature.exclude_from_run.feature +96 -0
- data/vendor/behave/features/formatter.help.feature +30 -0
- data/vendor/behave/features/formatter.json.feature +420 -0
- data/vendor/behave/features/formatter.progress3.feature +235 -0
- data/vendor/behave/features/formatter.rerun.feature +296 -0
- data/vendor/behave/features/formatter.steps.feature +181 -0
- data/vendor/behave/features/formatter.steps_catalog.feature +100 -0
- data/vendor/behave/features/formatter.steps_doc.feature +140 -0
- data/vendor/behave/features/formatter.steps_usage.feature +404 -0
- data/vendor/behave/features/formatter.tags.feature +134 -0
- data/vendor/behave/features/formatter.tags_location.feature +183 -0
- data/vendor/behave/features/formatter.user_defined.feature +196 -0
- data/vendor/behave/features/i18n.unicode_problems.feature +445 -0
- data/vendor/behave/features/logcapture.clear_handlers.feature +114 -0
- data/vendor/behave/features/logcapture.feature +188 -0
- data/vendor/behave/features/logcapture.filter.feature +130 -0
- data/vendor/behave/features/logging.no_capture.feature +99 -0
- data/vendor/behave/features/logging.setup_format.feature +157 -0
- data/vendor/behave/features/logging.setup_level.feature +168 -0
- data/vendor/behave/features/logging.setup_with_configfile.feature +137 -0
- data/vendor/behave/features/parser.background.sad_cases.feature +129 -0
- data/vendor/behave/features/parser.feature.sad_cases.feature +144 -0
- data/vendor/behave/features/runner.abort_by_user.feature +305 -0
- data/vendor/behave/features/runner.continue_after_failed_step.feature +136 -0
- data/vendor/behave/features/runner.default_format.feature +175 -0
- data/vendor/behave/features/runner.dry_run.feature +184 -0
- data/vendor/behave/features/runner.feature_listfile.feature +223 -0
- data/vendor/behave/features/runner.hook_errors.feature +382 -0
- data/vendor/behave/features/runner.multiple_formatters.feature +285 -0
- data/vendor/behave/features/runner.scenario_autoretry.feature +131 -0
- data/vendor/behave/features/runner.select_files_by_regexp.example.feature +71 -0
- data/vendor/behave/features/runner.select_files_by_regexp.feature +84 -0
- data/vendor/behave/features/runner.select_scenarios_by_file_location.feature +403 -0
- data/vendor/behave/features/runner.select_scenarios_by_name.feature +289 -0
- data/vendor/behave/features/runner.select_scenarios_by_tag.feature +225 -0
- data/vendor/behave/features/runner.stop_after_failure.feature +122 -0
- data/vendor/behave/features/runner.tag_logic.feature +67 -0
- data/vendor/behave/features/runner.unknown_formatter.feature +23 -0
- data/vendor/behave/features/runner.use_stage_implementations.feature +126 -0
- data/vendor/behave/features/scenario.description.feature +171 -0
- data/vendor/behave/features/scenario.exclude_from_run.feature +217 -0
- data/vendor/behave/features/scenario_outline.basics.feature +100 -0
- data/vendor/behave/features/scenario_outline.improved.feature +177 -0
- data/vendor/behave/features/scenario_outline.name_annotation.feature +157 -0
- data/vendor/behave/features/scenario_outline.parametrized.feature +401 -0
- data/vendor/behave/features/scenario_outline.tagged_examples.feature +118 -0
- data/vendor/behave/features/step.async_steps.feature +225 -0
- data/vendor/behave/features/step.duplicated_step.feature +106 -0
- data/vendor/behave/features/step.execute_steps.feature +59 -0
- data/vendor/behave/features/step.execute_steps.with_table.feature +65 -0
- data/vendor/behave/features/step.import_other_step_module.feature +103 -0
- data/vendor/behave/features/step.pending_steps.feature +128 -0
- data/vendor/behave/features/step.undefined_steps.feature +307 -0
- data/vendor/behave/features/step.use_step_library.feature +44 -0
- data/vendor/behave/features/step_dialect.generic_steps.feature +189 -0
- data/vendor/behave/features/step_dialect.given_when_then.feature +89 -0
- data/vendor/behave/features/step_param.builtin_types.with_float.feature +239 -0
- data/vendor/behave/features/step_param.builtin_types.with_integer.feature +305 -0
- data/vendor/behave/features/step_param.custom_types.feature +134 -0
- data/vendor/behave/features/steps/behave_active_tags_steps.py +86 -0
- data/vendor/behave/features/steps/behave_context_steps.py +67 -0
- data/vendor/behave/features/steps/behave_model_tag_logic_steps.py +105 -0
- data/vendor/behave/features/steps/behave_model_util.py +105 -0
- data/vendor/behave/features/steps/behave_select_files_steps.py +83 -0
- data/vendor/behave/features/steps/behave_tag_expression_steps.py +166 -0
- data/vendor/behave/features/steps/behave_undefined_steps.py +101 -0
- data/vendor/behave/features/steps/use_steplib_behave4cmd.py +12 -0
- data/vendor/behave/features/summary.undefined_steps.feature +114 -0
- data/vendor/behave/features/tags.active_tags.feature +385 -0
- data/vendor/behave/features/tags.default_tags.feature +104 -0
- data/vendor/behave/features/tags.tag_expression.feature +105 -0
- data/vendor/behave/features/userdata.feature +331 -0
- data/vendor/behave/invoke.yaml +21 -0
- data/vendor/behave/issue.features/README.txt +17 -0
- data/vendor/behave/issue.features/environment.py +97 -0
- data/vendor/behave/issue.features/issue0030.feature +21 -0
- data/vendor/behave/issue.features/issue0031.feature +16 -0
- data/vendor/behave/issue.features/issue0032.feature +28 -0
- data/vendor/behave/issue.features/issue0035.feature +74 -0
- data/vendor/behave/issue.features/issue0040.feature +154 -0
- data/vendor/behave/issue.features/issue0041.feature +135 -0
- data/vendor/behave/issue.features/issue0042.feature +230 -0
- data/vendor/behave/issue.features/issue0044.feature +51 -0
- data/vendor/behave/issue.features/issue0046.feature +77 -0
- data/vendor/behave/issue.features/issue0052.feature +66 -0
- data/vendor/behave/issue.features/issue0059.feature +29 -0
- data/vendor/behave/issue.features/issue0063.feature +102 -0
- data/vendor/behave/issue.features/issue0064.feature +97 -0
- data/vendor/behave/issue.features/issue0065.feature +18 -0
- data/vendor/behave/issue.features/issue0066.feature +80 -0
- data/vendor/behave/issue.features/issue0067.feature +90 -0
- data/vendor/behave/issue.features/issue0069.feature +64 -0
- data/vendor/behave/issue.features/issue0072.feature +32 -0
- data/vendor/behave/issue.features/issue0073.feature +228 -0
- data/vendor/behave/issue.features/issue0075.feature +18 -0
- data/vendor/behave/issue.features/issue0077.feature +89 -0
- data/vendor/behave/issue.features/issue0080.feature +49 -0
- data/vendor/behave/issue.features/issue0081.feature +138 -0
- data/vendor/behave/issue.features/issue0083.feature +69 -0
- data/vendor/behave/issue.features/issue0084.feature +69 -0
- data/vendor/behave/issue.features/issue0085.feature +119 -0
- data/vendor/behave/issue.features/issue0092.feature +66 -0
- data/vendor/behave/issue.features/issue0096.feature +173 -0
- data/vendor/behave/issue.features/issue0099.feature +130 -0
- data/vendor/behave/issue.features/issue0109.feature +60 -0
- data/vendor/behave/issue.features/issue0111.feature +53 -0
- data/vendor/behave/issue.features/issue0112.feature +64 -0
- data/vendor/behave/issue.features/issue0114.feature +118 -0
- data/vendor/behave/issue.features/issue0116.feature +71 -0
- data/vendor/behave/issue.features/issue0125.feature +49 -0
- data/vendor/behave/issue.features/issue0127.feature +64 -0
- data/vendor/behave/issue.features/issue0139.feature +67 -0
- data/vendor/behave/issue.features/issue0142.feature +37 -0
- data/vendor/behave/issue.features/issue0143.feature +54 -0
- data/vendor/behave/issue.features/issue0145.feature +63 -0
- data/vendor/behave/issue.features/issue0148.feature +105 -0
- data/vendor/behave/issue.features/issue0152.feature +52 -0
- data/vendor/behave/issue.features/issue0159.feature +74 -0
- data/vendor/behave/issue.features/issue0162.feature +86 -0
- data/vendor/behave/issue.features/issue0171.feature +16 -0
- data/vendor/behave/issue.features/issue0172.feature +51 -0
- data/vendor/behave/issue.features/issue0175.feature +91 -0
- data/vendor/behave/issue.features/issue0177.feature +40 -0
- data/vendor/behave/issue.features/issue0181.feature +36 -0
- data/vendor/behave/issue.features/issue0184.feature +144 -0
- data/vendor/behave/issue.features/issue0186.feature +12 -0
- data/vendor/behave/issue.features/issue0188.feature +60 -0
- data/vendor/behave/issue.features/issue0191.feature +178 -0
- data/vendor/behave/issue.features/issue0194.feature +215 -0
- data/vendor/behave/issue.features/issue0197.feature +11 -0
- data/vendor/behave/issue.features/issue0216.feature +129 -0
- data/vendor/behave/issue.features/issue0226.feature +51 -0
- data/vendor/behave/issue.features/issue0228.feature +41 -0
- data/vendor/behave/issue.features/issue0230.feature +46 -0
- data/vendor/behave/issue.features/issue0231.feature +77 -0
- data/vendor/behave/issue.features/issue0238.feature +52 -0
- data/vendor/behave/issue.features/issue0251.feature +15 -0
- data/vendor/behave/issue.features/issue0280.feature +118 -0
- data/vendor/behave/issue.features/issue0288.feature +95 -0
- data/vendor/behave/issue.features/issue0300.feature +49 -0
- data/vendor/behave/issue.features/issue0302.feature +91 -0
- data/vendor/behave/issue.features/issue0309.feature +52 -0
- data/vendor/behave/issue.features/issue0330.feature +124 -0
- data/vendor/behave/issue.features/issue0349.feature +9 -0
- data/vendor/behave/issue.features/issue0361.feature +79 -0
- data/vendor/behave/issue.features/issue0383.feature +76 -0
- data/vendor/behave/issue.features/issue0384.feature +103 -0
- data/vendor/behave/issue.features/issue0385.feature +109 -0
- data/vendor/behave/issue.features/issue0424.feature +66 -0
- data/vendor/behave/issue.features/issue0446.feature +116 -0
- data/vendor/behave/issue.features/issue0449.feature +42 -0
- data/vendor/behave/issue.features/issue0453.feature +42 -0
- data/vendor/behave/issue.features/issue0457.feature +65 -0
- data/vendor/behave/issue.features/issue0462.feature +38 -0
- data/vendor/behave/issue.features/issue0476.feature +39 -0
- data/vendor/behave/issue.features/issue0487.feature +92 -0
- data/vendor/behave/issue.features/issue0506.feature +77 -0
- data/vendor/behave/issue.features/issue0510.feature +51 -0
- data/vendor/behave/issue.features/requirements.txt +12 -0
- data/vendor/behave/issue.features/steps/ansi_steps.py +20 -0
- data/vendor/behave/issue.features/steps/behave_hooks_steps.py +10 -0
- data/vendor/behave/issue.features/steps/use_steplib_behave4cmd.py +13 -0
- data/vendor/behave/more.features/formatter.json.validate_output.feature +37 -0
- data/vendor/behave/more.features/steps/tutorial_steps.py +16 -0
- data/vendor/behave/more.features/steps/use_steplib_behave4cmd.py +7 -0
- data/vendor/behave/more.features/tutorial.feature +6 -0
- data/vendor/behave/py.requirements/README.txt +5 -0
- data/vendor/behave/py.requirements/all.txt +16 -0
- data/vendor/behave/py.requirements/basic.txt +21 -0
- data/vendor/behave/py.requirements/develop.txt +28 -0
- data/vendor/behave/py.requirements/docs.txt +6 -0
- data/vendor/behave/py.requirements/json.txt +7 -0
- data/vendor/behave/py.requirements/more_py26.txt +8 -0
- data/vendor/behave/py.requirements/testing.txt +10 -0
- data/vendor/behave/pytest.ini +24 -0
- data/vendor/behave/setup.cfg +29 -0
- data/vendor/behave/setup.py +118 -0
- data/vendor/behave/setuptools_behave.py +130 -0
- data/vendor/behave/tasks/__behave.py +45 -0
- data/vendor/behave/tasks/__init__.py +55 -0
- data/vendor/behave/tasks/__main__.py +70 -0
- data/vendor/behave/tasks/_setup.py +135 -0
- data/vendor/behave/tasks/_vendor/README.rst +35 -0
- data/vendor/behave/tasks/_vendor/invoke.zip +0 -0
- data/vendor/behave/tasks/_vendor/path.py +1725 -0
- data/vendor/behave/tasks/_vendor/pathlib.py +1280 -0
- data/vendor/behave/tasks/_vendor/six.py +868 -0
- data/vendor/behave/tasks/clean.py +246 -0
- data/vendor/behave/tasks/docs.py +97 -0
- data/vendor/behave/tasks/requirements.txt +17 -0
- data/vendor/behave/tasks/test.py +192 -0
- data/vendor/behave/test/__init__.py +0 -0
- data/vendor/behave/test/_importer_candidate.py +3 -0
- data/vendor/behave/test/reporters/__init__.py +0 -0
- data/vendor/behave/test/reporters/test_summary.py +240 -0
- data/vendor/behave/test/test_ansi_escapes.py +73 -0
- data/vendor/behave/test/test_configuration.py +172 -0
- data/vendor/behave/test/test_formatter.py +265 -0
- data/vendor/behave/test/test_formatter_progress.py +39 -0
- data/vendor/behave/test/test_formatter_rerun.py +97 -0
- data/vendor/behave/test/test_formatter_tags.py +57 -0
- data/vendor/behave/test/test_importer.py +151 -0
- data/vendor/behave/test/test_log_capture.py +29 -0
- data/vendor/behave/test/test_matchers.py +236 -0
- data/vendor/behave/test/test_model.py +871 -0
- data/vendor/behave/test/test_parser.py +1590 -0
- data/vendor/behave/test/test_runner.py +1074 -0
- data/vendor/behave/test/test_step_registry.py +96 -0
- data/vendor/behave/test/test_tag_expression.py +506 -0
- data/vendor/behave/test/test_tag_expression2.py +462 -0
- data/vendor/behave/test/test_tag_matcher.py +729 -0
- data/vendor/behave/test/test_userdata.py +184 -0
- data/vendor/behave/tests/README.txt +12 -0
- data/vendor/behave/tests/__init__.py +0 -0
- data/vendor/behave/tests/api/__ONLY_PY34_or_newer.txt +0 -0
- data/vendor/behave/tests/api/__init__.py +0 -0
- data/vendor/behave/tests/api/_test_async_step34.py +130 -0
- data/vendor/behave/tests/api/_test_async_step35.py +75 -0
- data/vendor/behave/tests/api/test_async_step.py +18 -0
- data/vendor/behave/tests/api/testing_support.py +94 -0
- data/vendor/behave/tests/api/testing_support_async.py +21 -0
- data/vendor/behave/tests/issues/test_issue0336.py +66 -0
- data/vendor/behave/tests/issues/test_issue0449.py +55 -0
- data/vendor/behave/tests/issues/test_issue0453.py +62 -0
- data/vendor/behave/tests/issues/test_issue0458.py +54 -0
- data/vendor/behave/tests/issues/test_issue0495.py +65 -0
- data/vendor/behave/tests/unit/__init__.py +0 -0
- data/vendor/behave/tests/unit/test_behave4cmd_command_shell_proc.py +135 -0
- data/vendor/behave/tests/unit/test_capture.py +280 -0
- data/vendor/behave/tests/unit/test_model_core.py +56 -0
- data/vendor/behave/tests/unit/test_textutil.py +267 -0
- data/vendor/behave/tools/test-features/background.feature +9 -0
- data/vendor/behave/tools/test-features/environment.py +8 -0
- data/vendor/behave/tools/test-features/french.feature +11 -0
- data/vendor/behave/tools/test-features/outline.feature +39 -0
- data/vendor/behave/tools/test-features/parse.feature +10 -0
- data/vendor/behave/tools/test-features/step-data.feature +60 -0
- data/vendor/behave/tools/test-features/steps/steps.py +120 -0
- data/vendor/behave/tools/test-features/tags.feature +18 -0
- data/vendor/behave/tox.ini +159 -0
- metadata +562 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
Welcome to behave!
|
|
2
|
+
==================
|
|
3
|
+
|
|
4
|
+
behave is behaviour-driven development, Python style.
|
|
5
|
+
|
|
6
|
+
Behavior-driven development (or BDD) is an agile software development
|
|
7
|
+
technique that encourages collaboration between developers, QA and
|
|
8
|
+
non-technical or business participants in a software project. We have
|
|
9
|
+
a page further describing this :doc:`philosophy <philosophy>`.
|
|
10
|
+
|
|
11
|
+
:pypi:`behave` uses tests written in a natural language style,
|
|
12
|
+
backed up by Python code.
|
|
13
|
+
|
|
14
|
+
Once you've :doc:`installed <install>` *behave*, we recommend reading the
|
|
15
|
+
|
|
16
|
+
* :doc:`tutorial <tutorial>` first and then
|
|
17
|
+
* :doc:`feature test setup <gherkin>`,
|
|
18
|
+
* :doc:`behave API <api>` and
|
|
19
|
+
* :doc:`related software <related>` (things that you can combine with :pypi:`behave`)
|
|
20
|
+
* finally: :doc:`how to use and configure <behave>` the :pypi:`behave` tool.
|
|
21
|
+
|
|
22
|
+
There is also a :doc:`comparison <comparison>` with the other tools available.
|
|
23
|
+
|
|
24
|
+
Contents
|
|
25
|
+
--------
|
|
26
|
+
|
|
27
|
+
.. toctree::
|
|
28
|
+
:maxdepth: 2
|
|
29
|
+
|
|
30
|
+
install
|
|
31
|
+
tutorial
|
|
32
|
+
philosophy
|
|
33
|
+
gherkin
|
|
34
|
+
behave
|
|
35
|
+
api
|
|
36
|
+
django
|
|
37
|
+
comparison
|
|
38
|
+
new_and_noteworthy
|
|
39
|
+
more_info
|
|
40
|
+
appendix
|
|
41
|
+
|
|
42
|
+
.. seealso::
|
|
43
|
+
|
|
44
|
+
* `behave.example`_: `Behave Examples and Tutorials`_ (HTML)
|
|
45
|
+
* Peter Parente: `BDD and Behave <http://tott-meetup.readthedocs.org/en/latest/sessions/behave.html>`_ (tutorial)
|
|
46
|
+
|
|
47
|
+
.. _behave.example: https://github.com/behave/behave.example
|
|
48
|
+
.. _`Behave Examples and Tutorials`: http://behave.github.io/behave.example/
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
Indices and tables
|
|
52
|
+
==================
|
|
53
|
+
|
|
54
|
+
* :ref:`genindex`
|
|
55
|
+
* :ref:`modindex`
|
|
56
|
+
* :ref:`search`
|
|
57
|
+
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
Installation
|
|
2
|
+
============
|
|
3
|
+
|
|
4
|
+
Using pip (or ...)
|
|
5
|
+
------------------
|
|
6
|
+
|
|
7
|
+
:Category: Stable version
|
|
8
|
+
:Precondition: :pypi:`pip` (or :pypi:`setuptools`) is installed
|
|
9
|
+
|
|
10
|
+
Execute the following command to install :pypi:`behave` with :pypi:`pip`:
|
|
11
|
+
|
|
12
|
+
pip install behave
|
|
13
|
+
|
|
14
|
+
To update an already installed :pypi:`behave` version, use:
|
|
15
|
+
|
|
16
|
+
pip install -U behave
|
|
17
|
+
|
|
18
|
+
As an alternative,
|
|
19
|
+
you can also use :pypi:`easy_install <setuptools>` to install :pypi:`behave`::
|
|
20
|
+
|
|
21
|
+
easy_install behave # CASE: New installation.
|
|
22
|
+
easy_install -U behave # CASE: Upgrade existing installation.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
.. hint::
|
|
26
|
+
|
|
27
|
+
See also `pip related information`_ for installing Python packages.
|
|
28
|
+
|
|
29
|
+
.. _`pip related information`: https://pip.pypa.io/en/latest/installing.html
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
Using a Source Distribution
|
|
33
|
+
---------------------------
|
|
34
|
+
|
|
35
|
+
After unpacking the :pypi:`behave` source distribution,
|
|
36
|
+
enter the newly created directory "behave-<version>" and run::
|
|
37
|
+
|
|
38
|
+
python setup.py install
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
Using the Github Repository
|
|
42
|
+
---------------------------
|
|
43
|
+
|
|
44
|
+
:Category: Bleading edge
|
|
45
|
+
:Precondition: :pypi:`pip` is installed
|
|
46
|
+
|
|
47
|
+
Run the following command
|
|
48
|
+
to install the newest version from the `Github repository`_::
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
pip install git+https://github.com/behave/behave
|
|
52
|
+
|
|
53
|
+
To install a tagged version from the `Github repository`_, use::
|
|
54
|
+
|
|
55
|
+
pip install git+https://github.com/behave/behave@<tag>
|
|
56
|
+
|
|
57
|
+
where <tag> is the placeholder for an `existing tag`_.
|
|
58
|
+
|
|
59
|
+
.. _`Github repository`: https://github.com/behave/behave
|
|
60
|
+
.. _`existing tag`: https://github.com/behave/behave/tags
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
.. _id.appendix.more_info:
|
|
2
|
+
|
|
3
|
+
More Information about Behave
|
|
4
|
+
==============================================================================
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Tutorials
|
|
8
|
+
------------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
For new users, that want to read, understand and explore the concepts in Gherkin
|
|
11
|
+
and `behave`_ (after reading the behave documentation):
|
|
12
|
+
|
|
13
|
+
* "`Behave by Example <http://behave.github.io/behave.example/>`_"
|
|
14
|
+
(on `github <https://github.com/behave/behave.example>`_)
|
|
15
|
+
|
|
16
|
+
The following small tutorials provide an introduction how you use `behave`_
|
|
17
|
+
in a specific testing domain:
|
|
18
|
+
|
|
19
|
+
* Phillip Johnson, `Getting Started with Behavior Testing in Python with Behave`_
|
|
20
|
+
* `Bdd with Python, Behave and WebDriver`_
|
|
21
|
+
* Wayne Witzel III, `Using Behave with Pyramid`_, 2014-01-10.
|
|
22
|
+
|
|
23
|
+
.. _`Getting Started with Behavior Testing in Python with Behave`: https://semaphoreci.com/community/tutorials/getting-started-with-behavior-testing-in-python-with-behave
|
|
24
|
+
.. _`Bdd with Python, Behave and WebDriver`: https://testingbot.com/support/getting-started/behave.html
|
|
25
|
+
.. _`Using Behave with Pyramid`: https://www.safaribooksonline.com/blog/2014/01/10/using-behave-with-pyramid/
|
|
26
|
+
|
|
27
|
+
.. warning::
|
|
28
|
+
|
|
29
|
+
A word of caution if you are new to **"behaviour-driven development" (BDD)**.
|
|
30
|
+
In general, you want to avoid "user interface" (UI) details in your
|
|
31
|
+
scenarios, because they describe **how something is implemented**
|
|
32
|
+
(in this case the UI itself), like:
|
|
33
|
+
|
|
34
|
+
* ``press this button``
|
|
35
|
+
* then ``enter this text into the text field``
|
|
36
|
+
* ...
|
|
37
|
+
|
|
38
|
+
In **BDD** (or testing in general), you should describe **what should be done**
|
|
39
|
+
(meaning the intention). This will make your scenarios much more robust
|
|
40
|
+
and stable because you can change the underlying implementation of:
|
|
41
|
+
|
|
42
|
+
* the "system under test" (SUT) or
|
|
43
|
+
* the test automation layer, that interacts with the SUT.
|
|
44
|
+
|
|
45
|
+
without changing the scenarios.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
Books
|
|
49
|
+
------------------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
`Behave`_ is covered in the following books:
|
|
52
|
+
|
|
53
|
+
.. [TDD-Python] Harry Percival,
|
|
54
|
+
`Test-Driven Web Development with Python`_, O'Reilly, June 2014,
|
|
55
|
+
`Appendix E: BDD <http://chimera.labs.oreilly.com/books/1234000000754/ape.html>`_
|
|
56
|
+
(covers behave)
|
|
57
|
+
|
|
58
|
+
.. _`Test-Driven Web Development with Python`: http://chimera.labs.oreilly.com/books/1234000000754
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
Presentation Videos
|
|
62
|
+
------------------------------------------------------------------------------
|
|
63
|
+
|
|
64
|
+
* Benno Rice: `Making Your Application Behave`_ (30min),
|
|
65
|
+
2012-08-12, PyCon Australia.
|
|
66
|
+
|
|
67
|
+
* Selenium: `First behave python tuorial with selenium`_ (8min), 2015-01-28,
|
|
68
|
+
http://www.seleniumframework.com/python-basic/first-behave-gherkin/
|
|
69
|
+
|
|
70
|
+
* Jessica Ingrasselino: `Automation with Python and Behave`_ (67min), 2015-12-16
|
|
71
|
+
|
|
72
|
+
* `Selenium Python Webdriver Tutorial - Behave (BDD)`_ (14min), 2016-01-21
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
.. hidden:
|
|
76
|
+
|
|
77
|
+
PREPARED:
|
|
78
|
+
---------------------
|
|
79
|
+
|
|
80
|
+
.. ifconfig:: not supports_video
|
|
81
|
+
|
|
82
|
+
* Benno Rice: `Making Your Application Behave`_ (30min),
|
|
83
|
+
PyCon Australia, 2012-08-12
|
|
84
|
+
|
|
85
|
+
* Selenium: `First behave python tuorial with selenium`_ (8min), 2015-01-28,
|
|
86
|
+
http://www.seleniumframework.com/python-basic/first-behave-gherkin/
|
|
87
|
+
|
|
88
|
+
* Jessica Ingrasselino: `Automation with Python and Behave`_ (67min), 2015-12-16
|
|
89
|
+
|
|
90
|
+
* `Selenium Python Webdriver Tutorial - Behave (BDD)`_ (14min), 2016-01-21
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
.. hint::
|
|
94
|
+
|
|
95
|
+
Manually install `sphinxcontrib-youtube`_
|
|
96
|
+
(from "youtube" subdirectory in sphinx-extensions bundle)
|
|
97
|
+
to have embedded videos on this page (when this page is build).
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
.. ifconfig:: supports_video
|
|
101
|
+
|
|
102
|
+
Benno Rice: `Making Your Application Behave`_
|
|
103
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
104
|
+
|
|
105
|
+
:Conference: PyCon Australia
|
|
106
|
+
:Date: 2012-08-12
|
|
107
|
+
:Duration: 30min
|
|
108
|
+
|
|
109
|
+
.. youtube:: u8BOKuNkmhg
|
|
110
|
+
:width: 600
|
|
111
|
+
:height: 400
|
|
112
|
+
|
|
113
|
+
Selenium: `First behave python tuorial with selenium`_
|
|
114
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
115
|
+
|
|
116
|
+
:Date: 2015-01-28
|
|
117
|
+
:Duration: 8min
|
|
118
|
+
|
|
119
|
+
.. youtube:: D24_QrGUCFk
|
|
120
|
+
:width: 600
|
|
121
|
+
:height: 400
|
|
122
|
+
|
|
123
|
+
RELATED: http://www.seleniumframework.com/python-basic/what-is-python/
|
|
124
|
+
|
|
125
|
+
Jessica Ingrasselino: `Automation with Python and Behave`_
|
|
126
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
127
|
+
|
|
128
|
+
:Date: 2015-12-16
|
|
129
|
+
:Duration: 67min
|
|
130
|
+
|
|
131
|
+
.. youtube:: e78c7h6DRDQ
|
|
132
|
+
:width: 600
|
|
133
|
+
:height: 400
|
|
134
|
+
|
|
135
|
+
`Selenium Python Webdriver Tutorial - Behave (BDD)`_
|
|
136
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
137
|
+
|
|
138
|
+
:Date: 2016-01-21
|
|
139
|
+
:Duration: 14min
|
|
140
|
+
|
|
141
|
+
.. youtube:: mextSo0UExc
|
|
142
|
+
:width: 600
|
|
143
|
+
:height: 400
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
.. _`Making Your Application Behave`: https://www.youtube.com/watch?v=u8BOKuNkmhg
|
|
147
|
+
.. _`First behave python tuorial with selenium`: https://www.youtube.com/watch?v=D24_QrGUCFk
|
|
148
|
+
.. _`Automation with Python and Behave`: https://www.youtube.com/watch?v=e78c7h6DRDQ
|
|
149
|
+
.. _`Selenium Python Webdriver Tutorial - Behave (BDD)`: https://www.youtube.com/watch?v=mextSo0UExc
|
|
150
|
+
|
|
151
|
+
.. _sphinxcontrib-youtube: https://bitbucket.org/birkenfeld/sphinx-contrib
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
Tool-oriented Tutorials
|
|
155
|
+
------------------------------------------------------------------------------
|
|
156
|
+
|
|
157
|
+
JetBrains PyCharm:
|
|
158
|
+
|
|
159
|
+
* Blog: `In-Depth Screencast on Testing`_ (2016-04-11; video offset=2:10min)
|
|
160
|
+
* Docs: `BDD Testing Framework Support in PyCharm 2016.1
|
|
161
|
+
<https://www.jetbrains.com/help/pycharm/2016.1/bdd-testing-framework.html>`_
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
.. _`Getting Started with PyCharm`: https://www.youtube.com/playlist?list=PLQ176FUIyIUZ1mwB-uImQE-gmkwzjNLjP
|
|
165
|
+
.. _`PyCharm In-Depth: Testing`: https://youtu.be/nmBbR97Vsv8?list=PLQ176FUIyIUZ1mwB-uImQE-gmkwzjNLjP
|
|
166
|
+
.. _`In-Depth Screencast on Testing`: http://blog.jetbrains.com/pycharm/2016/04/in-depth-screencast-on-testing/
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
Find more Information
|
|
171
|
+
------------------------------------------------------------------------------
|
|
172
|
+
|
|
173
|
+
.. seealso::
|
|
174
|
+
|
|
175
|
+
* google:`python-behave examples <https://www.google.com/?q=python-behave%20examples>`_
|
|
176
|
+
* google:`python-behave tutorials <https://www.google.com/?q=python-behave%20tutorials>`_
|
|
177
|
+
* google:`python-behave videos <https://www.google.com/?q=python-behave%20videos>`_
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
.. _Behave: https://github.com/behave/behave
|
|
181
|
+
.. _behave: https://github.com/behave/behave
|
|
182
|
+
.. _Selenium: http://docs.seleniumhq.org/
|
|
183
|
+
.. _behave4cmd: https://github.com/behave/behave4cmd
|
|
184
|
+
.. _behave-django: https://github.com/behave/behave-django
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
New and Noteworthy
|
|
2
|
+
==============================================================================
|
|
3
|
+
|
|
4
|
+
In the good tradition of the `Eclipse IDE`_,
|
|
5
|
+
a number of news, changes and improvements are described here to provide
|
|
6
|
+
better background information about what has changed and how to make use of it.
|
|
7
|
+
|
|
8
|
+
This page orders the information by newest version first.
|
|
9
|
+
|
|
10
|
+
.. _`Eclipse IDE`: http://www.eclipse.org/
|
|
11
|
+
|
|
12
|
+
.. toctree::
|
|
13
|
+
:maxdepth: 2
|
|
14
|
+
|
|
15
|
+
new_and_noteworthy_v1.2.6
|
|
16
|
+
new_and_noteworthy_v1.2.5
|
|
17
|
+
new_and_noteworthy_v1.2.4
|
|
18
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Noteworthy in Version 1.2.4
|
|
2
|
+
==============================================================================
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
Diagnostics: Start Debugger on Error
|
|
6
|
+
-------------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
:Since: behave 1.2.4a1
|
|
9
|
+
|
|
10
|
+
See also :ref:`debug-on-error` .
|
|
11
|
+
|
|
@@ -0,0 +1,814 @@
|
|
|
1
|
+
Noteworthy in Version 1.2.5
|
|
2
|
+
==============================================================================
|
|
3
|
+
|
|
4
|
+
Scenario Outline Improvements
|
|
5
|
+
-------------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
.. index::
|
|
8
|
+
single: ScenarioOutline; name annotation
|
|
9
|
+
pair: ScenarioOutline; file location
|
|
10
|
+
|
|
11
|
+
Better represent Example/Row
|
|
12
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
13
|
+
|
|
14
|
+
:Since: behave 1.2.5a1
|
|
15
|
+
:Covers: Name annotation, file location
|
|
16
|
+
|
|
17
|
+
A scenario outline basically a parametrized scenario template.
|
|
18
|
+
It represents a macro/script that is executed for a data-driven set of examples
|
|
19
|
+
(parametrized data). Therefore, a scenario outline generates several scenarios,
|
|
20
|
+
each representing one example/row combination.
|
|
21
|
+
|
|
22
|
+
.. code-block:: gherkin
|
|
23
|
+
|
|
24
|
+
# -- file:features/xxx.feature
|
|
25
|
+
Feature:
|
|
26
|
+
Scenario Outline: Wow # line 2
|
|
27
|
+
Given an employee "<name>"
|
|
28
|
+
|
|
29
|
+
Examples: Araxas
|
|
30
|
+
| name | birthyear |
|
|
31
|
+
| Alice | 1985 | # line 7
|
|
32
|
+
| Bob | 1975 | # line 8
|
|
33
|
+
|
|
34
|
+
Examples:
|
|
35
|
+
| name | birthyear |
|
|
36
|
+
| Charly | 1995 | # line 12
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
Up to now, the following scenarios were generated from the scenario outline:
|
|
40
|
+
|
|
41
|
+
.. code-block:: gherkin
|
|
42
|
+
|
|
43
|
+
Scenario Outline: Wow # features/xxx.feature:2
|
|
44
|
+
Given an employee "Alice"
|
|
45
|
+
|
|
46
|
+
Scenario Outline: Wow # features/xxx.feature:2
|
|
47
|
+
Given an employee "Bob"
|
|
48
|
+
|
|
49
|
+
Scenario Outline: Wow # features/xxx.feature:2
|
|
50
|
+
Given an employee "Charly"
|
|
51
|
+
|
|
52
|
+
Note that all generated scenarios had the:
|
|
53
|
+
|
|
54
|
+
* same name (scenario_outline.name)
|
|
55
|
+
* same file location (scenario_outline.file_location)
|
|
56
|
+
|
|
57
|
+
From now on, the generated scenarios better
|
|
58
|
+
represent the example/row combination within a scenario outline:
|
|
59
|
+
|
|
60
|
+
.. code-block:: gherkin
|
|
61
|
+
|
|
62
|
+
Scenario Outline: Wow -- @1.1 Araxas # features/xxx.feature:7
|
|
63
|
+
Given an employee "Alice"
|
|
64
|
+
|
|
65
|
+
Scenario Outline: Wow -- @1.2 Araxas # features/xxx.feature:8
|
|
66
|
+
Given an employee "Bob"
|
|
67
|
+
|
|
68
|
+
Scenario Outline: Wow -- @2.1 # features/xxx.feature:12
|
|
69
|
+
Given an employee "Charly"
|
|
70
|
+
|
|
71
|
+
Note that:
|
|
72
|
+
|
|
73
|
+
* scenario name is now unique for any examples/row combination
|
|
74
|
+
* scenario name optionally contains the examples (group) name (if one exists)
|
|
75
|
+
* each scenario has a unique file location, based on the row's file location
|
|
76
|
+
|
|
77
|
+
Therefore, each generated scenario from a scenario outline can be selected
|
|
78
|
+
via its file location (and run on its own). In addition, if one fails,
|
|
79
|
+
it is now possible to rerun only the failing example/row combination(s).
|
|
80
|
+
|
|
81
|
+
The name annoations schema for the generated scenarios from above provides
|
|
82
|
+
the new default name annotation schema.
|
|
83
|
+
It can be adapted/overwritten in "behave.ini":
|
|
84
|
+
|
|
85
|
+
.. code-block:: ini
|
|
86
|
+
|
|
87
|
+
# -- file:behave.ini
|
|
88
|
+
[behave]
|
|
89
|
+
scenario_outline_annotation_schema = {name} -- @{row.id} {examples.name}
|
|
90
|
+
|
|
91
|
+
# -- REVERT TO: Old naming schema:
|
|
92
|
+
# scenario_outline_annotation_schema = {name}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
The following additional placeholders are provided within a
|
|
96
|
+
scenario outline to support this functionality.
|
|
97
|
+
They can be used anywhere within a scenario outline.
|
|
98
|
+
|
|
99
|
+
=============== ===============================================================
|
|
100
|
+
Placeholder Description
|
|
101
|
+
=============== ===============================================================
|
|
102
|
+
examples.name Refers name of the example group, may be an empty string.
|
|
103
|
+
examples.index Index of the example group (range=1..N).
|
|
104
|
+
row.index Index of the current row within an example group (range=1..R).
|
|
105
|
+
row.id Shortcut for schema: "<examples.index>.<row.index>"
|
|
106
|
+
=============== ===============================================================
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
.. index::
|
|
110
|
+
single: ScenarioOutline; name with placeholders
|
|
111
|
+
|
|
112
|
+
Name may contain Placeholders
|
|
113
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
114
|
+
|
|
115
|
+
:Since: behave 1.2.5a1
|
|
116
|
+
|
|
117
|
+
A scenario outline can now use placeholders from example/rows in its name
|
|
118
|
+
or its examples name. When the scenarios a generated,
|
|
119
|
+
these placeholders will be replaced with the values of the example/row.
|
|
120
|
+
|
|
121
|
+
Up to now this behavior did only apply to steps of a scenario outline.
|
|
122
|
+
|
|
123
|
+
EXAMPLE:
|
|
124
|
+
|
|
125
|
+
.. code-block:: gherkin
|
|
126
|
+
|
|
127
|
+
# -- file:features/xxx.feature
|
|
128
|
+
Feature:
|
|
129
|
+
Scenario Outline: Wow <name>-<birthyear> # line 2
|
|
130
|
+
Given an employee "<name>"
|
|
131
|
+
|
|
132
|
+
Examples:
|
|
133
|
+
| name | birthyear |
|
|
134
|
+
| Alice | 1985 | # line 7
|
|
135
|
+
| Bob | 1975 | # line 8
|
|
136
|
+
|
|
137
|
+
Examples: Benares-<ID>
|
|
138
|
+
| name | birthyear | ID |
|
|
139
|
+
| Charly | 1995 | 42 | # line 12
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
This leads to the following generated scenarios,
|
|
143
|
+
one for each examples/row combination:
|
|
144
|
+
|
|
145
|
+
.. code-block:: gherkin
|
|
146
|
+
|
|
147
|
+
Scenario Outline: Wow Alice-1985 -- @1.1 # features/xxx.feature:7
|
|
148
|
+
Given an employee "Alice"
|
|
149
|
+
|
|
150
|
+
Scenario Outline: Wow Bob-1975 -- @1.2 # features/xxx.feature:8
|
|
151
|
+
Given an employee "Bob"
|
|
152
|
+
|
|
153
|
+
Scenario Outline: Wow Charly-1885 -- @2.1 Benares-42 # features/xxx.feature:12
|
|
154
|
+
Given an employee "Charly"
|
|
155
|
+
|
|
156
|
+
.. index::
|
|
157
|
+
pair: ScenarioOutline; tags with placeholders
|
|
158
|
+
|
|
159
|
+
Tags may contain Placeholders
|
|
160
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
161
|
+
|
|
162
|
+
:Since: behave 1.2.5a1
|
|
163
|
+
|
|
164
|
+
Tags from a Scenario Outline are also part of the parametrized template.
|
|
165
|
+
Therefore, you may also use placeholders in the tags of a Scenario Outline.
|
|
166
|
+
|
|
167
|
+
.. note::
|
|
168
|
+
|
|
169
|
+
* Placeholder names, that are used in tags, should not contain whitespace.
|
|
170
|
+
* Placeholder values, that are used in tags, are transformed to contain
|
|
171
|
+
no whitespace characters.
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
EXAMPLE:
|
|
175
|
+
|
|
176
|
+
.. code-block:: gherkin
|
|
177
|
+
|
|
178
|
+
# -- file:features/xxx.feature
|
|
179
|
+
Feature:
|
|
180
|
+
|
|
181
|
+
@foo.group<examples.index>
|
|
182
|
+
@foo.row<row.id>
|
|
183
|
+
@foo.name.<name>
|
|
184
|
+
Scenario Outline: Wow # line 6
|
|
185
|
+
Given an employee "<name>"
|
|
186
|
+
|
|
187
|
+
Examples: Araxas
|
|
188
|
+
| name | birthyear |
|
|
189
|
+
| Alice | 1985 | # line 11
|
|
190
|
+
| Bob | 1975 | # line 12
|
|
191
|
+
|
|
192
|
+
Examples: Benares
|
|
193
|
+
| name | birthyear | ID |
|
|
194
|
+
| Charly | 1995 | 42 | # line 16
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
This leads to the following generated scenarios,
|
|
198
|
+
one for each examples/row combination:
|
|
199
|
+
|
|
200
|
+
.. code-block:: gherkin
|
|
201
|
+
|
|
202
|
+
@foo.group1 @foo.row1.1 @foo.name.Alice
|
|
203
|
+
Scenario Outline: Wow -- @1.1 Araxas # features/xxx.feature:11
|
|
204
|
+
Given an employee "Alice"
|
|
205
|
+
|
|
206
|
+
@foo.group1 @foo.row1.2 @foo.name.Bob
|
|
207
|
+
Scenario Outline: Wow -- @1.2 Araxas # features/xxx.feature:12
|
|
208
|
+
Given an employee "Bob"
|
|
209
|
+
|
|
210
|
+
@foo.group2 @foo.row2.1 @foo.name.Charly
|
|
211
|
+
Scenario Outline: Wow -- @2.1 Benares # features/xxx.feature:16
|
|
212
|
+
Given an employee "Charly"
|
|
213
|
+
|
|
214
|
+
.. index::
|
|
215
|
+
single: ScenarioOutline; select-group-by-tag
|
|
216
|
+
|
|
217
|
+
It is now possible to run only the examples group "Araxas" (examples group 1)
|
|
218
|
+
by using the select-by-tag mechanism:
|
|
219
|
+
|
|
220
|
+
.. code-block:: sh
|
|
221
|
+
|
|
222
|
+
$ behave --tags=@foo.group1 -f progress3 features/xxx.feature
|
|
223
|
+
... # features/xxx.feature
|
|
224
|
+
Wow -- @1.1 Araxas .
|
|
225
|
+
Wow -- @1.2 Araxas .
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
.. index::
|
|
229
|
+
single: ScenarioOutline; select-group-by-name
|
|
230
|
+
|
|
231
|
+
Run examples group via select-by-name
|
|
232
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
233
|
+
|
|
234
|
+
:Since: behave 1.2.5a1
|
|
235
|
+
|
|
236
|
+
The improvements on unique generated scenario names for a scenario outline
|
|
237
|
+
(with name annotation) can now be used to run all rows of one examples group.
|
|
238
|
+
|
|
239
|
+
EXAMPLE:
|
|
240
|
+
|
|
241
|
+
.. code-block:: gherkin
|
|
242
|
+
|
|
243
|
+
# -- file:features/xxx.feature
|
|
244
|
+
Feature:
|
|
245
|
+
Scenario Outline: Wow # line 2
|
|
246
|
+
Given an employee "<name>"
|
|
247
|
+
|
|
248
|
+
Examples: Araxas
|
|
249
|
+
| name | birthyear |
|
|
250
|
+
| Alice | 1985 | # line 7
|
|
251
|
+
| Bob | 1975 | # line 8
|
|
252
|
+
|
|
253
|
+
Examples: Benares
|
|
254
|
+
| name | birthyear |
|
|
255
|
+
| Charly | 1995 | # line 12
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
This leads to the following generated scenarios (when the feature is executed):
|
|
259
|
+
|
|
260
|
+
.. code-block:: gherkin
|
|
261
|
+
|
|
262
|
+
Scenario Outline: Wow -- @1.1 Araxas # features/xxx.feature:7
|
|
263
|
+
Given an employee "Alice"
|
|
264
|
+
|
|
265
|
+
Scenario Outline: Wow -- @1.2 Araxas # features/xxx.feature:8
|
|
266
|
+
Given an employee "Bob"
|
|
267
|
+
|
|
268
|
+
Scenario Outline: Wow -- @2.1 Benares # features/xxx.feature:12
|
|
269
|
+
Given an employee "Charly"
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
You can now run all rows of the "Araxas" examples (group)
|
|
273
|
+
by selecting it by name (name part or regular expression):
|
|
274
|
+
|
|
275
|
+
.. code-block:: sh
|
|
276
|
+
|
|
277
|
+
$ behave --name=Araxas -f progress3 features/xxx.feature
|
|
278
|
+
... # features/xxx.feature
|
|
279
|
+
Wow -- @1.1 Araxas .
|
|
280
|
+
Wow -- @1.2 Araxas .
|
|
281
|
+
|
|
282
|
+
$ behave --name='-- @.* Araxas' -f progress3 features/xxx.feature
|
|
283
|
+
... # features/xxx.feature
|
|
284
|
+
Wow -- @1.1 Araxas .
|
|
285
|
+
Wow -- @1.2 Araxas .
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
.. index::
|
|
289
|
+
single: Scenario; exclude from test run
|
|
290
|
+
pair: Scenario; exclude from test run
|
|
291
|
+
single: Feature; exclude from test run
|
|
292
|
+
pair: Feature; exclude from test run
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
Exclude Feature/Scenario at Runtime
|
|
296
|
+
-------------------------------------------------------------------------------
|
|
297
|
+
|
|
298
|
+
:Since: behave 1.2.5a1
|
|
299
|
+
|
|
300
|
+
A test writer can now provide a runtime decision logic to exclude
|
|
301
|
+
a feature, scenario or scenario outline from a test run
|
|
302
|
+
within the following hooks:
|
|
303
|
+
|
|
304
|
+
* ``before_feature()`` for a feature
|
|
305
|
+
* ``before_scenario()`` for a scenario
|
|
306
|
+
* step implementation (normally only: given step)
|
|
307
|
+
|
|
308
|
+
by using the ``skip()`` method before a feature or scenario is run.
|
|
309
|
+
|
|
310
|
+
.. code-block:: python
|
|
311
|
+
|
|
312
|
+
# -- FILE: features/environment.py
|
|
313
|
+
# EXAMPLE 1: Exclude scenario from run-set at runtime.
|
|
314
|
+
import sys
|
|
315
|
+
|
|
316
|
+
def should_exclude_scenario(scenario):
|
|
317
|
+
# -- RUNTIME DECISION LOGIC: Will exclude
|
|
318
|
+
# * Scenario: Alice
|
|
319
|
+
# * Scenario: Alice in Wonderland
|
|
320
|
+
# * Scenario: Bob and Alice2
|
|
321
|
+
return "Alice" in scenario.name
|
|
322
|
+
|
|
323
|
+
def before_scenario(context, scenario):
|
|
324
|
+
if should_exclude_scenario(scenario):
|
|
325
|
+
scenario.skip() #< EXCLUDE FROM RUN-SET.
|
|
326
|
+
# -- OR WITH REASON:
|
|
327
|
+
# reason = "RUNTIME-EXCLUDED"
|
|
328
|
+
# scenario.skip(reason)
|
|
329
|
+
|
|
330
|
+
.. code-block:: python
|
|
331
|
+
|
|
332
|
+
# -- FILE: features/steps/my_steps.py
|
|
333
|
+
# EXAMPLE 2: Skip remaining steps in step implementation.
|
|
334
|
+
from behave import given
|
|
335
|
+
|
|
336
|
+
@given('the assumption "{assumption}" is met')
|
|
337
|
+
def step_check_assumption(context, assumption):
|
|
338
|
+
if not is_assumption_valid(assumption):
|
|
339
|
+
# -- SKIP: Remaining steps in current scenario.
|
|
340
|
+
context.scenario.skip("OOPS: Assumption not met")
|
|
341
|
+
return
|
|
342
|
+
|
|
343
|
+
# -- NORMAL CASE:
|
|
344
|
+
...
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
.. index::
|
|
349
|
+
single: Stage
|
|
350
|
+
pair: Stage; Test Stage
|
|
351
|
+
|
|
352
|
+
Test Stages
|
|
353
|
+
-------------------------------------------------------------------------------
|
|
354
|
+
|
|
355
|
+
:Since: behave 1.2.5a1
|
|
356
|
+
:Intention: Use different Step Implementations for Each Stage
|
|
357
|
+
|
|
358
|
+
A test stage allows the user to provide different step and environment
|
|
359
|
+
implementation for each stage. Examples for test stages are:
|
|
360
|
+
|
|
361
|
+
* develop (example: development environment with simple database)
|
|
362
|
+
* product (example: use the real product and its database)
|
|
363
|
+
* systemint (system integration)
|
|
364
|
+
* ...
|
|
365
|
+
|
|
366
|
+
Each test stage may have a different test environment and needs to
|
|
367
|
+
fulfill different testing constraints.
|
|
368
|
+
|
|
369
|
+
EXAMPLE DIRECTORY LAYOUT (with ``stage=testlab`` and default stage)::
|
|
370
|
+
|
|
371
|
+
features/
|
|
372
|
+
+-- steps/ # -- Step implementations for default stage.
|
|
373
|
+
| +-- foo_steps.py
|
|
374
|
+
+-- testlab_steps/ # -- Step implementations for stage=testlab.
|
|
375
|
+
| +-- foo_steps.py
|
|
376
|
+
+-- environment.py # -- Environment for default stage.
|
|
377
|
+
+-- testlab_environment.py # -- Environment for stage=testlab.
|
|
378
|
+
+-- *.feature
|
|
379
|
+
|
|
380
|
+
To use the ``stage=testlab``, you run behave with::
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
behave --stage=testlab ...
|
|
384
|
+
|
|
385
|
+
or define the environment variable ``BEHAVE_STAGE=testlab``.
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
.. _userdata:
|
|
389
|
+
.. index::
|
|
390
|
+
single: userdata
|
|
391
|
+
pair: userdata; user-specific configuration data
|
|
392
|
+
|
|
393
|
+
Userdata
|
|
394
|
+
-------------------------------------------------------------------------------
|
|
395
|
+
|
|
396
|
+
:Since: behave 1.2.5a1
|
|
397
|
+
:Intention: User-specific Configuration Data
|
|
398
|
+
|
|
399
|
+
The userdata functionality allows a user to provide its own configuration data:
|
|
400
|
+
|
|
401
|
+
* as command-line option ``-D name=value`` or ``--define name=value``
|
|
402
|
+
* with the behave configuration file in section ``behave.userdata``
|
|
403
|
+
* load more configuration data in ``before_all()`` hook
|
|
404
|
+
|
|
405
|
+
.. code-block:: ini
|
|
406
|
+
|
|
407
|
+
# -- FILE: behave.ini
|
|
408
|
+
[behave.userdata]
|
|
409
|
+
browser = firefox
|
|
410
|
+
server = asterix
|
|
411
|
+
|
|
412
|
+
.. note::
|
|
413
|
+
|
|
414
|
+
Command-line definitions override userdata definitions in the
|
|
415
|
+
configuration file.
|
|
416
|
+
|
|
417
|
+
If the command-line contains no value part, like in ``-D NEEDS_CLEANUP``,
|
|
418
|
+
its value is ``"true"``.
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
The userdata settings can be accessed as dictionary in hooks and steps
|
|
422
|
+
by using the ``context.config.userdata`` dictionary.
|
|
423
|
+
|
|
424
|
+
.. code-block:: python
|
|
425
|
+
|
|
426
|
+
# -- FILE: features/environment.py
|
|
427
|
+
def before_all(context):
|
|
428
|
+
browser = context.config.userdata.get("browser", "chrome")
|
|
429
|
+
setup_browser(browser)
|
|
430
|
+
|
|
431
|
+
.. code-block:: python
|
|
432
|
+
|
|
433
|
+
# -- FILE: features/steps/userdata_example_steps.py
|
|
434
|
+
@given('I setup the system with the user-specified server"')
|
|
435
|
+
def step_setup_system_with_userdata_server(context):
|
|
436
|
+
server_host = context.config.userdata.get("server", "beatrix")
|
|
437
|
+
context.xxx_client = xxx_protocol.connect(server_host)
|
|
438
|
+
|
|
439
|
+
.. code-block:: sh
|
|
440
|
+
|
|
441
|
+
# -- ADAPT TEST-RUN: With user-specific data settings.
|
|
442
|
+
# SHELL:
|
|
443
|
+
behave -D server=obelix features/
|
|
444
|
+
behave --define server=obelix features/
|
|
445
|
+
|
|
446
|
+
Other examples for user-specific data are:
|
|
447
|
+
|
|
448
|
+
* Passing a URL to an external resource that should be used in the tests
|
|
449
|
+
|
|
450
|
+
* Turning off cleanup mechanisms implemented in environment hooks,
|
|
451
|
+
for debugging purposes.
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
Type Converters
|
|
455
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
456
|
+
|
|
457
|
+
The userdata object provides basic support for "type conversion on demand",
|
|
458
|
+
similar to the :mod:`configparser` module. The following type conversion
|
|
459
|
+
methods are provided:
|
|
460
|
+
|
|
461
|
+
* ``Userdata.getint(name, default=0)``
|
|
462
|
+
* ``Userdata.getfloat(name, default=0.0)``
|
|
463
|
+
* ``Userdata.getbool(name, default=False)``
|
|
464
|
+
* ``Userdata.getas(convert_func, name, default=None, ...)``
|
|
465
|
+
|
|
466
|
+
Type conversion may raise a ``ValueError`` exception if the conversion fails.
|
|
467
|
+
|
|
468
|
+
The following example shows how the type converter functions for integers are used:
|
|
469
|
+
|
|
470
|
+
.. code-block:: python
|
|
471
|
+
|
|
472
|
+
# -- FILE: features/environment.py
|
|
473
|
+
def before_all(context):
|
|
474
|
+
userdata = context.config.userdata
|
|
475
|
+
server_name = userdata.get("server", "beatrix")
|
|
476
|
+
int_number = userdata.getint("port", 80)
|
|
477
|
+
bool_answer = userdata.getbool("are_you_sure", True)
|
|
478
|
+
float_number = userdata.getfloat("temperature_threshold", 50.0)
|
|
479
|
+
...
|
|
480
|
+
|
|
481
|
+
.. hidden:
|
|
482
|
+
|
|
483
|
+
* :py:meth:`behave.configuration.Userdata.getint()`
|
|
484
|
+
* :py:meth:`behave.configuration.Userdata.getfloat()`
|
|
485
|
+
* :py:meth:`behave.configuration.Userdata.getbool()`
|
|
486
|
+
* :py:meth:`behave.configuration.Userdata.getas()`
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
Advanced Cases
|
|
490
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
491
|
+
|
|
492
|
+
The last section described the basic use cases of userdata.
|
|
493
|
+
For more complicated cases, it is better to provide your own configuration setup
|
|
494
|
+
in the ``before_all()`` hook.
|
|
495
|
+
|
|
496
|
+
This section describes how to load a JSON configuration file and store its
|
|
497
|
+
data in the ``userdata`` dictionary.
|
|
498
|
+
|
|
499
|
+
.. code-block:: py
|
|
500
|
+
|
|
501
|
+
# -- FILE: features/environment.py
|
|
502
|
+
import json
|
|
503
|
+
import os.path
|
|
504
|
+
|
|
505
|
+
def before_all(context):
|
|
506
|
+
"""Load and update userdata from JSON configuration file."""
|
|
507
|
+
userdata = context.config.userdata
|
|
508
|
+
configfile = userdata.get("configfile", "userconfig.json")
|
|
509
|
+
if os.path.exists(configfile):
|
|
510
|
+
assert configfile.endswith(".json")
|
|
511
|
+
more_userdata = json.load(open(configfile))
|
|
512
|
+
context.config.update_userdata(more_userdata)
|
|
513
|
+
# -- NOTE: Reapplies userdata_defines from command-line, too.
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
Provide the file "userconfig.json" with:
|
|
517
|
+
|
|
518
|
+
.. code-block:: json
|
|
519
|
+
|
|
520
|
+
{
|
|
521
|
+
"browser": "firefox",
|
|
522
|
+
"server": "asterix",
|
|
523
|
+
"count": 42,
|
|
524
|
+
"cleanup": true
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
Other advanced use cases:
|
|
528
|
+
|
|
529
|
+
* support configuration profiles via cmdline "... -D PROFILE=xxx ..."
|
|
530
|
+
(uses profile-specific configuration file or profile-specific config section)
|
|
531
|
+
* provide test stage specific configuration data
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
.. index::
|
|
535
|
+
single: Active Tags
|
|
536
|
+
|
|
537
|
+
Active Tags
|
|
538
|
+
-------------------------------------------------------------------------------
|
|
539
|
+
|
|
540
|
+
:Since: behave 1.2.5a1
|
|
541
|
+
|
|
542
|
+
**Active tags** are used when it is necessary to decide at runtime
|
|
543
|
+
which features or scenarios should run (and which should be skipped).
|
|
544
|
+
The runtime decision is based on which:
|
|
545
|
+
|
|
546
|
+
* platform the tests run (like: Windows, Linux, MACOSX, ...)
|
|
547
|
+
* runtime environment resources are available (by querying the "testbed")
|
|
548
|
+
* runtime environment resources should be used (via `userdata`_ or ...)
|
|
549
|
+
|
|
550
|
+
Therefore, for *active tags* it is decided at runtime if a tag is enabled or
|
|
551
|
+
disabled. The runtime decision logic excludes features/scenarios with disabled
|
|
552
|
+
active tags before they are run.
|
|
553
|
+
|
|
554
|
+
.. note::
|
|
555
|
+
|
|
556
|
+
The active tag mechanism is applied after the normal tag filtering
|
|
557
|
+
that is configured on the command-line.
|
|
558
|
+
|
|
559
|
+
The active tag mechanism uses the :class:`~behave.tag_matcher.ActiveTagMatcher`
|
|
560
|
+
for its core functionality.
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
.. index::
|
|
564
|
+
single: Active Tag Logic
|
|
565
|
+
|
|
566
|
+
Active Tag Logic
|
|
567
|
+
~~~~~~~~~~~~~~~~~
|
|
568
|
+
|
|
569
|
+
* A (positive) active tag is enabled,
|
|
570
|
+
if its value matches the current value of its category.
|
|
571
|
+
|
|
572
|
+
* A negated active tag (starting with "not") is enabled,
|
|
573
|
+
if its value does not match the current value of its category.
|
|
574
|
+
|
|
575
|
+
* A sequence of active tags is enabled,
|
|
576
|
+
if all its active tags are enabled (logical-and operation).
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
.. index::
|
|
580
|
+
single: Active Tag Schema
|
|
581
|
+
pair: @active.with_{category}={value}; active tag schema (dialect 1)
|
|
582
|
+
pair: @not_active.with_{category}={value}; active tag schema (dialect 1)
|
|
583
|
+
pair: @use.with_{category}={value}; active tag schema (dialect 2)
|
|
584
|
+
pair: @not.with_{category}={value}; active tag schema (dialect 2)
|
|
585
|
+
pair: @only.with_{category}={value}; active tag schema (dialect 2)
|
|
586
|
+
|
|
587
|
+
Active Tag Schema
|
|
588
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
589
|
+
|
|
590
|
+
The following two tag schemas are supported for active tags (by default).
|
|
591
|
+
|
|
592
|
+
**Dialect 1:**
|
|
593
|
+
|
|
594
|
+
* @active.with_{category}={value}
|
|
595
|
+
* @not_active.with_{category}={value}
|
|
596
|
+
|
|
597
|
+
**Dialect 2:**
|
|
598
|
+
|
|
599
|
+
* @use.with_{category}={value}
|
|
600
|
+
* @not.with_{category}={value}
|
|
601
|
+
* @only.with_{category}={value}
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
Example 1
|
|
607
|
+
~~~~~~~~~~
|
|
608
|
+
|
|
609
|
+
Assuming you have the feature file where:
|
|
610
|
+
|
|
611
|
+
* scenario "Alice" should only run when browser "Chrome" is used
|
|
612
|
+
* scenario "Bob" should only run when browser "Safari" is used
|
|
613
|
+
|
|
614
|
+
.. code-block:: gherkin
|
|
615
|
+
|
|
616
|
+
# -- FILE: features/alice.feature
|
|
617
|
+
Feature:
|
|
618
|
+
|
|
619
|
+
@use.with_browser=chrome
|
|
620
|
+
Scenario: Alice (Run only with Browser Chrome)
|
|
621
|
+
Given I do something
|
|
622
|
+
...
|
|
623
|
+
|
|
624
|
+
@use.with_browser=safari
|
|
625
|
+
Scenario: Bob (Run only with Browser Safari)
|
|
626
|
+
Given I do something else
|
|
627
|
+
...
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
.. code-block:: python
|
|
631
|
+
|
|
632
|
+
# -- FILE: features/environment.py
|
|
633
|
+
# EXAMPLE: ACTIVE TAGS, exclude scenario from run-set at runtime.
|
|
634
|
+
# NOTE: ActiveTagMatcher implements the runtime decision logic.
|
|
635
|
+
from behave.tag_matcher import ActiveTagMatcher
|
|
636
|
+
import os
|
|
637
|
+
import sys
|
|
638
|
+
|
|
639
|
+
active_tag_value_provider = {
|
|
640
|
+
"browser": "chrome"
|
|
641
|
+
}
|
|
642
|
+
active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
|
|
643
|
+
|
|
644
|
+
def before_all(context):
|
|
645
|
+
# -- SETUP ACTIVE-TAG MATCHER VALUE(s):
|
|
646
|
+
active_tag_value_provider["browser"] = os.environ.get("BROWSER", "chrome")
|
|
647
|
+
|
|
648
|
+
def before_scenario(context, scenario):
|
|
649
|
+
# -- NOTE: scenario.effective_tags := scenario.tags + feature.tags
|
|
650
|
+
if active_tag_matcher.should_exclude_with(scenario.effective_tags):
|
|
651
|
+
# -- NOTE: Exclude any with @use.with_browser=<other_browser>
|
|
652
|
+
scenario.skip(reason="DISABLED ACTIVE-TAG")
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
.. note::
|
|
656
|
+
|
|
657
|
+
By using this mechanism, the ``@use.with_browser=*`` tags become
|
|
658
|
+
**active tags**. The runtime decision logic decides when these tags
|
|
659
|
+
are enabled or disabled (and uses them to exclude their scenario/feature).
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
Example 2
|
|
665
|
+
~~~~~~~~~~
|
|
666
|
+
|
|
667
|
+
Assuming you have scenarios with the following runtime conditions:
|
|
668
|
+
|
|
669
|
+
* Run scenario Alice only on Windows OS
|
|
670
|
+
* Run scenario Bob only with browser Chrome
|
|
671
|
+
|
|
672
|
+
.. code-block:: gherkin
|
|
673
|
+
|
|
674
|
+
# -- FILE: features/alice.feature
|
|
675
|
+
# TAG SCHEMA: @use.with_{category}={value}, ...
|
|
676
|
+
Feature:
|
|
677
|
+
|
|
678
|
+
@use.with_os=win32
|
|
679
|
+
Scenario: Alice (Run only on Windows)
|
|
680
|
+
Given I do something
|
|
681
|
+
...
|
|
682
|
+
|
|
683
|
+
@use.with_browser=chrome
|
|
684
|
+
Scenario: Bob (Run only with Web-Browser Chrome)
|
|
685
|
+
Given I do something else
|
|
686
|
+
...
|
|
687
|
+
|
|
688
|
+
|
|
689
|
+
.. code-block:: python
|
|
690
|
+
|
|
691
|
+
# -- FILE: features/environment.py
|
|
692
|
+
from behave.tag_matcher import ActiveTagMatcher
|
|
693
|
+
import sys
|
|
694
|
+
|
|
695
|
+
# -- MATCHES ANY TAGS: @use.with_{category}={value}
|
|
696
|
+
# NOTE: active_tag_value_provider provides category values for active tags.
|
|
697
|
+
active_tag_value_provider = {
|
|
698
|
+
"browser": os.environ.get("BEHAVE_BROWSER", "chrome"),
|
|
699
|
+
"os": sys.platform,
|
|
700
|
+
}
|
|
701
|
+
active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
|
|
702
|
+
|
|
703
|
+
# -- BETTER USE: from behave.tag_matcher import setup_active_tag_values
|
|
704
|
+
def setup_active_tag_values(active_tag_values, data):
|
|
705
|
+
for category in active_tag_values.keys():
|
|
706
|
+
if category in data:
|
|
707
|
+
active_tag_values[category] = data[category]
|
|
708
|
+
|
|
709
|
+
def before_all(context):
|
|
710
|
+
# -- SETUP ACTIVE-TAG MATCHER (with userdata):
|
|
711
|
+
# USE: behave -D browser=safari ...
|
|
712
|
+
setup_active_tag_values(active_tag_value_provider, context.config.userdata)
|
|
713
|
+
|
|
714
|
+
def before_feature(context, feature):
|
|
715
|
+
if active_tag_matcher.should_exclude_with(feature.tags):
|
|
716
|
+
feature.skip(reason="DISABLED ACTIVE-TAG")
|
|
717
|
+
|
|
718
|
+
def before_scenario(context, scenario):
|
|
719
|
+
if active_tag_matcher.should_exclude_with(scenario.effective_tags):
|
|
720
|
+
scenario.skip("DISABLED ACTIVE-TAG")
|
|
721
|
+
|
|
722
|
+
|
|
723
|
+
By using the `userdata`_ mechanism, you can now define on command-line
|
|
724
|
+
which browser should be used when you run behave.
|
|
725
|
+
|
|
726
|
+
.. code-block:: sh
|
|
727
|
+
|
|
728
|
+
# -- SHELL: Run behave with browser=safari, ... by using userdata.
|
|
729
|
+
# TEST VARIANT 1: Run tests with browser=safari
|
|
730
|
+
behave -D browser=safari features/
|
|
731
|
+
|
|
732
|
+
# TEST VARIANT 2: Run tests with browser=chrome
|
|
733
|
+
behave -D browser=chrome features/
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
.. note::
|
|
737
|
+
|
|
738
|
+
Unknown categories, missing in the ``active_tag_value_provider`` are ignored.
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
User-defined Formatters
|
|
742
|
+
-------------------------------------------------------------------------------
|
|
743
|
+
|
|
744
|
+
:Since: behave 1.2.5a1
|
|
745
|
+
|
|
746
|
+
Behave formatters are a typical candidate for an extension point.
|
|
747
|
+
You often need another formatter that provides the desired output format for a
|
|
748
|
+
test-run.
|
|
749
|
+
|
|
750
|
+
Therefore, behave supports now formatters as extension point (or plugin).
|
|
751
|
+
It is now possible to use own, user-defined formatters in two ways:
|
|
752
|
+
|
|
753
|
+
* Use formatter class (as "scoped class name") as ``--format`` option value
|
|
754
|
+
* Register own formatters by name in behave's configuration file
|
|
755
|
+
|
|
756
|
+
.. note::
|
|
757
|
+
|
|
758
|
+
Scoped class name (schema):
|
|
759
|
+
|
|
760
|
+
* ``my.module:MyClass`` (preferred)
|
|
761
|
+
* ``my.module::MyClass`` (alternative; with double colon as separator)
|
|
762
|
+
|
|
763
|
+
|
|
764
|
+
User-defined Formatter on Command-line
|
|
765
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
766
|
+
|
|
767
|
+
Just use the formatter class (as "scoped class name") on the command-line
|
|
768
|
+
as value for the ``-format`` option (short option: ``-f``):
|
|
769
|
+
|
|
770
|
+
.. code-block:: sh
|
|
771
|
+
|
|
772
|
+
behave -f my.own_module:SimpleFormatter ...
|
|
773
|
+
behave -f behave.formatter.plain:PlainFormatter ...
|
|
774
|
+
|
|
775
|
+
.. code-block:: python
|
|
776
|
+
|
|
777
|
+
# -- FILE: my/own_module.py
|
|
778
|
+
# (or installed as Python module: my.own_module)
|
|
779
|
+
from behave.formatter.base import Formatter
|
|
780
|
+
|
|
781
|
+
class SimpleFormatter(Formatter):
|
|
782
|
+
description = "A very simple NULL formatter"
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
Register User-defined Formatter by Name
|
|
786
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
787
|
+
|
|
788
|
+
It is also possible to extend behave's built-in formatters
|
|
789
|
+
by registering one or more user-defined formatters by name in the
|
|
790
|
+
configuration file:
|
|
791
|
+
|
|
792
|
+
.. code-block:: ini
|
|
793
|
+
|
|
794
|
+
# -- FILE: behave.ini
|
|
795
|
+
[behave.formatters]
|
|
796
|
+
foo = behave_contrib.formatter.foo:FooFormatter
|
|
797
|
+
bar = behave_contrib.formatter.bar:BarFormatter
|
|
798
|
+
|
|
799
|
+
.. code-block:: python
|
|
800
|
+
|
|
801
|
+
# -- FILE: behave_contrib/formatter/foo.py
|
|
802
|
+
from behave.formatter.base import Formatter
|
|
803
|
+
|
|
804
|
+
class FooFormatter(Formatter):
|
|
805
|
+
description = "A FOO formatter"
|
|
806
|
+
...
|
|
807
|
+
|
|
808
|
+
Now you can use the name for any registered, user-defined formatter:
|
|
809
|
+
|
|
810
|
+
.. code-block:: sh
|
|
811
|
+
|
|
812
|
+
# -- NOTE: Use FooFormatter that was registered by name "foo".
|
|
813
|
+
behave -f foo ...
|
|
814
|
+
|