Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Examples table to include values not used in steps #391

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions CHANGES.rst
Expand Up @@ -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 <start> 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.
Expand Down
6 changes: 3 additions & 3 deletions pytest_bdd/parser.py
Expand Up @@ -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)
)
)
Expand Down
57 changes: 47 additions & 10 deletions tests/feature/test_outline.py
Expand Up @@ -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 <start> cucumbers
When I eat <eat> cucumbers
Then I should have <left> 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",
Expand All @@ -95,8 +131,8 @@ def test_wrongly_outlined(testdir):
Then I should have <left> cucumbers

Examples:
| start | eat | left | unknown_param |
| 12 | 5 | 7 | value |
| start | eat |
| 12 | 5 |

"""
),
Expand All @@ -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):
Expand Down