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,66 @@
|
|
|
1
|
+
.. _id.appendix.context_attributes:
|
|
2
|
+
|
|
3
|
+
==============================================================================
|
|
4
|
+
Context Attributes
|
|
5
|
+
==============================================================================
|
|
6
|
+
|
|
7
|
+
A context object (:class:`~behave.runner.Context`) is handed to
|
|
8
|
+
|
|
9
|
+
* step definitions (step implementations)
|
|
10
|
+
* behave hooks (:func:`before_all`, :func:`before_feature`, ..., :func:`after_all`)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
Behave Attributes
|
|
14
|
+
-------------------------
|
|
15
|
+
|
|
16
|
+
The :pypi:`behave` runner assigns a number of attributes to the context object
|
|
17
|
+
during a test run.
|
|
18
|
+
|
|
19
|
+
=============== ========= ============================================= ==============================================================
|
|
20
|
+
Attribute Name Layer Type Description
|
|
21
|
+
=============== ========= ============================================= ==============================================================
|
|
22
|
+
config test run :class:`~behave.configuration.Configuration` Configuration that is used.
|
|
23
|
+
aborted test run bool Set to true if test run is aborted by the user.
|
|
24
|
+
failed test run bool Set to true if a step fails.
|
|
25
|
+
feature feature :class:`~behave.model.Feature` Current feature.
|
|
26
|
+
tags feature, list<:class:`~behave.model.Tag`> Effective tags of current feature, scenario, scenario outline.
|
|
27
|
+
scenario
|
|
28
|
+
active_outline scenario :class:`~behave.model.Row` Current row in a scenario outline (in examples table).
|
|
29
|
+
outline
|
|
30
|
+
scenario scenario :class:`~behave.model.Scenario` Current scenario.
|
|
31
|
+
log_capture scenario :class:`~behave.log_capture.LoggingCapture` If logging capture is enabled.
|
|
32
|
+
stdout_capture scenario :class:`~StringIO.StringIO` If stdout capture is enabled.
|
|
33
|
+
stderr_capture scenario :class:`~StringIO.StringIO` If stderr capture is enabled.
|
|
34
|
+
table step :class:`~behave.model.Table` Contains step's table, otherwise None.
|
|
35
|
+
text step String Contains step's multi-line text (unicode), otherwise None.
|
|
36
|
+
=============== ========= ============================================= ==============================================================
|
|
37
|
+
|
|
38
|
+
.. note::
|
|
39
|
+
|
|
40
|
+
`Behave attributes`_ in the context object should not be modified by a user.
|
|
41
|
+
See :class:`~behave.runner.Context` class description for more details.
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
User Attributes
|
|
45
|
+
-------------------------
|
|
46
|
+
|
|
47
|
+
A user can assign (or modify) own attributes to the context object.
|
|
48
|
+
But these attributes will be removed again from the context object depending
|
|
49
|
+
where these attributes are defined.
|
|
50
|
+
|
|
51
|
+
======= =========================== =======================
|
|
52
|
+
Kind Assign Location Lifecycle Layer (Scope)
|
|
53
|
+
======= =========================== =======================
|
|
54
|
+
Hook :func:`before_all` test run
|
|
55
|
+
Hook :func:`after_all` test run
|
|
56
|
+
Hook :func:`before_tags` feature or scenario
|
|
57
|
+
Hook :func:`after_tags` feature or scenario
|
|
58
|
+
Hook :func:`before_feature` feature
|
|
59
|
+
Hook :func:`after_feature` feature
|
|
60
|
+
Hook :func:`before_scenario` scenario
|
|
61
|
+
Hook :func:`after_scenario` scenario
|
|
62
|
+
Hook :func:`before_step` scenario
|
|
63
|
+
Hook :func:`after_step` scenario
|
|
64
|
+
Step Step definition scenario
|
|
65
|
+
======= =========================== =======================
|
|
66
|
+
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
=======================
|
|
2
|
+
Django Test Integration
|
|
3
|
+
=======================
|
|
4
|
+
|
|
5
|
+
There are now at least 2 projects that integrate `Django`_ and :pypi:`behave`.
|
|
6
|
+
Both use a `LiveServerTestCase`_ to spin up a runserver for the tests automatically,
|
|
7
|
+
and shut it down when done with the test run. The approach used for integrating
|
|
8
|
+
Django, though, varies slightly.
|
|
9
|
+
|
|
10
|
+
:pypi:`behave-django`
|
|
11
|
+
Provides a dedicated management command. Easy, automatic integration (thanks
|
|
12
|
+
to monkey patching). Behave tests are run with ``python manage.py behave``.
|
|
13
|
+
Allows running tests against an existing database as a special feature.
|
|
14
|
+
See `setup behave-django <https://pythonhosted.org/behave-django/installation.html>`_
|
|
15
|
+
and `usage <https://pythonhosted.org/behave-django/usage.html>`_ instructions.
|
|
16
|
+
|
|
17
|
+
:pypi:`django-behave`
|
|
18
|
+
Provides a Django-specific TestRunner for Behave, which is set with the
|
|
19
|
+
`TEST_RUNNER`_ property in your settings. Behave tests are run
|
|
20
|
+
with the usual ``python manage.py test <app_name>`` by default.
|
|
21
|
+
See `setup django-behave <https://github.com/django-behave/django-behave/blob/master/README.md#how-to-use>`_
|
|
22
|
+
instructions.
|
|
23
|
+
|
|
24
|
+
.. _Django: https://www.djangoproject.com
|
|
25
|
+
.. _LiveServerTestCase: https://docs.djangoproject.com/en/1.8/topics/testing/tools/#liveservertestcase
|
|
26
|
+
.. _TEST_RUNNER: https://docs.djangoproject.com/en/1.8/topics/testing/advanced/#using-different-testing-frameworks
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
Manual Integration
|
|
30
|
+
==================
|
|
31
|
+
|
|
32
|
+
Alternatively, you can integrate Django using the following boilerplate code
|
|
33
|
+
in your ``environment.py`` file:
|
|
34
|
+
|
|
35
|
+
.. code-block:: python
|
|
36
|
+
|
|
37
|
+
# -- FILE: features/environment.py
|
|
38
|
+
import os
|
|
39
|
+
import django
|
|
40
|
+
from django.test.runner import DiscoverRunner
|
|
41
|
+
from django.test.testcases import LiveServerTestCase
|
|
42
|
+
|
|
43
|
+
os.environ["DJANGO_SETTINGS_MODULE"] = "test_project.settings"
|
|
44
|
+
|
|
45
|
+
def before_all(context):
|
|
46
|
+
django.setup()
|
|
47
|
+
context.test_runner = DiscoverRunner()
|
|
48
|
+
context.test_runner.setup_test_environment()
|
|
49
|
+
context.old_db_config = context.test_runner.setup_databases()
|
|
50
|
+
|
|
51
|
+
def before_scenario(context, scenario):
|
|
52
|
+
context.test_case = LiveServerTestCase
|
|
53
|
+
context.test_case.setUpClass()
|
|
54
|
+
|
|
55
|
+
def after_scenario(context, scenario):
|
|
56
|
+
context.test_case.tearDownClass()
|
|
57
|
+
del context.test_case
|
|
58
|
+
|
|
59
|
+
def after_all(context):
|
|
60
|
+
context.test_runner.teardown_databases(context.old_db_config)
|
|
61
|
+
context.test_runner.teardown_test_environment()
|
|
62
|
+
|
|
63
|
+
Taken from Andrey Zarubin's blog post "`BDD. PyCharm + Python & Django`_".
|
|
64
|
+
|
|
65
|
+
.. _`BDD. PyCharm + Python & Django`:
|
|
66
|
+
https://anvileight.com/blog/2016/04/12/behavior-driven-development-pycharm-python-django/
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
Automation Libraries
|
|
70
|
+
====================
|
|
71
|
+
|
|
72
|
+
With *behave* you can test anything on the Django stack: front-end behavior,
|
|
73
|
+
REST APIs, you can even drive your unit tests using Gherkin language.
|
|
74
|
+
Any library that helps you with that you usually integrate by adding start-up
|
|
75
|
+
code in ``before_all()`` and tear-down code in ``after_all()``.
|
|
76
|
+
|
|
77
|
+
The following examples show you how to interact with your `Django`_ application
|
|
78
|
+
by using the web interface (see `A Note on Testing`_ below to learn about entry
|
|
79
|
+
points for test automation that may be better suited for your use case).
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
Selenium (Example)
|
|
83
|
+
------------------
|
|
84
|
+
|
|
85
|
+
To start a web browser for interaction with the front-end using
|
|
86
|
+
:pypi:`Selenium` your ``environment.py`` may look like this:
|
|
87
|
+
|
|
88
|
+
.. code-block:: python
|
|
89
|
+
|
|
90
|
+
# -- FILE: features/environment.py
|
|
91
|
+
# CONTAINS: Browser fixture setup and teardown
|
|
92
|
+
from selenium.webdriver import Firefox
|
|
93
|
+
|
|
94
|
+
def before_all(context):
|
|
95
|
+
context.browser = Firefox()
|
|
96
|
+
|
|
97
|
+
def after_all(context):
|
|
98
|
+
context.browser.quit()
|
|
99
|
+
context.browser = None
|
|
100
|
+
|
|
101
|
+
In your step implementations you can use the ``context.browser`` object to
|
|
102
|
+
access Selenium features. See the `Selenium docs`_ (``remote.webdriver``) for
|
|
103
|
+
details. Example using :pypi:`behave-django`:
|
|
104
|
+
|
|
105
|
+
.. code-block:: python
|
|
106
|
+
|
|
107
|
+
# -- FILE: features/steps/browser_steps.py
|
|
108
|
+
from behave import given, when, then
|
|
109
|
+
|
|
110
|
+
@when(u'I visit "{url}"')
|
|
111
|
+
def step_impl(context, url):
|
|
112
|
+
context.browser.get(context.get_url(url))
|
|
113
|
+
|
|
114
|
+
.. _Selenium docs: https://seleniumhq.github.io/selenium/docs/api/py/api.html
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
Splinter (Example)
|
|
118
|
+
------------------
|
|
119
|
+
|
|
120
|
+
To start a web browser for interaction with the front-end using
|
|
121
|
+
:pypi:`Splinter` your ``environment.py`` may look like this:
|
|
122
|
+
|
|
123
|
+
.. code-block:: python
|
|
124
|
+
|
|
125
|
+
# -- FILE: features/environment.py
|
|
126
|
+
# CONTAINS: Browser fixture setup and teardown
|
|
127
|
+
from splinter.browser import Browser
|
|
128
|
+
|
|
129
|
+
def before_all(context):
|
|
130
|
+
context.browser = Browser()
|
|
131
|
+
|
|
132
|
+
def after_all(context):
|
|
133
|
+
context.browser.quit()
|
|
134
|
+
context.browser = None
|
|
135
|
+
|
|
136
|
+
In your step implementations you can use the ``context.browser`` object to
|
|
137
|
+
access Splinter features. See the `Splinter docs`_ for details. Example
|
|
138
|
+
using *behave-django*:
|
|
139
|
+
|
|
140
|
+
.. code-block:: python
|
|
141
|
+
|
|
142
|
+
# -- FILE: features/steps/browser_steps.py
|
|
143
|
+
from behave import given, when, then
|
|
144
|
+
|
|
145
|
+
@when(u'I visit "{url}"')
|
|
146
|
+
def step_impl(context, url):
|
|
147
|
+
context.browser.visit(context.get_url(url))
|
|
148
|
+
|
|
149
|
+
.. _Splinter docs: http://splinter.readthedocs.org/en/latest/
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
Visual Testing
|
|
153
|
+
--------------
|
|
154
|
+
|
|
155
|
+
Visually checking your front-end on regression is integrated into *behave* in
|
|
156
|
+
a straight-forward manner, too. Basically, what you do is drive your
|
|
157
|
+
application using the front-end automation library of your choice (such as
|
|
158
|
+
Selenium, Splinter, etc.) to the test location, take a screenshot and compare
|
|
159
|
+
it with an earlier, approved screenshot (your "baseline").
|
|
160
|
+
|
|
161
|
+
A list of visual testing tools and services is available from Dave Haeffner's
|
|
162
|
+
`How to Do Visual Testing`_ blog post.
|
|
163
|
+
|
|
164
|
+
.. _How to Do Visual Testing:
|
|
165
|
+
http://testautomation.applitools.com/post/105435804567/how-to-do-visual-testing-with-selenium
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
A Note on Testing
|
|
169
|
+
-----------------
|
|
170
|
+
|
|
171
|
+
While you can use :pypi:`behave` to drive the "user interface" (UI) or front-end,
|
|
172
|
+
interacting with the model layer or the business logic, e.g. by using a REST API,
|
|
173
|
+
is often the better choice.
|
|
174
|
+
|
|
175
|
+
And keep in mind, BDD advises your to test **WHAT** your application should do
|
|
176
|
+
and not **HOW** it is done.
|
|
177
|
+
|
|
178
|
+
If you want to test/exercise also the "user interface", it may be a good idea
|
|
179
|
+
to reuse the feature files, that test the model layer, by just replacing the
|
|
180
|
+
test automation layer (meaning mostly the step implementations).
|
|
181
|
+
This approach ensures that your feature files are technology-agnostic,
|
|
182
|
+
meaning they are independent how you interact with "system under test" (SUT) or
|
|
183
|
+
"application under test" (AUT).
|
|
184
|
+
|
|
185
|
+
For example, if you want to use the feature files in the same directory for
|
|
186
|
+
testing the model layer and the UI layer, this can be done by using the
|
|
187
|
+
``--stage`` option, like with:
|
|
188
|
+
|
|
189
|
+
.. code-block:: bash
|
|
190
|
+
|
|
191
|
+
$ behave --stage=model features/
|
|
192
|
+
$ behave --stage=ui features/ # NOTE: Normally used on a subset of features.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
.. _id.appendix.formatters:
|
|
2
|
+
|
|
3
|
+
==============================================================================
|
|
4
|
+
Formatters and Reporters
|
|
5
|
+
==============================================================================
|
|
6
|
+
|
|
7
|
+
:pypi:`behave` provides 2 different concepts for reporting results of a test run:
|
|
8
|
+
|
|
9
|
+
* formatters
|
|
10
|
+
* reporters
|
|
11
|
+
|
|
12
|
+
A slightly different interface is provided for each "formatter" concept.
|
|
13
|
+
The ``Formatter`` is informed about each step that is taken.
|
|
14
|
+
The ``Reporter`` has a more coarse-grained API.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
Formatters
|
|
18
|
+
------------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
The following formatters are currently supported:
|
|
21
|
+
|
|
22
|
+
============== ======== ================================================================
|
|
23
|
+
Name Mode Description
|
|
24
|
+
============== ======== ================================================================
|
|
25
|
+
help normal Shows all registered formatters.
|
|
26
|
+
json normal JSON dump of test run
|
|
27
|
+
json.pretty normal JSON dump of test run (human readable)
|
|
28
|
+
plain normal Very basic formatter with maximum compatibility
|
|
29
|
+
pretty normal Standard colourised pretty formatter
|
|
30
|
+
progress normal Shows dotted progress for each executed scenario.
|
|
31
|
+
progress2 normal Shows dotted progress for each executed step.
|
|
32
|
+
progress3 normal Shows detailed progress for each step of a scenario.
|
|
33
|
+
rerun normal Emits scenario file locations of failing scenarios
|
|
34
|
+
sphinx.steps dry-run Generate sphinx-based documentation for step definitions.
|
|
35
|
+
steps dry-run Shows step definitions (step implementations).
|
|
36
|
+
steps.doc dry-run Shows documentation for step definitions.
|
|
37
|
+
steps.usage dry-run Shows how step definitions are used by steps (in feature files).
|
|
38
|
+
tags dry-run Shows tags (and how often they are used).
|
|
39
|
+
tags.location dry-run Shows tags and the location where they are used.
|
|
40
|
+
============== ======== ================================================================
|
|
41
|
+
|
|
42
|
+
.. note::
|
|
43
|
+
|
|
44
|
+
You can use more than one formatter during a test run.
|
|
45
|
+
But in general you have only one formatter that writes to ``stdout``.
|
|
46
|
+
|
|
47
|
+
The "Mode" column indicates if a formatter is intended to be used in
|
|
48
|
+
dry-run (``--dry-run`` command-line option) or normal mode.
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
Reporters
|
|
52
|
+
------------------------------------------------------------------------------
|
|
53
|
+
|
|
54
|
+
The following reporters are currently supported:
|
|
55
|
+
|
|
56
|
+
============== ================================================================
|
|
57
|
+
Name Description
|
|
58
|
+
============== ================================================================
|
|
59
|
+
junit Provides JUnit XML-like output.
|
|
60
|
+
summary Provides a summary of the test run.
|
|
61
|
+
============== ================================================================
|
|
@@ -0,0 +1,673 @@
|
|
|
1
|
+
=====================
|
|
2
|
+
Feature Testing Setup
|
|
3
|
+
=====================
|
|
4
|
+
|
|
5
|
+
.. if you change any headings in here make sure you haven't broken the
|
|
6
|
+
cross-references in the API documentation or module docstrings!
|
|
7
|
+
|
|
8
|
+
Feature Testing Layout
|
|
9
|
+
======================
|
|
10
|
+
|
|
11
|
+
*behave* works with three types of files:
|
|
12
|
+
|
|
13
|
+
1. `feature files`_ written by your Business Analyst / Sponsor / whoever
|
|
14
|
+
with your behaviour scenarios in it, and
|
|
15
|
+
2. a "steps" directory with `Python step implementations`_ for the
|
|
16
|
+
scenarios.
|
|
17
|
+
3. optionally some `environmental controls`_ (code to run before and after
|
|
18
|
+
steps, scenarios, features or the whole shooting match).
|
|
19
|
+
|
|
20
|
+
.. _`feature files`: #gherkin-feature-testing-language
|
|
21
|
+
.. _`Python step implementations`: tutorial.html#python-step-implementations
|
|
22
|
+
.. _`environmental controls`: tutorial.html#environmental-controls
|
|
23
|
+
|
|
24
|
+
These files are typically stored in a directory called "features". The
|
|
25
|
+
minimum requirement for a features directory is::
|
|
26
|
+
|
|
27
|
+
features/
|
|
28
|
+
features/everything.feature
|
|
29
|
+
features/steps/
|
|
30
|
+
features/steps/steps.py
|
|
31
|
+
|
|
32
|
+
A more complex directory might look like::
|
|
33
|
+
|
|
34
|
+
features/
|
|
35
|
+
features/signup.feature
|
|
36
|
+
features/login.feature
|
|
37
|
+
features/account_details.feature
|
|
38
|
+
features/environment.py
|
|
39
|
+
features/steps/
|
|
40
|
+
features/steps/website.py
|
|
41
|
+
features/steps/utils.py
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
Layout Variations
|
|
45
|
+
-----------------
|
|
46
|
+
|
|
47
|
+
*behave* has some flexibility built in. It will actually try quite hard to
|
|
48
|
+
find feature specifications. When launched you may pass on the command
|
|
49
|
+
line:
|
|
50
|
+
|
|
51
|
+
**nothing**
|
|
52
|
+
In the absence of any information *behave* will attempt to load your
|
|
53
|
+
features from a subdirectory called "features" in the directory you launched
|
|
54
|
+
*behave*.
|
|
55
|
+
|
|
56
|
+
**a features directory path**
|
|
57
|
+
This is the path to a features directory laid out as described above. It may be called
|
|
58
|
+
anything by *must* contain at least one "*name*.feature" file and a directory
|
|
59
|
+
called "steps". The "environment.py" file, if present, must be in the same
|
|
60
|
+
directory that contains the "steps" directory (not *in* the "steps"
|
|
61
|
+
directory).
|
|
62
|
+
|
|
63
|
+
**the path to a "*name*.feature" file**
|
|
64
|
+
This tells *behave* where to find the feature file. To find the steps
|
|
65
|
+
directory *behave* will look in the directory containing the feature
|
|
66
|
+
file. If it is not present, *behave* will look in the parent directory,
|
|
67
|
+
and then its parent, and so on until it hits the root of the filesystem.
|
|
68
|
+
The "environment.py" file, if present, must be in the same directory
|
|
69
|
+
that contains the "steps" directory (not *in* the "steps" directory).
|
|
70
|
+
|
|
71
|
+
**a directory containing your feature files**
|
|
72
|
+
Similar to the approach above, you're identifying the directory where your
|
|
73
|
+
"*name*.feature" files are, and if the "steps" directory is not in the
|
|
74
|
+
same place then *behave* will search for it just like above. This allows
|
|
75
|
+
you to have a layout like::
|
|
76
|
+
|
|
77
|
+
tests/
|
|
78
|
+
tests/environment.py
|
|
79
|
+
tests/features/signup.feature
|
|
80
|
+
tests/features/login.feature
|
|
81
|
+
tests/features/account_details.feature
|
|
82
|
+
tests/steps/
|
|
83
|
+
tests/steps/website.py
|
|
84
|
+
tests/steps/utils.py
|
|
85
|
+
|
|
86
|
+
Note that with this approach, if you want to execute *behave* without having
|
|
87
|
+
to explicitly specify the directory (first option) you can set the ``paths``
|
|
88
|
+
setting in your `configuration file`_ (e.g. ``paths=tests``).
|
|
89
|
+
|
|
90
|
+
If you're having trouble setting things up and want to see what *behave* is
|
|
91
|
+
doing in attempting to find your features use the "-v" (verbose)
|
|
92
|
+
command-line switch.
|
|
93
|
+
|
|
94
|
+
.. _`configuration file`: behave.html#configuration-files
|
|
95
|
+
|
|
96
|
+
.. _chapter.gherkin:
|
|
97
|
+
|
|
98
|
+
Gherkin: Feature Testing Language
|
|
99
|
+
=================================
|
|
100
|
+
|
|
101
|
+
*behave* `features`_ are written using a language called `Gherkin`_ (with
|
|
102
|
+
`some modifications`_) and are named "*name*.feature".
|
|
103
|
+
|
|
104
|
+
.. _`some modifications`: #modifications-to-the-gherkin-standard
|
|
105
|
+
|
|
106
|
+
These files should be written using natural language - ideally by the
|
|
107
|
+
non-technical business participants in the software project. Feature files
|
|
108
|
+
serve two purposes – documentation and automated tests.
|
|
109
|
+
|
|
110
|
+
It is very flexible but has a few simple rules that writers need to adhere to.
|
|
111
|
+
|
|
112
|
+
Line endings terminate statements (eg, steps). Either spaces or tabs may be
|
|
113
|
+
used for indentation (but spaces are more portable). Indentation is almost
|
|
114
|
+
always ignored - it's a tool for the feature writer to express some
|
|
115
|
+
structure in the text. Most lines start with a keyword ("Feature",
|
|
116
|
+
"Scenario", "Given", ...)
|
|
117
|
+
|
|
118
|
+
Comment lines are allowed anywhere in the file. They begin with zero or
|
|
119
|
+
more spaces, followed by a sharp sign (#) and some amount of text.
|
|
120
|
+
|
|
121
|
+
.. _`gherkin`: https://github.com/cucumber/cucumber/wiki/Gherkin
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
Features
|
|
125
|
+
--------
|
|
126
|
+
|
|
127
|
+
Features are composed of scenarios. They may optionally have a description,
|
|
128
|
+
a background and a set of tags. In its simplest form a feature looks like:
|
|
129
|
+
|
|
130
|
+
.. code-block:: gherkin
|
|
131
|
+
|
|
132
|
+
Feature: feature name
|
|
133
|
+
|
|
134
|
+
Scenario: some scenario
|
|
135
|
+
Given some condition
|
|
136
|
+
Then some result is expected.
|
|
137
|
+
|
|
138
|
+
In all its glory it could look like:
|
|
139
|
+
|
|
140
|
+
.. code-block:: gherkin
|
|
141
|
+
|
|
142
|
+
@tags @tag
|
|
143
|
+
Feature: feature name
|
|
144
|
+
description
|
|
145
|
+
further description
|
|
146
|
+
|
|
147
|
+
Background: some requirement of this test
|
|
148
|
+
Given some setup condition
|
|
149
|
+
And some other setup action
|
|
150
|
+
|
|
151
|
+
Scenario: some scenario
|
|
152
|
+
Given some condition
|
|
153
|
+
When some action is taken
|
|
154
|
+
Then some result is expected.
|
|
155
|
+
|
|
156
|
+
Scenario: some other scenario
|
|
157
|
+
Given some other condition
|
|
158
|
+
When some action is taken
|
|
159
|
+
Then some other result is expected.
|
|
160
|
+
|
|
161
|
+
Scenario: ...
|
|
162
|
+
|
|
163
|
+
The feature name should just be some reasonably descriptive title for the
|
|
164
|
+
feature being tested, like "the message posting interface". The following
|
|
165
|
+
description is optional and serves to clarify any potential confusion or
|
|
166
|
+
scope issue in the feature name. The description is for the benefit of
|
|
167
|
+
humans reading the feature text.
|
|
168
|
+
|
|
169
|
+
.. any other advice we could include here?
|
|
170
|
+
|
|
171
|
+
The Background part and the Scenarios will be discussed in the following sections.
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
Background
|
|
175
|
+
----------
|
|
176
|
+
|
|
177
|
+
A background consists of a series of steps similar to `scenarios`_.
|
|
178
|
+
It allows you to add some context to the scenarios of a feature.
|
|
179
|
+
A background is executed before each scenario of this feature but after any
|
|
180
|
+
of the before hooks. It is useful for performing setup operations like:
|
|
181
|
+
|
|
182
|
+
* logging into a web browser or
|
|
183
|
+
* setting up a database
|
|
184
|
+
|
|
185
|
+
with test data used by the scenarios.
|
|
186
|
+
|
|
187
|
+
The background description is for the benefit of humans reading the feature text.
|
|
188
|
+
Again the background name should just be a reasonably descriptive title
|
|
189
|
+
for the background operation being performed or requirement being met.
|
|
190
|
+
|
|
191
|
+
A background section may exist only once within a feature file.
|
|
192
|
+
In addition, a background must be defined before any scenario or
|
|
193
|
+
scenario outline.
|
|
194
|
+
|
|
195
|
+
It contains `steps`_ as described below.
|
|
196
|
+
|
|
197
|
+
**Good practices for using Background**
|
|
198
|
+
|
|
199
|
+
Don’t use "Background" to set up complicated state unless that state is actually something the client needs to know.
|
|
200
|
+
For example, if the user and site names don’t matter to the client, you
|
|
201
|
+
should use a high-level step such as "Given that I am logged in as a site
|
|
202
|
+
owner".
|
|
203
|
+
|
|
204
|
+
Keep your "Background" section short.
|
|
205
|
+
You’re expecting the user to actually remember this stuff when reading
|
|
206
|
+
your scenarios. If the background is more than 4 lines long, can you move
|
|
207
|
+
some of the irrelevant details into high-level steps? See `calling steps
|
|
208
|
+
from other steps`_.
|
|
209
|
+
|
|
210
|
+
Make your "Background" section vivid.
|
|
211
|
+
You should use colorful names and try to tell a story, because the human
|
|
212
|
+
brain can keep track of stories much better than it can keep track of
|
|
213
|
+
names like "User A", "User B", "Site 1", and so on.
|
|
214
|
+
|
|
215
|
+
Keep your scenarios short, and don’t have too many.
|
|
216
|
+
If the background section has scrolled off the screen, you should think
|
|
217
|
+
about using higher-level steps, or splitting the features file in two.
|
|
218
|
+
|
|
219
|
+
.. _`calling steps from other steps`: api.html#calling-steps-from-other-steps
|
|
220
|
+
.. _`Cucumber Background description`: https://github.com/cucumber/cucumber/wiki/Background
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
Scenarios
|
|
224
|
+
---------
|
|
225
|
+
|
|
226
|
+
Scenarios describe the discrete behaviours being tested. They are given a
|
|
227
|
+
title which should be a reasonably descriptive title for the scenario being
|
|
228
|
+
tested. The scenario description is for the benefit of humans reading the
|
|
229
|
+
feature text.
|
|
230
|
+
|
|
231
|
+
Scenarios are composed of a series of `steps`_ as described below. The
|
|
232
|
+
steps typically take the form of "given some condition" "then we expect
|
|
233
|
+
some test will pass." In this simplest form, a scenario might be:
|
|
234
|
+
|
|
235
|
+
.. code-block:: gherkin
|
|
236
|
+
|
|
237
|
+
Scenario: we have some stock when we open the store
|
|
238
|
+
Given that the store has just opened
|
|
239
|
+
then we should have items for sale.
|
|
240
|
+
|
|
241
|
+
There may be additional conditions imposed on the scenario, and these would
|
|
242
|
+
take the form of "when" steps following the initial "given" condition. If
|
|
243
|
+
necessary, additional "and" or "but" steps may also follow the "given",
|
|
244
|
+
"when" and "then" steps if more needs to be tested. A more complex example
|
|
245
|
+
of a scenario might be:
|
|
246
|
+
|
|
247
|
+
.. code-block:: gherkin
|
|
248
|
+
|
|
249
|
+
Scenario: Replaced items should be returned to stock
|
|
250
|
+
Given that a customer buys a blue garment
|
|
251
|
+
and I have two blue garments in stock
|
|
252
|
+
but I have no red garments in stock
|
|
253
|
+
and three black garments in stock.
|
|
254
|
+
When he returns the garment for a replacement in black,
|
|
255
|
+
then I should have three blue garments in stock
|
|
256
|
+
and no red garments in stock,
|
|
257
|
+
and two black garments in stock.
|
|
258
|
+
|
|
259
|
+
It is good practise to have a scenario test only one behaviour or desired
|
|
260
|
+
outcome.
|
|
261
|
+
|
|
262
|
+
Scenarios contain `steps`_ as described below.
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
Scenario Outlines
|
|
266
|
+
-----------------
|
|
267
|
+
|
|
268
|
+
These may be used when you have a set of expected conditions and outcomes
|
|
269
|
+
to go along with your scenario `steps`_.
|
|
270
|
+
|
|
271
|
+
An outline includes keywords in the step definitions which are filled in
|
|
272
|
+
using values from example tables. You may have a number of example tables
|
|
273
|
+
in each scenario outline.
|
|
274
|
+
|
|
275
|
+
.. code-block:: gherkin
|
|
276
|
+
|
|
277
|
+
Scenario Outline: Blenders
|
|
278
|
+
Given I put <thing> in a blender,
|
|
279
|
+
when I switch the blender on
|
|
280
|
+
then it should transform into <other thing>
|
|
281
|
+
|
|
282
|
+
Examples: Amphibians
|
|
283
|
+
| thing | other thing |
|
|
284
|
+
| Red Tree Frog | mush |
|
|
285
|
+
|
|
286
|
+
Examples: Consumer Electronics
|
|
287
|
+
| thing | other thing |
|
|
288
|
+
| iPhone | toxic waste |
|
|
289
|
+
| Galaxy Nexus | toxic waste |
|
|
290
|
+
|
|
291
|
+
*behave* will run the scenario once for each (non-heading) line appearing
|
|
292
|
+
in the example data tables.
|
|
293
|
+
|
|
294
|
+
The values to replace are determined using the name appearing in the angle
|
|
295
|
+
brackets "<*name*>" which must match a headings of the example tables. The
|
|
296
|
+
name may include almost any character, though not the close angle bracket
|
|
297
|
+
">".
|
|
298
|
+
|
|
299
|
+
Substitution may also occur in `step data`_ if the "<*name*>" texts appear
|
|
300
|
+
within the step data text or table cells.
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
Steps
|
|
304
|
+
-----
|
|
305
|
+
|
|
306
|
+
Steps take a line each and begin with a *keyword* - one of "given", "when",
|
|
307
|
+
"then", "and" or "but".
|
|
308
|
+
|
|
309
|
+
In a formal sense the keywords are all Title Case, though some languages
|
|
310
|
+
allow all-lowercase keywords where that makes sense.
|
|
311
|
+
|
|
312
|
+
Steps should not need to contain significant degree of detail about the
|
|
313
|
+
mechanics of testing; that is, instead of:
|
|
314
|
+
|
|
315
|
+
.. code-block:: gherkin
|
|
316
|
+
|
|
317
|
+
Given a browser client is used to load the URL "http://website.example/website/home.html"
|
|
318
|
+
|
|
319
|
+
the step could instead simply say:
|
|
320
|
+
|
|
321
|
+
.. code-block:: gherkin
|
|
322
|
+
|
|
323
|
+
Given we are looking at the home page
|
|
324
|
+
|
|
325
|
+
Steps are implemented using Python code which is implemented in the "steps"
|
|
326
|
+
directory in Python modules (files with Python code which are named
|
|
327
|
+
"*name*.py".) The naming of the Python modules does not matter. *All* modules
|
|
328
|
+
in the "steps" directory will be imported by *behave* at startup to
|
|
329
|
+
discover the step implementations.
|
|
330
|
+
|
|
331
|
+
Given, When, Then (And, But)
|
|
332
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
333
|
+
|
|
334
|
+
*behave* doesn't technically distinguish between the various kinds of steps.
|
|
335
|
+
However, we strongly recommend that you do! These words have been carefully
|
|
336
|
+
selected for their purpose, and you should know what the purpose is to get
|
|
337
|
+
into the BDD mindset.
|
|
338
|
+
|
|
339
|
+
Given
|
|
340
|
+
"""""
|
|
341
|
+
|
|
342
|
+
The purpose of givens is to **put the system in a known state** before the
|
|
343
|
+
user (or external system) starts interacting with the system (in the When
|
|
344
|
+
steps). Avoid talking about user interaction in givens. If you had worked
|
|
345
|
+
with usecases, you would call this preconditions.
|
|
346
|
+
|
|
347
|
+
Examples:
|
|
348
|
+
|
|
349
|
+
- Create records (model instances) / set up the database state.
|
|
350
|
+
- It's ok to call directly into your application model here.
|
|
351
|
+
- Log in a user (An exception to the no-interaction recommendation. Things
|
|
352
|
+
that "happened earlier" are ok).
|
|
353
|
+
|
|
354
|
+
You might also use Given with a multiline table argument to set up database
|
|
355
|
+
records instead of fixtures hard-coded in steps. This way you can read
|
|
356
|
+
the scenario and make sense out of it without having to look elsewhere (at
|
|
357
|
+
the fixtures).
|
|
358
|
+
|
|
359
|
+
When
|
|
360
|
+
""""
|
|
361
|
+
|
|
362
|
+
Each of these steps should **describe the key action** the user (or
|
|
363
|
+
external system) performs. This is the interaction with your system which
|
|
364
|
+
should (or perhaps should not) cause some state to change.
|
|
365
|
+
|
|
366
|
+
Examples:
|
|
367
|
+
|
|
368
|
+
- Interact with a web page (`Requests`_/`Twill`_/`Selenium`_ *interaction*
|
|
369
|
+
etc should mostly go into When steps).
|
|
370
|
+
- Interact with some other user interface element.
|
|
371
|
+
- Developing a library? Kicking off some kind of action that has an
|
|
372
|
+
observable effect somewhere else.
|
|
373
|
+
|
|
374
|
+
.. _`requests`: http://docs.python-requests.org/en/latest/
|
|
375
|
+
.. _`twill`: http://twill.idyll.org/
|
|
376
|
+
.. _`selenium`: http://docs.seleniumhq.org/projects/webdriver/
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
Then
|
|
380
|
+
""""
|
|
381
|
+
|
|
382
|
+
Here we **observe outcomes**. The observations should be related to the
|
|
383
|
+
business value/benefit in your feature description. The observations should
|
|
384
|
+
also be on some kind of *output* - that is something that comes *out* of
|
|
385
|
+
the system (report, user interface, message) and not something that is
|
|
386
|
+
deeply buried inside it (that has no business value).
|
|
387
|
+
|
|
388
|
+
Examples:
|
|
389
|
+
|
|
390
|
+
- Verify that something related to the Given+When is (or is not) in the output
|
|
391
|
+
- Check that some external system has received the expected message (was an
|
|
392
|
+
email with specific content sent?)
|
|
393
|
+
|
|
394
|
+
While it might be tempting to implement Then steps to just look in the
|
|
395
|
+
database - resist the temptation. You should only verify outcome that is
|
|
396
|
+
observable for the user (or external system) and databases usually are not.
|
|
397
|
+
|
|
398
|
+
And, But
|
|
399
|
+
""""""""
|
|
400
|
+
|
|
401
|
+
If you have several givens, whens or thens you could write:
|
|
402
|
+
|
|
403
|
+
.. code-block:: gherkin
|
|
404
|
+
|
|
405
|
+
Scenario: Multiple Givens
|
|
406
|
+
Given one thing
|
|
407
|
+
Given an other thing
|
|
408
|
+
Given yet an other thing
|
|
409
|
+
When I open my eyes
|
|
410
|
+
Then I see something
|
|
411
|
+
Then I don't see something else
|
|
412
|
+
|
|
413
|
+
Or you can make it read more fluently by writing:
|
|
414
|
+
|
|
415
|
+
.. code-block:: gherkin
|
|
416
|
+
|
|
417
|
+
Scenario: Multiple Givens
|
|
418
|
+
Given one thing
|
|
419
|
+
And an other thing
|
|
420
|
+
And yet an other thing
|
|
421
|
+
When I open my eyes
|
|
422
|
+
Then I see something
|
|
423
|
+
But I don't see something else
|
|
424
|
+
|
|
425
|
+
The two scenarios are identical to *behave* - steps beginning with "and" or
|
|
426
|
+
"but" are exactly the same kind of steps as all the others. They simply
|
|
427
|
+
mimic the step that preceeds them.
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
Step Data
|
|
431
|
+
~~~~~~~~~
|
|
432
|
+
|
|
433
|
+
Steps may have some text or a table of data attached to them.
|
|
434
|
+
|
|
435
|
+
Substitution of scenario outline values will be done in step data text or
|
|
436
|
+
table data if the "<*name*>" texts appear within the step data text or
|
|
437
|
+
table cells.
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
Text
|
|
441
|
+
""""
|
|
442
|
+
|
|
443
|
+
Any text block following a step wrapped in ``"""`` lines will be associated
|
|
444
|
+
with the step. This is the one case where indentation is actually parsed:
|
|
445
|
+
the leading whitespace is stripped from the text, and successive lines of
|
|
446
|
+
the text should have at least the same amount of whitespace as the first
|
|
447
|
+
line.
|
|
448
|
+
|
|
449
|
+
So for this rather contrived example:
|
|
450
|
+
|
|
451
|
+
.. code-block:: gherkin
|
|
452
|
+
|
|
453
|
+
Scenario: some scenario
|
|
454
|
+
Given a sample text loaded into the frobulator
|
|
455
|
+
"""
|
|
456
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
|
|
457
|
+
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
|
|
458
|
+
enim ad minim veniam, quis nostrud exercitation ullamco laboris
|
|
459
|
+
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
|
|
460
|
+
reprehenderit in voluptate velit esse cillum dolore eu fugiat
|
|
461
|
+
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
|
|
462
|
+
sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
463
|
+
"""
|
|
464
|
+
When we activate the frobulator
|
|
465
|
+
Then we will find it similar to English
|
|
466
|
+
|
|
467
|
+
The text is available to the Python step code as the ".text" attribute
|
|
468
|
+
in the :class:`~behave.runner.Context` variable passed into each step
|
|
469
|
+
function. The text supplied on the first step in a scenario will be
|
|
470
|
+
available on the context variable for the duration of that scenario. Any
|
|
471
|
+
further text present on a subsequent step will overwrite previously-set
|
|
472
|
+
text.
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
Table
|
|
476
|
+
"""""
|
|
477
|
+
|
|
478
|
+
You may associate a table of data with a step by simply entering it,
|
|
479
|
+
indented, following the step. This can be useful for loading specific
|
|
480
|
+
required data into a model.
|
|
481
|
+
|
|
482
|
+
The table formatting doesn't have to be strictly lined up but it does need
|
|
483
|
+
to have the same number of columns on each line. A column is anything
|
|
484
|
+
appearing between two vertical bars "|". Any whitespace between the column
|
|
485
|
+
content and the vertical bar is removed.
|
|
486
|
+
|
|
487
|
+
.. code-block:: gherkin
|
|
488
|
+
|
|
489
|
+
Scenario: some scenario
|
|
490
|
+
Given a set of specific users
|
|
491
|
+
| name | department |
|
|
492
|
+
| Barry | Beer Cans |
|
|
493
|
+
| Pudey | Silly Walks |
|
|
494
|
+
| Two-Lumps | Silly Walks |
|
|
495
|
+
|
|
496
|
+
When we count the number of people in each department
|
|
497
|
+
Then we will find two people in "Silly Walks"
|
|
498
|
+
But we will find one person in "Beer Cans"
|
|
499
|
+
|
|
500
|
+
The table is available to the Python step code as the ".table" attribute
|
|
501
|
+
in the :class:`~behave.runner.Context` variable passed into each step
|
|
502
|
+
function. The table is an instance of :class:`~behave.model.Table` and
|
|
503
|
+
for the example above could be accessed like so:
|
|
504
|
+
|
|
505
|
+
.. code-block:: python
|
|
506
|
+
|
|
507
|
+
@given('a set of specific users')
|
|
508
|
+
def step_impl(context):
|
|
509
|
+
for row in context.table:
|
|
510
|
+
model.add_user(name=row['name'], department=row['department'])
|
|
511
|
+
|
|
512
|
+
There's a variety of ways to access the table data - see the
|
|
513
|
+
:class:`~behave.model.Table` API documentation for the full details.
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
Tags
|
|
517
|
+
----
|
|
518
|
+
|
|
519
|
+
You may also "tag" parts of your feature file. At the simplest level this
|
|
520
|
+
allows *behave* to selectively check parts of your feature set.
|
|
521
|
+
|
|
522
|
+
You may tag features, scenarios or scenario outlines but nothing else.
|
|
523
|
+
Any tag that exists in a feature will be inherited by its scenarios and
|
|
524
|
+
scenario outlines.
|
|
525
|
+
|
|
526
|
+
Tags appear on the line preceding the feature or scenario you wish to tag.
|
|
527
|
+
You may have many space-separated tags on a single line.
|
|
528
|
+
|
|
529
|
+
A tag takes the form of the at symbol "@" followed by a word (which may
|
|
530
|
+
include underscores "_"). Valid tag lines include::
|
|
531
|
+
|
|
532
|
+
@slow
|
|
533
|
+
@wip
|
|
534
|
+
@needs_database @slow
|
|
535
|
+
|
|
536
|
+
For example:
|
|
537
|
+
|
|
538
|
+
.. code-block:: gherkin
|
|
539
|
+
|
|
540
|
+
@wip @slow
|
|
541
|
+
Feature: annual reporting
|
|
542
|
+
Some description of a slow reporting system.
|
|
543
|
+
|
|
544
|
+
or:
|
|
545
|
+
|
|
546
|
+
.. code-block:: gherkin
|
|
547
|
+
|
|
548
|
+
@wip
|
|
549
|
+
@slow
|
|
550
|
+
Feature: annual reporting
|
|
551
|
+
Some description of a slow reporting system.
|
|
552
|
+
|
|
553
|
+
Tags may be used to `control your test run`_ by only including certain
|
|
554
|
+
features or scenarios based on tag selection. The tag information may also
|
|
555
|
+
be accessed from the `Python code backing up the tests`_.
|
|
556
|
+
|
|
557
|
+
.. _`control your test run`: #controlling-your-test-run-with-tags
|
|
558
|
+
.. _`Python code backing up the tests`: #accessing-tag-information-in-python
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
Controlling Your Test Run With Tags
|
|
562
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
563
|
+
|
|
564
|
+
Given a feature file with:
|
|
565
|
+
|
|
566
|
+
.. code-block:: gherkin
|
|
567
|
+
|
|
568
|
+
Feature: Fight or flight
|
|
569
|
+
In order to increase the ninja survival rate,
|
|
570
|
+
As a ninja commander
|
|
571
|
+
I want my ninjas to decide whether to take on an
|
|
572
|
+
opponent based on their skill levels
|
|
573
|
+
|
|
574
|
+
@slow
|
|
575
|
+
Scenario: Weaker opponent
|
|
576
|
+
Given the ninja has a third level black-belt
|
|
577
|
+
When attacked by a samurai
|
|
578
|
+
Then the ninja should engage the opponent
|
|
579
|
+
|
|
580
|
+
Scenario: Stronger opponent
|
|
581
|
+
Given the ninja has a third level black-belt
|
|
582
|
+
When attacked by Chuck Norris
|
|
583
|
+
Then the ninja should run for his life
|
|
584
|
+
|
|
585
|
+
then running ``behave --tags=slow`` will run just the scenarios tagged
|
|
586
|
+
``@slow``. If you wish to check everything *except* the slow ones then you
|
|
587
|
+
may run ``behave --tags=-slow``.
|
|
588
|
+
|
|
589
|
+
Another common use-case is to tag a scenario you're working on with
|
|
590
|
+
``@wip`` and then ``behave --tags=wip`` to just test that one case.
|
|
591
|
+
|
|
592
|
+
Tag selection on the command-line may be combined:
|
|
593
|
+
|
|
594
|
+
**--tags=wip,slow**
|
|
595
|
+
This will select all the cases tagged *either* "wip" or "slow".
|
|
596
|
+
|
|
597
|
+
**--tags=wip --tags=slow**
|
|
598
|
+
This will select all the cases tagged *both* "wip" and "slow".
|
|
599
|
+
|
|
600
|
+
If a feature or scenario is tagged and then skipped because of a
|
|
601
|
+
command-line control then the *before_* and *after_* environment functions
|
|
602
|
+
will not be called for that feature or scenario.
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
Accessing Tag Information In Python
|
|
606
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
607
|
+
|
|
608
|
+
The tags attached to a feature and scenario are available in
|
|
609
|
+
the environment functions via the "feature" or "scenario" object passed to
|
|
610
|
+
them. On those objects there is an attribute called "tags" which is a list
|
|
611
|
+
of the tag names attached, in the order they're found in the features file.
|
|
612
|
+
|
|
613
|
+
There are also `environmental controls`_ specific to tags, so in the above
|
|
614
|
+
example *behave* will attempt to invoke an ``environment.py`` function
|
|
615
|
+
``before_tag`` and ``after_tag`` before and after the Scenario tagged
|
|
616
|
+
``@slow``, passing in the name "slow". If multiple tags are present then
|
|
617
|
+
the functions will be called multiple times with each tag in the order
|
|
618
|
+
they're defined in the feature file.
|
|
619
|
+
|
|
620
|
+
Re-visiting the example from above; if only some of the features required a
|
|
621
|
+
browser and web server then you could tag them ``@browser``:
|
|
622
|
+
|
|
623
|
+
.. code-block:: python
|
|
624
|
+
|
|
625
|
+
def before_feature(context, feature):
|
|
626
|
+
model.init(environment='test')
|
|
627
|
+
if 'browser' in feature.tags:
|
|
628
|
+
context.server = simple_server.WSGIServer(('', 8000))
|
|
629
|
+
context.server.set_app(web_app.main(environment='test'))
|
|
630
|
+
context.thread = threading.Thread(target=context.server.serve_forever)
|
|
631
|
+
context.thread.start()
|
|
632
|
+
context.browser = webdriver.Chrome()
|
|
633
|
+
|
|
634
|
+
def after_feature(context, feature):
|
|
635
|
+
if 'browser' in feature.tags:
|
|
636
|
+
context.server.shutdown()
|
|
637
|
+
context.thread.join()
|
|
638
|
+
context.browser.quit()
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
Languages Other Than English
|
|
642
|
+
----------------------------
|
|
643
|
+
|
|
644
|
+
English is the default language used in parsing feature files. If you wish
|
|
645
|
+
to use a different language you should check to see whether it is
|
|
646
|
+
available::
|
|
647
|
+
|
|
648
|
+
behave --lang-list
|
|
649
|
+
|
|
650
|
+
This command lists all the supported languages. If yours is present then
|
|
651
|
+
you have two options:
|
|
652
|
+
|
|
653
|
+
1. add a line to the top of the feature files like (for French):
|
|
654
|
+
|
|
655
|
+
# language: fr
|
|
656
|
+
|
|
657
|
+
2. use the command-line switch ``--lang``::
|
|
658
|
+
|
|
659
|
+
behave --lang=fr
|
|
660
|
+
|
|
661
|
+
The feature file keywords will now use the French translations. To see what
|
|
662
|
+
the language equivalents recognised by *behave* are, use::
|
|
663
|
+
|
|
664
|
+
behave --lang-help fr
|
|
665
|
+
|
|
666
|
+
|
|
667
|
+
Modifications to the Gherkin Standard
|
|
668
|
+
-------------------------------------
|
|
669
|
+
|
|
670
|
+
*behave* can parse standard Gherkin files and extends Gherkin to allow
|
|
671
|
+
lowercase step keywords because these can sometimes allow more readable
|
|
672
|
+
feature specifications.
|
|
673
|
+
|