Skip to content

Commit

Permalink
Add support of step parts param substitution
Browse files Browse the repository at this point in the history
  • Loading branch information
Kostiantyn Goloveshko authored and Kostiantyn Goloveshko committed Aug 8, 2021
1 parent ad713f1 commit e5d22c4
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 10 deletions.
2 changes: 1 addition & 1 deletion pytest_bdd/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,4 +457,4 @@ def get_tags(line):


STEP_PARAM_TEMPLATE = "<{param}>"
STEP_PARAM_RE = re.compile(STEP_PARAM_TEMPLATE.format(param="(.+?)"))
STEP_PARAM_RE = re.compile(STEP_PARAM_TEMPLATE.format(param="([^<>]+?)"))
20 changes: 11 additions & 9 deletions pytest_bdd/scenario.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import collections
import os
import re
from functools import reduce

import pytest
from _pytest.fixtures import FixtureLookupError
Expand All @@ -28,17 +27,20 @@
ALPHA_REGEX = re.compile(r"^\d+_*")


def substitute_step_parameters(name, request):
def substitute_step_parameters(name: str, request):
"""Returns step name with substituted parameters from fixtures, example tables, param marks"""
return reduce(
lambda substituted_name, param_name: re.subn(
while True:
match = re.search(STEP_PARAM_RE, name)
if not match:
break
param_name = match.group(1)
name = re.sub(
STEP_PARAM_TEMPLATE.format(param=re.escape(param_name)),
str(request.getfixturevalue(param_name)),
substituted_name,
)[0],
re.findall(STEP_PARAM_RE, name),
name,
)
name,
count=1
)
return name


def find_argumented_step_fixture_name(name, type_, fixturemanager, request=None):
Expand Down
76 changes: 76 additions & 0 deletions tests/feature/test_outline.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,82 @@ def test_outline(request):
result.assert_outcomes(passed=2)


def test_nested_outlining(testdir):
testdir.makefile(
".feature",
outline=textwrap.dedent(
"""\
Feature: Outline
Scenario Outline: Outlined given, when, thens
Given there are <start> cucumbers
When I <use> cucumbers
Then I should have <left> cucumbers
Examples:
| use | start | count | left |
| eat <count> | 12 | 5 | 7 |
| grow <count>| 5 | 4 | 9 |
"""
),
)

testdir.makeconftest(textwrap.dedent(
"""\
from pytest_bdd import given, when, then
from pytest_bdd.parsers import re, parse
@given("there are <start> cucumbers", target_fixture="cucumbers_count")
def start_cucumbers(start):
assert isinstance(start, int)
return {"cucumbers_count": start}
@when(parse("I eat {eat:g} cucumbers"), converters=dict(eat=float))
def eat_cucumbers(cucumbers_count, eat):
assert isinstance(eat, float)
cucumbers_count["cucumbers_count"] -= eat
@when(parse("I grow {grow:g} cucumbers"), converters=dict(grow=float))
def eat_cucumbers(cucumbers_count, grow):
assert isinstance(grow, float)
cucumbers_count["cucumbers_count"] += grow
@then("I should have <left> cucumbers")
def should_have_left_cucumbers(cucumbers_count, left):
assert isinstance(left, str)
assert cucumbers_count["cucumbers_count"] == float(left)
"""
))

testdir.makepyfile(
textwrap.dedent(
"""\
from pytest_bdd.utils import get_parametrize_markers_args
from pytest_bdd import scenario
@scenario(
"outline.feature",
"Outlined given, when, thens",
example_converters=dict(start=int, count=float, left=str)
)
def test_outline(request):
assert get_parametrize_markers_args(request.node) == (
["use", "start", "count", "left"],
[
['eat <count>', 12, 5.0, "7"],
['grow <count>', 5, 4.0, "9"],
],
)
"""
)
)
result = testdir.runpytest()
result.assert_outcomes(passed=2)


@mark.parametrize("steps", [STRING_STEPS, PARSER_STEPS])
def test_outline_has_subset_of_parameters(testdir, steps):
"""Test parametrized scenario when the test function has a subset of the parameters of the examples."""
Expand Down

0 comments on commit e5d22c4

Please sign in to comment.