Removing the vertical examples support
This commit is contained in:
parent
e0a1437908
commit
6730b428ed
|
@ -4,8 +4,11 @@ Changelog
|
|||
Unreleased
|
||||
----------
|
||||
|
||||
This release introduces breaking changes in order to be more in line with the official gherkin specification.
|
||||
|
||||
- Cleanup of the documentation and tests related to parametrization (elchupanebrej)
|
||||
- Removed feature level examples for gherkin compatibility (olegpidsadnyi)
|
||||
- Removed feature level examples for the gherkin compatibility (olegpidsadnyi)
|
||||
- Removed vertical examples for the gherkin compatibility (olegpidsadnyi)
|
||||
|
||||
|
||||
|
||||
|
|
81
README.rst
81
README.rst
|
@ -522,63 +522,6 @@ Example:
|
|||
| start | eat | left |
|
||||
| 12 | 5 | 7 |
|
||||
|
||||
pytest-bdd feature file format also supports example tables in different way:
|
||||
|
||||
|
||||
.. code-block:: gherkin
|
||||
|
||||
Feature: Scenario outlines
|
||||
Scenario Outline: Outlined given, when, then
|
||||
Given there are <start> cucumbers
|
||||
When I eat <eat> cucumbers
|
||||
Then I should have <left> cucumbers
|
||||
|
||||
Examples: Vertical
|
||||
| start | 12 | 2 |
|
||||
| eat | 5 | 1 |
|
||||
| left | 7 | 1 |
|
||||
|
||||
This form allows to have tables with lots of columns keeping the maximum text width predictable without significant
|
||||
readability change.
|
||||
|
||||
The code will look like:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pytest_bdd import given, when, then, scenario, parsers
|
||||
|
||||
|
||||
@scenario(
|
||||
"outline.feature",
|
||||
"Outlined given, when, then",
|
||||
)
|
||||
def test_outlined():
|
||||
pass
|
||||
|
||||
|
||||
@given(parsers.parse("there are {start:d} cucumbers", target_fixture="start_cucumbers"))
|
||||
def start_cucumbers(start):
|
||||
assert isinstance(start, int)
|
||||
return dict(start=start)
|
||||
|
||||
|
||||
@when(parsers.parse("I eat {eat:g} cucumbers"))
|
||||
def eat_cucumbers(start_cucumbers, eat):
|
||||
assert isinstance(eat, float)
|
||||
start_cucumbers["eat"] = eat
|
||||
|
||||
|
||||
@then(parsers.parse("I should have {left} cucumbers"))
|
||||
def should_have_left_cucumbers(start_cucumbers, start, eat, left):
|
||||
assert isinstance(left, str)
|
||||
assert start - eat == int(left)
|
||||
assert start_cucumbers["start"] == start
|
||||
assert start_cucumbers["eat"] == eat
|
||||
|
||||
Example code also shows possibility to pass example converters which may be useful if you need parameter types
|
||||
different than strings.
|
||||
|
||||
|
||||
|
||||
Organizing your scenarios
|
||||
-------------------------
|
||||
|
@ -1056,6 +999,30 @@ As as side effect, the tool will validate the files for format errors, also some
|
|||
ordering of the types of the steps.
|
||||
|
||||
|
||||
.. _Migration from 5.x.x:
|
||||
|
||||
Migration of your tests from versions 5.x.x
|
||||
-------------------------------------------
|
||||
|
||||
The primary focus of the pytest-bdd is the compatibility with the latest gherkin developments
|
||||
e.g. multiple scenario outline example tables with tags support etc.
|
||||
|
||||
In order to provide the best compatibility it is best to support the features described in the official
|
||||
gherkin reference. This means deprecation of some non-standard features that were implemented in pytest-bdd.
|
||||
|
||||
|
||||
Removal of the feature examples
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
The example tables on the feature level are no longer supported. The tests should be parametrized with the example tables
|
||||
on the scenario level.
|
||||
|
||||
|
||||
Removal of the vertical examples
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Vertical example tables are no longer supported since the official gherkin doesn't support them.
|
||||
The example tables should have horizontal orientation.
|
||||
|
||||
|
||||
.. _Migration from 4.x.x:
|
||||
|
||||
Migration of your tests from versions 4.x.x
|
||||
|
|
|
@ -12,7 +12,6 @@ COMMENT_RE = re.compile(r"(^|(?<=\s))#")
|
|||
STEP_PREFIXES = [
|
||||
("Feature: ", types.FEATURE),
|
||||
("Scenario Outline: ", types.SCENARIO_OUTLINE),
|
||||
("Examples: Vertical", types.EXAMPLES_VERTICAL),
|
||||
("Examples:", types.EXAMPLES),
|
||||
("Scenario: ", types.SCENARIO),
|
||||
("Background:", types.BACKGROUND),
|
||||
|
@ -157,26 +156,11 @@ def parse_feature(basedir: str, filename: str, encoding: str = "utf-8") -> "Feat
|
|||
elif mode == types.EXAMPLES:
|
||||
mode = types.EXAMPLES_HEADERS
|
||||
scenario.examples.line_number = line_number
|
||||
elif mode == types.EXAMPLES_VERTICAL:
|
||||
mode = types.EXAMPLE_LINE_VERTICAL
|
||||
scenario.examples.line_number = line_number
|
||||
elif mode == types.EXAMPLES_HEADERS:
|
||||
scenario.examples.set_param_names([l for l in split_line(parsed_line) if l])
|
||||
mode = types.EXAMPLE_LINE
|
||||
elif mode == types.EXAMPLE_LINE:
|
||||
scenario.examples.add_example([l for l in split_line(stripped_line)])
|
||||
elif mode == types.EXAMPLE_LINE_VERTICAL:
|
||||
param_line_parts = [l for l in split_line(stripped_line)]
|
||||
try:
|
||||
scenario.examples.add_example_row(param_line_parts[0], param_line_parts[1:])
|
||||
except exceptions.ExamplesNotValidError as exc:
|
||||
raise exceptions.FeatureError(
|
||||
f"Scenario has not valid examples. {exc.args[0]}",
|
||||
line_number,
|
||||
clean_line,
|
||||
filename,
|
||||
)
|
||||
|
||||
elif mode and mode not in (types.FEATURE, types.TAG):
|
||||
step = Step(name=parsed_line, type=mode, indent=line_indent, line_number=line_number, keyword=keyword)
|
||||
if feature.background and not scenario:
|
||||
|
@ -383,7 +367,6 @@ class Examples:
|
|||
"""Initialize examples instance."""
|
||||
self.example_params = []
|
||||
self.examples = []
|
||||
self.vertical_examples = []
|
||||
self.line_number = None
|
||||
self.name = None
|
||||
|
||||
|
@ -412,17 +395,8 @@ class Examples:
|
|||
f"""Example rows should contain unique parameters. "{param}" appeared more than once"""
|
||||
)
|
||||
self.example_params.append(param)
|
||||
self.vertical_examples.append(values)
|
||||
|
||||
def as_contexts(self) -> typing.Iterable[typing.Dict[str, typing.Any]]:
|
||||
param_count = len(self.example_params)
|
||||
if self.vertical_examples and not self.examples:
|
||||
for value_index in range(len(self.vertical_examples[0])):
|
||||
example = []
|
||||
for param_index in range(param_count):
|
||||
example.append(self.vertical_examples[param_index][value_index])
|
||||
self.examples.append(example)
|
||||
|
||||
if not self.examples:
|
||||
return
|
||||
|
||||
|
@ -430,12 +404,11 @@ class Examples:
|
|||
|
||||
for row in rows:
|
||||
assert len(header) == len(row)
|
||||
|
||||
yield dict(zip(header, row))
|
||||
|
||||
def __bool__(self):
|
||||
"""Bool comparison."""
|
||||
return bool(self.vertical_examples or self.examples)
|
||||
return bool(self.examples)
|
||||
|
||||
|
||||
def get_tags(line):
|
||||
|
|
|
@ -3,10 +3,8 @@
|
|||
FEATURE = "feature"
|
||||
SCENARIO_OUTLINE = "scenario outline"
|
||||
EXAMPLES = "examples"
|
||||
EXAMPLES_VERTICAL = "examples vertical"
|
||||
EXAMPLES_HEADERS = "example headers"
|
||||
EXAMPLE_LINE = "example line"
|
||||
EXAMPLE_LINE_VERTICAL = "example line vertical"
|
||||
SCENARIO = "scenario"
|
||||
BACKGROUND = "background"
|
||||
GIVEN = "given"
|
||||
|
|
|
@ -122,46 +122,6 @@ def test_wrongly_outlined(testdir):
|
|||
result.stdout.fnmatch_lines("*should match set of example values [[]'eat', 'left', 'start', 'unknown_param'[]].*")
|
||||
|
||||
|
||||
def test_wrong_vertical_examples_scenario(testdir):
|
||||
"""Test parametrized scenario vertical example table has wrong format."""
|
||||
testdir.makefile(
|
||||
".feature",
|
||||
outline=textwrap.dedent(
|
||||
"""\
|
||||
Feature: Outline
|
||||
Scenario Outline: Outlined with wrong vertical example table
|
||||
Given there are <start> cucumbers
|
||||
When I eat <eat> cucumbers
|
||||
Then I should have <left> cucumbers
|
||||
|
||||
Examples: Vertical
|
||||
| start | 12 | 2 |
|
||||
| start | 10 | 1 |
|
||||
| left | 7 | 1 |
|
||||
"""
|
||||
),
|
||||
)
|
||||
testdir.makeconftest(textwrap.dedent(STEPS))
|
||||
|
||||
testdir.makepyfile(
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
from pytest_bdd import scenario
|
||||
|
||||
@scenario("outline.feature", "Outlined with wrong vertical example table")
|
||||
def test_outline(request):
|
||||
pass
|
||||
"""
|
||||
)
|
||||
)
|
||||
result = testdir.runpytest()
|
||||
assert_outcomes(result, errors=1)
|
||||
result.stdout.fnmatch_lines(
|
||||
"*Scenario has not valid examples. Example rows should contain unique parameters. "
|
||||
'"start" appeared more than once.*'
|
||||
)
|
||||
|
||||
|
||||
def test_outlined_with_other_fixtures(testdir):
|
||||
"""Test outlined scenario also using other parametrized fixture."""
|
||||
testdir.makefile(
|
||||
|
@ -211,54 +171,6 @@ def test_outlined_with_other_fixtures(testdir):
|
|||
result.assert_outcomes(passed=6)
|
||||
|
||||
|
||||
def test_vertical_example(testdir):
|
||||
"""Test outlined scenario with vertical examples table."""
|
||||
testdir.makefile(
|
||||
".feature",
|
||||
outline=textwrap.dedent(
|
||||
"""\
|
||||
Feature: Outline
|
||||
Scenario Outline: Outlined with vertical example table
|
||||
Given there are <start> cucumbers
|
||||
When I eat <eat> cucumbers
|
||||
Then I should have <left> cucumbers
|
||||
|
||||
Examples: Vertical
|
||||
| start | 12 | 2 |
|
||||
| eat | 5 | 1 |
|
||||
| left | 7 | 1 |
|
||||
|
||||
"""
|
||||
),
|
||||
)
|
||||
|
||||
testdir.makeconftest(textwrap.dedent(STEPS))
|
||||
|
||||
testdir.makepyfile(
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
from pytest_bdd import scenario
|
||||
|
||||
@scenario(
|
||||
"outline.feature",
|
||||
"Outlined with vertical example table",
|
||||
)
|
||||
def test_outline():
|
||||
pass
|
||||
"""
|
||||
)
|
||||
)
|
||||
result = testdir.runpytest("-s")
|
||||
result.assert_outcomes(passed=2)
|
||||
parametrizations = collect_dumped_objects(result)
|
||||
# fmt: off
|
||||
assert parametrizations == [
|
||||
12, 5.0, "7",
|
||||
2, 1.0, "1",
|
||||
]
|
||||
# fmt: on
|
||||
|
||||
|
||||
def test_outline_with_escaped_pipes(testdir):
|
||||
"""Test parametrized feature example table with escaped pipe characters in input."""
|
||||
testdir.makefile(
|
||||
|
|
|
@ -61,40 +61,3 @@ def test_scenario_with_empty_example_values(testdir):
|
|||
result = testdir.runpytest("-s")
|
||||
result.assert_outcomes(passed=1)
|
||||
assert collect_dumped_objects(result) == ["#", "", ""]
|
||||
|
||||
|
||||
def test_scenario_with_empty_example_values_vertical(testdir):
|
||||
testdir.makefile(
|
||||
".feature",
|
||||
outline=textwrap.dedent(
|
||||
"""\
|
||||
Feature: Outline
|
||||
Scenario Outline: Outlined with empty example values vertical
|
||||
Given there are <start> cucumbers
|
||||
When I eat <eat> cucumbers
|
||||
Then I should have <left> cucumbers
|
||||
|
||||
Examples: Vertical
|
||||
| start | # |
|
||||
| eat | |
|
||||
| left | |
|
||||
"""
|
||||
),
|
||||
)
|
||||
testdir.makeconftest(textwrap.dedent(STEPS))
|
||||
|
||||
testdir.makepyfile(
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
from pytest_bdd.utils import dump_obj
|
||||
from pytest_bdd import scenario
|
||||
|
||||
@scenario("outline.feature", "Outlined with empty example values vertical")
|
||||
def test_outline():
|
||||
pass
|
||||
"""
|
||||
)
|
||||
)
|
||||
result = testdir.runpytest("-s")
|
||||
result.assert_outcomes(passed=1)
|
||||
assert collect_dumped_objects(result) == ["#", "", ""]
|
||||
|
|
Loading…
Reference in New Issue