diff --git a/CHANGES.rst b/CHANGES.rst index 1c90f501..570eec28 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,7 @@ Unreleased ----------- This release introduces breaking changes, please refer to the :ref:`Migration from 4.x.x`. +- Unused examples are now ignored. Previously an error was raised. - Rewrite the logic to parse Examples for Scenario Outlines. Now the substitution of the examples is done during the parsing of Gherkin feature files. You won't need to define the steps twice like ``@given("there are cucumbers")`` and ``@given(parsers.parse("there are {start} cucumbers"))``. The latter will be enough. - Removed ``example_converters`` from ``scenario(...)`` signature. You should now use just the ``converters`` parameter for ``given``, ``when``, ``then``. - Removed ``--cucumberjson-expanded`` and ``--cucumber-json-expanded`` options. Now the JSON report is always expanded. diff --git a/pytest_bdd/parser.py b/pytest_bdd/parser.py index 8cbfbb14..b8bfe044 100644 --- a/pytest_bdd/parser.py +++ b/pytest_bdd/parser.py @@ -265,10 +265,10 @@ def validate(self): """ params = frozenset(sum((list(step.params) for step in self.steps), [])) example_params = set(self.examples.example_params + self.feature.examples.example_params) - if params and example_params and params != example_params: + if params and example_params and not params.issubset(example_params): raise exceptions.ScenarioExamplesNotValidError( - """Scenario "{}" in the feature "{}" has not valid examples. """ - """Set of step parameters {} should match set of example values {}.""".format( + """Scenario "{}" in the feature "{}" does not have valid examples. """ + """Set of step parameters {} should be a subset of example values {}.""".format( self.name, self.feature.filename, sorted(params), sorted(example_params) ) ) diff --git a/tests/feature/test_outline.py b/tests/feature/test_outline.py index 3628db8d..e411bc3f 100644 --- a/tests/feature/test_outline.py +++ b/tests/feature/test_outline.py @@ -81,8 +81,44 @@ def test_outline(request): # fmt: on -def test_wrongly_outlined(testdir): - """Test parametrized scenario when the test function lacks parameters.""" +def test_extra_examples_are_ignored(testdir): + """Test that the Examples section can have more examples than the ones used by the scenario.""" + + testdir.makefile( + ".feature", + outline=textwrap.dedent( + """\ + Feature: Outline + Scenario Outline: Outlined with extra examples + Given there are cucumbers + When I eat cucumbers + Then I should have cucumbers + + Examples: + | start | eat | left | notes | + | 12 | 5 | 7 | Should be ignored | + + """ + ), + ) + testdir.makeconftest(textwrap.dedent(STEPS)) + + testdir.makepyfile( + textwrap.dedent( + """\ + from pytest_bdd import scenarios + + scenarios("outline.feature") + """ + ) + ) + result = testdir.runpytest() + assert_outcomes(result, passed=1) + + +def test_not_enough_examples(testdir): + """Test parametrized scenario when the test function has a parameter set which is not a subset of those in the + examples table.""" testdir.makefile( ".feature", @@ -95,8 +131,8 @@ def test_wrongly_outlined(testdir): Then I should have cucumbers Examples: - | start | eat | left | unknown_param | - | 12 | 5 | 7 | value | + | start | eat | + | 12 | 5 | """ ), @@ -106,20 +142,21 @@ def test_wrongly_outlined(testdir): testdir.makepyfile( textwrap.dedent( """\ - from pytest_bdd import scenario + from pytest_bdd import scenarios - @scenario("outline.feature", "Outlined with wrong examples") - def test_outline(request): - pass + scenarios("outline.feature") """ ) ) result = testdir.runpytest() assert_outcomes(result, errors=1) result.stdout.fnmatch_lines( - '*ScenarioExamplesNotValidError: Scenario "Outlined with wrong examples"*has not valid examples*', + '*ScenarioExamplesNotValidError: Scenario "Outlined with wrong examples"*does not have valid examples*', + ) + expected_msg = ( + "Set of step parameters ['eat', 'left', 'start'] " "should be a subset of example values ['eat', 'start']" ) - result.stdout.fnmatch_lines("*should match set of example values [[]'eat', 'left', 'start', 'unknown_param'[]].*") + assert expected_msg in result.stdout.str() def test_wrong_vertical_examples_scenario(testdir):