diff --git a/AUTHORS.rst b/AUTHORS.rst index db47776..aae000b 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -19,3 +19,4 @@ These people have contributed to `pytest-bdd`, in alphabetical order: * `Laurence Rowe `_ * `Leonardo Santagada `_ * `Robin Pedersen `_ +* `Sergey Kraynev `_ diff --git a/CHANGES.rst b/CHANGES.rst index fe33981..c1cf0a7 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,11 @@ Changelog ========= +2.18.2 +------ + +- Fix check for out section steps definitions for no strict gherkin feature + 2.18.1 ------ diff --git a/README.rst b/README.rst index 9f51984..2354cdc 100644 --- a/README.rst +++ b/README.rst @@ -884,6 +884,14 @@ steps, adding possibility to prepare some common setup for multiple scenarios in About background best practices, please read `here `_. +.. NOTE:: There is only step "Given" should be used in "Background" section, + steps "When" and "Then" are prohibited, because their purpose are + related to actions and consuming outcomes, that is conflict with + "Background" aim - prepare system for tests or "put the system + in a known state" as "Given" does it. + The statement above is applied for strict Gherkin mode, which is + enabled by default. + Reusing fixtures ---------------- diff --git a/pytest_bdd/feature.py b/pytest_bdd/feature.py index 6c4c50d..950fda2 100644 --- a/pytest_bdd/feature.py +++ b/pytest_bdd/feature.py @@ -293,7 +293,11 @@ class Feature(object): continue mode = get_step_type(clean_line) or mode - if not scenario and prev_mode not in (types.BACKGROUND, types.GIVEN) and mode in types.STEP_TYPES: + allowed_prev_mode = (types.BACKGROUND, types.GIVEN) + if not strict_gherkin: + allowed_prev_mode += (types.WHEN, ) + + if not scenario and prev_mode not in allowed_prev_mode and mode in types.STEP_TYPES: raise exceptions.FeatureError( "Step definition outside of a Scenario or a Background", line_number, clean_line, filename) diff --git a/tests/feature/no_sctrict_gherkin_background.feature b/tests/feature/no_sctrict_gherkin_background.feature new file mode 100644 index 0000000..e5192e5 --- /dev/null +++ b/tests/feature/no_sctrict_gherkin_background.feature @@ -0,0 +1,8 @@ +Feature: No strict Gherkin Background support + + Background: + When foo has a value "bar" + And foo is not boolean + And foo has not a value "baz" + + Scenario: Test background diff --git a/tests/feature/no_sctrict_gherkin_scenario.feature b/tests/feature/no_sctrict_gherkin_scenario.feature new file mode 100644 index 0000000..029d17b --- /dev/null +++ b/tests/feature/no_sctrict_gherkin_scenario.feature @@ -0,0 +1,6 @@ +Feature: No strict Gherkin Scenario support + + Scenario: Test scenario + When foo has a value "bar" + And foo is not boolean + And foo has not a value "baz" diff --git a/tests/feature/test_no_scenario.py b/tests/feature/test_no_scenario.py index 6b05f91..af275f6 100644 --- a/tests/feature/test_no_scenario.py +++ b/tests/feature/test_no_scenario.py @@ -24,3 +24,25 @@ def test_no_scenarios(testdir): '*FeatureError: Step definition outside of a Scenario or a Background.*', ], ) + + +def test_only_background_strict_mode(testdir): + """Test only wrong background defined in the feature file.""" + features = testdir.mkdir('features') + features.join('test.feature').write_text(textwrap.dedent(u""" + Background: + Given foo + When bar + """), 'utf-8', ensure=True) + testdir.makepyfile(py.code.Source(""" + + from pytest_bdd import scenarios + + scenarios('features') + """)) + result = testdir.runpytest() + result.stdout.fnmatch_lines( + [ + '*FeatureError: Background section can only contain Given steps.*', + ], + ) diff --git a/tests/feature/test_no_sctrict_gherkin.py b/tests/feature/test_no_sctrict_gherkin.py new file mode 100644 index 0000000..5a8a827 --- /dev/null +++ b/tests/feature/test_no_sctrict_gherkin.py @@ -0,0 +1,59 @@ +"""Test no strict gherkin for sections.""" + +import py +import pytest + +from pytest_bdd import ( + when, + scenario, +) + + +@pytest.fixture +def pytestbdd_strict_gherkin(): + return False + + +def test_background_no_strict_gherkin(request): + """Test background no strict gherkin.""" + @scenario( + "no_sctrict_gherkin_background.feature", + "Test background", + ) + def test(): + pass + + test(request) + +def test_scenario_no_strict_gherkin(request): + """Test scenario no strict gherkin.""" + @scenario( + "no_sctrict_gherkin_scenario.feature", + "Test scenario", + ) + def test(): + pass + + test(request) + + +@pytest.fixture +def foo(): + return {} + + +@when('foo has a value "bar"') +def bar(foo): + foo["bar"] = "bar" + return foo["bar"] + + +@when('foo is not boolean') +def not_boolean(foo): + assert foo is not bool + + +@when('foo has not a value "baz"') +def has_not_baz(foo): + assert "baz" not in foo +