busser-behave 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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,255 @@
|
|
1
|
+
Noteworthy in Version 1.2.6
|
2
|
+
==============================================================================
|
3
|
+
|
4
|
+
Summary:
|
5
|
+
|
6
|
+
* Tagged Examples: Examples in a ScenarioOutline can now have tags.
|
7
|
+
|
8
|
+
* Feature model elements have now language attribute based on language tag
|
9
|
+
in feature file (or the default language tag that was used by the parser).
|
10
|
+
|
11
|
+
* Gherkin parser: Supports escaped-pipe in Gherkin table cell value
|
12
|
+
|
13
|
+
* Configuration: Supports now to define default tags in configfile
|
14
|
+
|
15
|
+
* Configuration: language data is now used as default-language that should
|
16
|
+
be used by the Gherkin parser. Language tags in the Feature file override
|
17
|
+
this setting.
|
18
|
+
|
19
|
+
* Runner: Can continue after a failed step in a scenario
|
20
|
+
|
21
|
+
* Runner: Hooks processing handles now exceptions.
|
22
|
+
Hook errors (exception in hook processing) lead now to scenario failures
|
23
|
+
(even if no step fails).
|
24
|
+
|
25
|
+
* Testing support for asynchronuous frameworks or protocols (:mod:`asyncio` based)
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
Scenario Outline Improvements
|
30
|
+
-------------------------------------------------------------------------------
|
31
|
+
|
32
|
+
.. _tagged examples:
|
33
|
+
|
34
|
+
.. index::
|
35
|
+
pair: ScenarioOutline; tagged examples
|
36
|
+
pair: Gherkin parser; tagged examples
|
37
|
+
|
38
|
+
Tagged Examples
|
39
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
40
|
+
|
41
|
+
:Since: behave 1.2.6.dev0
|
42
|
+
|
43
|
+
The Gherkin parser (and the model) supports now to use tags with the
|
44
|
+
``Examples`` section in a ``Scenario Outline``. This functionality can be
|
45
|
+
used to provide multiple ``Examples`` sections, for example one section per
|
46
|
+
testing stage (development, integration testing, system testing, ...) or
|
47
|
+
one section per test team.
|
48
|
+
|
49
|
+
The following feature file provides a simple example of this functionality:
|
50
|
+
|
51
|
+
.. code-block:: gherkin
|
52
|
+
|
53
|
+
# -- FILE: features/tagged_examples.feature
|
54
|
+
Feature:
|
55
|
+
Scenario Outline: Wow
|
56
|
+
Given an employee "<name>"
|
57
|
+
|
58
|
+
@develop
|
59
|
+
Examples: Araxas
|
60
|
+
| name | birthyear |
|
61
|
+
| Alice | 1985 |
|
62
|
+
| Bob | 1975 |
|
63
|
+
|
64
|
+
@integration
|
65
|
+
Examples:
|
66
|
+
| name | birthyear |
|
67
|
+
| Charly | 1995 |
|
68
|
+
|
69
|
+
.. note::
|
70
|
+
|
71
|
+
The generated scenarios from a ScenarioOutline inherit the tags from
|
72
|
+
the ScenarioOutline and its Examples section::
|
73
|
+
|
74
|
+
# -- FOR scenario in scenario_outline.scenarios:
|
75
|
+
scenario.tags = scenario_outline.tags + examples.tags
|
76
|
+
|
77
|
+
To run only the first ``Examples`` section, you use:
|
78
|
+
|
79
|
+
.. code-block:: shell
|
80
|
+
|
81
|
+
behave --tags=@develop features/tagged_examples.feature
|
82
|
+
|
83
|
+
.. code-block:: gherkin
|
84
|
+
|
85
|
+
Scenario Outline: Wow -- @1.1 Araxas # features/tagged_examples.feature:7
|
86
|
+
Given an employee "Alice"
|
87
|
+
|
88
|
+
Scenario Outline: Wow -- @1.2 Araxas # features/tagged_examples.feature:8
|
89
|
+
Given an employee "Bob"
|
90
|
+
|
91
|
+
|
92
|
+
Tagged Examples with Active Tags and Userdata
|
93
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
94
|
+
|
95
|
+
An even more natural fit is to use ``tagged examples`` together with
|
96
|
+
``active tags`` and ``userdata``:
|
97
|
+
|
98
|
+
.. code-block:: gherkin
|
99
|
+
|
100
|
+
# -- FILE: features/tagged_examples2.feature
|
101
|
+
# VARIANT 2: With active tags and userdata.
|
102
|
+
Feature:
|
103
|
+
Scenario Outline: Wow
|
104
|
+
Given an employee "<name>"
|
105
|
+
|
106
|
+
@use.with_stage=develop
|
107
|
+
Examples: Araxas
|
108
|
+
| name | birthyear |
|
109
|
+
| Alice | 1985 |
|
110
|
+
| Bob | 1975 |
|
111
|
+
|
112
|
+
@use.with_stage=integration
|
113
|
+
Examples:
|
114
|
+
| name | birthyear |
|
115
|
+
| Charly | 1995 |
|
116
|
+
|
117
|
+
Select the ``Examples`` section now by using:
|
118
|
+
|
119
|
+
.. code-block:: shell
|
120
|
+
|
121
|
+
# -- VARIANT 1: Use userdata
|
122
|
+
behave -D stage=integration features/tagged_examples2.feature
|
123
|
+
|
124
|
+
# -- VARIANT 2: Use stage mechanism
|
125
|
+
behave --stage=integration features/tagged_examples2.feature
|
126
|
+
|
127
|
+
|
128
|
+
.. code-block:: python
|
129
|
+
|
130
|
+
# -- FILE: features/environment.py
|
131
|
+
from behave.tag_matcher import ActiveTagMatcher, setup_active_tag_values
|
132
|
+
import sys
|
133
|
+
|
134
|
+
# -- ACTIVE TAG SUPPORT: @use.with_{category}={value}, ...
|
135
|
+
active_tag_value_provider = {
|
136
|
+
"stage": "develop",
|
137
|
+
}
|
138
|
+
active_tag_matcher = ActiveTagMatcher(active_tag_value_provider)
|
139
|
+
|
140
|
+
# -- BEHAVE HOOKS:
|
141
|
+
def before_all(context):
|
142
|
+
userdata = context.config.userdata
|
143
|
+
stage = context.config.stage or userdata.get("stage", "develop")
|
144
|
+
userdata["stage"] = stage
|
145
|
+
setup_active_tag_values(active_tag_value_provider, userdata)
|
146
|
+
|
147
|
+
def before_scenario(context, scenario):
|
148
|
+
if active_tag_matcher.should_exclude_with(scenario.effective_tags):
|
149
|
+
sys.stdout.write("ACTIVE-TAG DISABLED: Scenario %s\n" % scenario.name)
|
150
|
+
scenario.skip(active_tag_matcher.exclude_reason)
|
151
|
+
|
152
|
+
|
153
|
+
Testing asyncio Frameworks
|
154
|
+
-------------------------------------------------------------------------------
|
155
|
+
|
156
|
+
:Since: behave 1.2.6.dev0
|
157
|
+
|
158
|
+
The following support was added to simplify testing asynchronuous
|
159
|
+
framework and protocols that are based on :mod:`asyncio` module
|
160
|
+
(since Python 3.4).
|
161
|
+
|
162
|
+
There are basically two use cases:
|
163
|
+
|
164
|
+
* async-steps (with event_loop.run_until_complete() semantics)
|
165
|
+
* async-dispatch step(s) with async-collect step(s) later on
|
166
|
+
|
167
|
+
|
168
|
+
Async-steps
|
169
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
170
|
+
|
171
|
+
It is now possible to use ``async-steps`` in ``behave``.
|
172
|
+
An async-step is basically a coroutine as step-implementation for behave.
|
173
|
+
The async-step is wrapped into an ``event_loop.run_until_complete()`` call
|
174
|
+
by using the ``@async_run_until_complete`` step-decorator.
|
175
|
+
|
176
|
+
This avoids another layer of indirection that would otherwise be necessary,
|
177
|
+
to use the coroutine.
|
178
|
+
|
179
|
+
A simple example for the implementation of the async-steps is shown for:
|
180
|
+
|
181
|
+
* Python 3.5 with new ``async``/``await`` keywords
|
182
|
+
* Python 3.4 with ``@asyncio.coroutine`` decorator and ``yield from`` keyword
|
183
|
+
|
184
|
+
.. literalinclude:: ../examples/async_step/features/steps/async_steps35.py
|
185
|
+
:language: python
|
186
|
+
:prepend:
|
187
|
+
# -- FILE: features/steps/async_steps35.py
|
188
|
+
|
189
|
+
|
190
|
+
.. literalinclude:: ../examples/async_step/features/steps/async_steps34.py
|
191
|
+
:language: python
|
192
|
+
:prepend:
|
193
|
+
# -- FILE: features/steps/async_steps34.py
|
194
|
+
|
195
|
+
When you use the async-step from above in a feature file and run it with behave:
|
196
|
+
|
197
|
+
.. literalinclude:: ../examples/async_step/testrun_example.async_run.txt
|
198
|
+
:language: gherkin
|
199
|
+
:prepend:
|
200
|
+
# -- TEST-RUN OUTPUT:
|
201
|
+
$ behave -f plain features/async_run.feature
|
202
|
+
|
203
|
+
.. hidden:
|
204
|
+
|
205
|
+
.. literalinclude:: ../examples/async_step/features/async_run.feature
|
206
|
+
:language: gherkin
|
207
|
+
:prepend: # -- FILE: features/async_run.feature
|
208
|
+
|
209
|
+
.. note::
|
210
|
+
|
211
|
+
The async-step is wrapped with an ``èvent_loop.run_until_complete()`` call.
|
212
|
+
As the timings show, it actually needs approximatly 0.3 seconds to run.
|
213
|
+
|
214
|
+
|
215
|
+
|
216
|
+
|
217
|
+
Async-dispatch and async-collect
|
218
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
219
|
+
|
220
|
+
The other use case with testing async frameworks is that
|
221
|
+
|
222
|
+
* you dispatch one or more async-calls
|
223
|
+
* you collect (and verify) the results of the async-calls later-on
|
224
|
+
|
225
|
+
A simple example of this approach is shown in the following feature file:
|
226
|
+
|
227
|
+
.. literalinclude:: ../examples/async_step/features/async_dispatch.feature
|
228
|
+
:language: gherkin
|
229
|
+
:prepend: # -- FILE: features/async_dispatch.feature
|
230
|
+
|
231
|
+
When you run this feature file:
|
232
|
+
|
233
|
+
.. literalinclude:: ../examples/async_step/testrun_example.async_dispatch.txt
|
234
|
+
:language: gherkin
|
235
|
+
:prepend:
|
236
|
+
# -- TEST-RUN OUTPUT:
|
237
|
+
$ behave -f plain features/async_dispatch.feature
|
238
|
+
|
239
|
+
.. note::
|
240
|
+
|
241
|
+
The final async-collect step needs approx. 0.2 seconds until the two
|
242
|
+
dispatched async-tasks have finished.
|
243
|
+
In contrast, the async-dispatch steps basically need no time at all.
|
244
|
+
|
245
|
+
An :class:`AsyncContext` object is used on the context,
|
246
|
+
to hold the event loop information and the async-tasks that are of interest.
|
247
|
+
|
248
|
+
The implementation of the steps from above:
|
249
|
+
|
250
|
+
.. literalinclude:: ../examples/async_step/features/steps/async_dispatch_steps.py
|
251
|
+
:language: gherkin
|
252
|
+
:prepend:
|
253
|
+
# -- FILE: features/steps/async_dispatch_steps.py
|
254
|
+
# REQUIRES: Python 3.4 or newer
|
255
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
.. _id.appendix.parse_builtin_types:
|
2
|
+
|
3
|
+
Predefined Data Types in ``parse``
|
4
|
+
==============================================================================
|
5
|
+
|
6
|
+
:pypi:`behave` uses the :pypi:`parse` module (inverse of Python `string.format`_)
|
7
|
+
under the hoods to parse parameters in step definitions.
|
8
|
+
This leads to rather simple and readable parse expressions for step parameters.
|
9
|
+
|
10
|
+
.. code-block:: python
|
11
|
+
|
12
|
+
# -- FILE: features/steps/type_transform_example_steps.py
|
13
|
+
from behave import given
|
14
|
+
|
15
|
+
@given('I have {number:d} friends') #< Convert 'number' into int type.
|
16
|
+
def step_given_i_have_number_friends(context, number):
|
17
|
+
assert number > 0
|
18
|
+
...
|
19
|
+
|
20
|
+
Therefore, the following ``parse types`` are already supported
|
21
|
+
in step definitions without registration of any *user-defined type*:
|
22
|
+
|
23
|
+
|
24
|
+
===== =========================================== ============
|
25
|
+
Type Characters Matched Output Type
|
26
|
+
===== =========================================== ============
|
27
|
+
w Letters and underscore str
|
28
|
+
W Non-letter and underscore str
|
29
|
+
s Whitespace str
|
30
|
+
S Non-whitespace str
|
31
|
+
d Digits (effectively integer numbers) int
|
32
|
+
D Non-digit str
|
33
|
+
n Numbers with thousands separators (, or .) int
|
34
|
+
% Percentage (converted to value/100.0) float
|
35
|
+
f Fixed-point numbers float
|
36
|
+
e Floating-point numbers with exponent float
|
37
|
+
e.g. 1.1e-10, NAN (all case insensitive)
|
38
|
+
g General number format (either d, f or e) float
|
39
|
+
b Binary numbers int
|
40
|
+
o Octal numbers int
|
41
|
+
x Hexadecimal numbers (lower and upper case) int
|
42
|
+
ti ISO 8601 format date/time datetime
|
43
|
+
e.g. 1972-01-20T10:21:36Z
|
44
|
+
te RFC2822 e-mail format date/time datetime
|
45
|
+
e.g. Mon, 20 Jan 1972 10:21:36 +1000
|
46
|
+
tg Global (day/month) format date/time datetime
|
47
|
+
e.g. 20/1/1972 10:21:36 AM +1:00
|
48
|
+
ta US (month/day) format date/time datetime
|
49
|
+
e.g. 1/20/1972 10:21:36 PM +10:30
|
50
|
+
tc ctime() format date/time datetime
|
51
|
+
e.g. Sun Sep 16 01:03:52 1973
|
52
|
+
th HTTP log format date/time datetime
|
53
|
+
e.g. 21/Nov/2011:00:07:11 +0000
|
54
|
+
tt Time time
|
55
|
+
e.g. 10:21:36 PM -5:30
|
56
|
+
===== =========================================== ============
|
57
|
+
|
58
|
+
|
59
|
+
.. _string.format: https://docs.python.org/2/library/string.html#format-string-syntax
|
@@ -0,0 +1,235 @@
|
|
1
|
+
===========================
|
2
|
+
Behavior Driven Development
|
3
|
+
===========================
|
4
|
+
|
5
|
+
Behavior-driven development (or BDD) is an agile software development
|
6
|
+
technique that encourages collaboration between developers, QA and
|
7
|
+
non-technical or business participants in a software project. It was
|
8
|
+
originally named in 2003 by `Dan North`__ as a response to test-driven
|
9
|
+
development (TDD), including acceptance test or customer test driven
|
10
|
+
development practices as found in extreme programming. It has `evolved over
|
11
|
+
the last few years`__.
|
12
|
+
|
13
|
+
__ http://dannorth.net/introducing-bdd
|
14
|
+
__ https://forums.pragprog.com/forums/95/topics/3035
|
15
|
+
|
16
|
+
On the "Agile specifications, BDD and Testing eXchange" in November 2009 in
|
17
|
+
London, Dan North `gave the following definition of BDD`__:
|
18
|
+
|
19
|
+
BDD is a second-generation, outside–in, pull-based, multiple-stakeholder,
|
20
|
+
multiple-scale, high-automation, agile methodology. It describes a cycle
|
21
|
+
of interactions with well-defined outputs, resulting in the delivery of
|
22
|
+
working, tested software that matters.
|
23
|
+
|
24
|
+
__ https://skillsmatter.com/skillscasts/923-how-to-sell-bdd-to-the-business
|
25
|
+
|
26
|
+
BDD focuses on obtaining a clear understanding of desired software behavior
|
27
|
+
through discussion with stakeholders. It extends TDD by writing test cases
|
28
|
+
in a natural language that non-programmers can read. Behavior-driven
|
29
|
+
developers use their native language in combination with the ubiquitous
|
30
|
+
language of domain-driven design to describe the purpose and benefit of
|
31
|
+
their code. This allows the developers to focus on why the code should be
|
32
|
+
created, rather than the technical details, and minimizes translation
|
33
|
+
between the technical language in which the code is written and the domain
|
34
|
+
language spoken by the business, users, stakeholders, project management,
|
35
|
+
etc.
|
36
|
+
|
37
|
+
|
38
|
+
BDD practices
|
39
|
+
-------------
|
40
|
+
|
41
|
+
The practices of BDD include:
|
42
|
+
|
43
|
+
- Establishing the goals of different stakeholders required for a vision to
|
44
|
+
be implemented
|
45
|
+
- Drawing out features which will achieve those goals using feature
|
46
|
+
injection
|
47
|
+
- Involving stakeholders in the implementation process through outside–in
|
48
|
+
software development
|
49
|
+
- Using examples to describe the behavior of the application, or of units
|
50
|
+
of code
|
51
|
+
- Automating those examples to provide quick feedback and regression
|
52
|
+
testing
|
53
|
+
- Using 'should' when describing the behavior of software to help clarify
|
54
|
+
responsibility and allow the software's functionality to be questioned
|
55
|
+
- Using 'ensure' when describing responsibilities of software to
|
56
|
+
differentiate outcomes in the scope of the code in question from
|
57
|
+
side-effects of other elements of code.
|
58
|
+
- Using mocks to stand-in for collaborating modules of code which have not
|
59
|
+
yet been written
|
60
|
+
|
61
|
+
|
62
|
+
Outside–in
|
63
|
+
----------
|
64
|
+
|
65
|
+
BDD is driven by `business value`__; that is, the benefit to the business
|
66
|
+
which accrues once the application is in production. The only way in which
|
67
|
+
this benefit can be realized is through the user interface(s) to the
|
68
|
+
application, usually (but not always) a GUI.
|
69
|
+
|
70
|
+
__ http://lizkeogh.com/2007/06/13/bdd-tdd-done-well/
|
71
|
+
|
72
|
+
In the same way, each piece of code, starting with the UI, can be
|
73
|
+
considered a stakeholder of the other modules of code which it uses. Each
|
74
|
+
element of code provides some aspect of behavior which, in collaboration
|
75
|
+
with the other elements, provides the application behavior.
|
76
|
+
|
77
|
+
The first piece of production code that BDD developers implement is the UI.
|
78
|
+
Developers can then benefit from quick feedback as to whether the UI looks
|
79
|
+
and behaves appropriately. Through code, and using principles of good
|
80
|
+
design and refactoring, developers discover collaborators of the UI, and of
|
81
|
+
every unit of code thereafter. This helps them adhere to the principle of
|
82
|
+
YAGNI, since each piece of production code is required either by the
|
83
|
+
business, or by another piece of code already written.
|
84
|
+
|
85
|
+
|
86
|
+
The Gherkin language
|
87
|
+
--------------------
|
88
|
+
|
89
|
+
The requirements of a retail application might be, "Refunded or exchanged
|
90
|
+
items should be returned to stock." In BDD, a developer or QA engineer
|
91
|
+
might clarify the requirements by breaking this down into specific
|
92
|
+
examples. The language of the examples below is called Gherkin and is used
|
93
|
+
by *behave* as well as many other tools.
|
94
|
+
|
95
|
+
.. code-block:: gherkin
|
96
|
+
|
97
|
+
Scenario: Refunded items should be returned to stock
|
98
|
+
Given a customer previously bought a black sweater from me
|
99
|
+
and I currently have three black sweaters left in stock.
|
100
|
+
When he returns the sweater for a refund
|
101
|
+
then I should have four black sweaters in stock.,
|
102
|
+
|
103
|
+
Scenario: Replaced items should be returned to stock
|
104
|
+
Given that a customer buys a blue garment
|
105
|
+
and I have two blue garments in stock
|
106
|
+
and three black garments in stock.
|
107
|
+
When he returns the garment for a replacement in black,
|
108
|
+
then I should have three blue garments in stock
|
109
|
+
and two black garments in stock.
|
110
|
+
|
111
|
+
Each scenario is an exemplar, designed to illustrate a specific aspect of behavior of the application.
|
112
|
+
|
113
|
+
When discussing the scenarios, participants question whether the outcomes
|
114
|
+
described always result from those events occurring in the given context.
|
115
|
+
This can `help to uncover further scenarios which clarify the
|
116
|
+
requirements`__. For instance, a domain expert noticing that refunded items
|
117
|
+
are not always returned to stock might reword the requirements as "Refunded
|
118
|
+
or replaced items should be returned to stock, unless faulty.".
|
119
|
+
|
120
|
+
__ http://dannorth.net/whats-in-a-story
|
121
|
+
|
122
|
+
This in turn helps participants to pin down the scope of requirements,
|
123
|
+
which leads to better estimates of how long those requirements will take to
|
124
|
+
implement.
|
125
|
+
|
126
|
+
The words Given, When and Then are often used to help drive out the
|
127
|
+
scenarios, but are not mandated.
|
128
|
+
|
129
|
+
These scenarios can also be automated, if an appropriate tool exists to
|
130
|
+
allow automation at the UI level. If no such tool exists then it may be
|
131
|
+
possible to automate at the next level in, i.e.: if an MVC design pattern
|
132
|
+
has been used, the level of the Controller.
|
133
|
+
|
134
|
+
|
135
|
+
Programmer-domain examples and behavior
|
136
|
+
---------------------------------------
|
137
|
+
|
138
|
+
The same principles of examples, using contexts, events and outcomes are
|
139
|
+
used to drive development at the level of abstraction of the programmer, as
|
140
|
+
opposed to the business level. For instance, the following examples
|
141
|
+
describe an aspect of behavior of a list:
|
142
|
+
|
143
|
+
.. code-block:: gherkin
|
144
|
+
|
145
|
+
Scenario: New lists are empty
|
146
|
+
Given a new list
|
147
|
+
then the list should be empty.
|
148
|
+
|
149
|
+
Scenario: Lists with things in them are not empty.
|
150
|
+
Given a new list
|
151
|
+
when we add an object
|
152
|
+
then the list should not be empty.
|
153
|
+
|
154
|
+
Both these examples are required to describe the boolean nature of a list
|
155
|
+
in Python and to derive the benefit of the nature. These examples are
|
156
|
+
usually automated using TDD frameworks. In BDD these examples are often
|
157
|
+
encapsulated in a single method, with the name of the method being a
|
158
|
+
complete description of the behavior. Both examples are required for the
|
159
|
+
code to be valuable, and encapsulating them in this way makes it easy to
|
160
|
+
question, remove or change the behavior.
|
161
|
+
|
162
|
+
For instance as unit tests, the above examples might become:
|
163
|
+
|
164
|
+
.. code-block:: python
|
165
|
+
|
166
|
+
class TestList(object):
|
167
|
+
def test_empty_list_is_false(self):
|
168
|
+
list = []
|
169
|
+
assertEqual(bool(list), False)
|
170
|
+
|
171
|
+
def test_populated_list_is_true(self):
|
172
|
+
list = []
|
173
|
+
list.append('item')
|
174
|
+
assertEqual(bool(list), True)
|
175
|
+
|
176
|
+
.. Other practitioners[who?], particularly in the Ruby community, prefer to split these into two separate examples, based on separate contexts for when the list is empty or has items in. This technique is based on Dave Astels' practice, "One assertion per test"[12].
|
177
|
+
.. 12. http://techblog.daveastels.com/tag/bdd/
|
178
|
+
|
179
|
+
Sometimes the difference between the context, events and outcomes is made more explicit. For instance:
|
180
|
+
|
181
|
+
.. code-block:: python
|
182
|
+
|
183
|
+
class TestWindow(object):
|
184
|
+
def test_window_close(self):
|
185
|
+
# Given
|
186
|
+
window = gui.Window("My Window")
|
187
|
+
frame = gui.Frame(window)
|
188
|
+
|
189
|
+
# When
|
190
|
+
window.close()
|
191
|
+
|
192
|
+
# Then
|
193
|
+
assert_(not frame.isVisible())
|
194
|
+
|
195
|
+
However the example is phrased, the effect describes the behavior of the
|
196
|
+
code in question. For instance, from the examples above one can derive:
|
197
|
+
|
198
|
+
- lists should know when they are empty
|
199
|
+
- window.close() should cause contents to stop being visible
|
200
|
+
|
201
|
+
The description is intended to be useful if the test fails, and to provide
|
202
|
+
documentation of the code's behavior. Once the examples have been written
|
203
|
+
they are then run and the code implemented to make them work in the same
|
204
|
+
way as TDD. The examples then become part of the suite of regression tests.
|
205
|
+
|
206
|
+
|
207
|
+
Using mocks
|
208
|
+
-----------
|
209
|
+
|
210
|
+
BDD proponents claim that the use of "should" and "ensureThat" in BDD
|
211
|
+
examples encourages developers to question whether the responsibilities
|
212
|
+
they're assigning to their classes are appropriate, or whether they can be
|
213
|
+
delegated or moved to another class entirely. Practitioners use an object
|
214
|
+
which is simpler than the collaborating code, and provides the same
|
215
|
+
interface but more predictable behavior. This is injected into the code
|
216
|
+
which needs it, and examples of that code's behavior are written using this
|
217
|
+
object instead of the production version.
|
218
|
+
|
219
|
+
These objects can either be created by hand, or created using a
|
220
|
+
mocking framework such as :pypi:`mock`.
|
221
|
+
|
222
|
+
Questioning responsibilities in this way, and using mocks to fulfill the
|
223
|
+
required roles of collaborating classes, encourages the use of Role-based
|
224
|
+
Interfaces. It also helps to keep the classes small and loosely coupled.
|
225
|
+
|
226
|
+
|
227
|
+
Acknowledgement
|
228
|
+
---------------
|
229
|
+
|
230
|
+
This text is partially taken from the wikipedia text on `Behavior Driven
|
231
|
+
Development`_ with modifications where appropriate to be more specific to
|
232
|
+
*behave* and Python.
|
233
|
+
|
234
|
+
.. _`Behavior Driven Development`: http://en.wikipedia.org/wiki/Behavior_Driven_Development
|
235
|
+
|