Step arguments are no longer fixtures
This commit is contained in:
parent
6730b428ed
commit
7cd7b40df3
|
@ -9,6 +9,7 @@ This release introduces breaking changes in order to be more in line with the of
|
|||
- Cleanup of the documentation and tests related to parametrization (elchupanebrej)
|
||||
- Removed feature level examples for the gherkin compatibility (olegpidsadnyi)
|
||||
- Removed vertical examples for the gherkin compatibility (olegpidsadnyi)
|
||||
- Step arguments are no longer fixtures (olegpidsadnyi)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1023,6 +1023,12 @@ Vertical example tables are no longer supported since the official gherkin doesn
|
|||
The example tables should have horizontal orientation.
|
||||
|
||||
|
||||
Step arguments are no longer fixtures
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Step parsed arguments conflicted with the fixtures. Now they no longer define fixture.
|
||||
If the fixture has to be defined by the step the target_fixture param should be used.
|
||||
|
||||
|
||||
.. _Migration from 4.x.x:
|
||||
|
||||
Migration of your tests from versions 4.x.x
|
||||
|
|
|
@ -44,7 +44,7 @@ def parse_line(line):
|
|||
"""
|
||||
for prefix, _ in STEP_PREFIXES:
|
||||
if line.startswith(prefix):
|
||||
return prefix.strip(), line[len(prefix) :].strip()
|
||||
return prefix.strip(), line[len(prefix):].strip()
|
||||
return "", line
|
||||
|
||||
|
||||
|
|
|
@ -44,14 +44,6 @@ def find_argumented_step_fixture_name(name, type_, fixturemanager, request=None)
|
|||
if not match:
|
||||
continue
|
||||
|
||||
# TODO: maybe `converters` should be part of the SterParser.__init__(),
|
||||
# and used by StepParser.parse_arguments() method
|
||||
converters = getattr(fixturedef.func, "converters", {})
|
||||
for arg, value in parser.parse_arguments(name).items():
|
||||
if arg in converters:
|
||||
value = converters[arg](value)
|
||||
if request:
|
||||
inject_fixture(request, arg, value)
|
||||
parser_name = get_step_fixture_name(parser.name, type_)
|
||||
if request:
|
||||
try:
|
||||
|
@ -105,7 +97,20 @@ def _execute_step_function(request, scenario, step, step_func):
|
|||
kw["step_func_args"] = {}
|
||||
try:
|
||||
# Get the step argument values.
|
||||
kwargs = {arg: request.getfixturevalue(arg) for arg in get_args(step_func)}
|
||||
converters = getattr(step_func, "converters", {})
|
||||
kwargs = {}
|
||||
|
||||
parser = getattr(step_func, "parser", None)
|
||||
if parser is not None:
|
||||
for arg, value in parser.parse_arguments(step.name).items():
|
||||
if arg in converters:
|
||||
value = converters[arg](value)
|
||||
kwargs[arg] = value
|
||||
|
||||
kwargs = {
|
||||
arg: kwargs[arg] if arg in kwargs else request.getfixturevalue(arg)
|
||||
for arg in get_args(step_func)
|
||||
}
|
||||
kw["step_func_args"] = kwargs
|
||||
|
||||
request.config.hook.pytest_bdd_before_step_call(**kw)
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
import textwrap
|
||||
|
||||
|
||||
def test_arg_fixture_mix(testdir):
|
||||
|
||||
subdir = testdir.mkpydir("arg_fixture_mix")
|
||||
subdir.join("test_a.py").write(
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
import re
|
||||
import pytest
|
||||
from pytest_bdd import scenario, given, then, parsers
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def foo():
|
||||
return "fine"
|
||||
|
||||
@scenario(
|
||||
'arg_and_fixture_mix.feature',
|
||||
'Use the step argument with the same name as fixture of another test',
|
||||
)
|
||||
def test_args():
|
||||
pass
|
||||
|
||||
@given(parsers.parse('foo is "{foo}"'))
|
||||
def foo1(foo):
|
||||
pass
|
||||
|
||||
|
||||
@then(parsers.parse('foo should be "{foo_value}"'))
|
||||
def foo_should_be(foo, foo_value):
|
||||
assert foo == foo_value
|
||||
|
||||
@scenario(
|
||||
'arg_and_fixture_mix.feature',
|
||||
'Everything is fine',
|
||||
)
|
||||
def test_bar():
|
||||
pass
|
||||
|
||||
@given('it is all fine')
|
||||
def fine():
|
||||
return "fine"
|
||||
|
||||
|
||||
@then('foo should be fine')
|
||||
def foo_should_be_fine(foo):
|
||||
assert foo == "fine"
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
subdir.join("test_b.py").write(
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
import re
|
||||
import pytest
|
||||
from pytest_bdd import scenario, given, then
|
||||
|
||||
@scenario(
|
||||
'arg_and_fixture_mix.feature',
|
||||
'Everything is fine',
|
||||
)
|
||||
def test_args():
|
||||
pass
|
||||
|
||||
@pytest.fixture
|
||||
def foo():
|
||||
return "fine"
|
||||
|
||||
|
||||
@given('it is all fine')
|
||||
def fine():
|
||||
return "fine"
|
||||
|
||||
|
||||
@then('foo should be fine')
|
||||
def foo_should_be(foo):
|
||||
assert foo == "fine"
|
||||
|
||||
|
||||
def test_bar(foo):
|
||||
assert foo == 'fine'
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
subdir.join("arg_and_fixture_mix.feature").write(
|
||||
"""
|
||||
Feature: Arg and fixture mix
|
||||
Scenario: Use the step argument with the same name as fixture of another test
|
||||
Given foo is "Hello"
|
||||
Then foo should be "Hello"
|
||||
|
||||
|
||||
Scenario: Everything is fine
|
||||
Given it is all fine
|
||||
Then foo should be fine
|
||||
"""
|
||||
)
|
||||
|
||||
result = testdir.runpytest("-k arg_fixture_mix")
|
||||
result.assert_outcomes(passed=4)
|
|
@ -87,14 +87,14 @@ def test_multiline(testdir, feature_text, expected_text):
|
|||
assert request.getfixturevalue("text") == expected_text
|
||||
|
||||
|
||||
@given(parsers.parse("I have a step with:\\n{{text}}"), target_fixture="i_have_text")
|
||||
@given(parsers.parse("I have a step with:\\n{{text}}"), target_fixture="text")
|
||||
def i_have_text(text):
|
||||
return text
|
||||
|
||||
|
||||
@then("the text should be parsed with correct indentation")
|
||||
def text_should_be_correct(i_have_text, text):
|
||||
assert i_have_text == text == expected_text
|
||||
def text_should_be_correct(text):
|
||||
assert text == expected_text
|
||||
|
||||
""".format(
|
||||
expected_text=expected_text.encode("unicode_escape").decode("utf-8"),
|
||||
|
@ -137,14 +137,14 @@ def test_multiline_wrong_indent(testdir):
|
|||
pass
|
||||
|
||||
|
||||
@given(parsers.parse("I have a step with:\\n{{text}}"))
|
||||
@given(parsers.parse("I have a step with:\\n{{text}}"), target_fixture="text")
|
||||
def i_have_text(text):
|
||||
return text
|
||||
|
||||
|
||||
@then("the text should be parsed with correct indentation")
|
||||
def text_should_be_correct(i_have_text, text):
|
||||
assert i_have_text == text == expected_text
|
||||
def text_should_be_correct(text):
|
||||
assert text == expected_text
|
||||
|
||||
"""
|
||||
)
|
||||
|
|
|
@ -9,27 +9,25 @@ from pytest_bdd import parsers, given, when, then
|
|||
from pytest_bdd.utils import dump_obj
|
||||
|
||||
|
||||
@given(parsers.parse("there are {start:d} cucumbers"), target_fixture="start_cucumbers")
|
||||
def start_cucumbers(start):
|
||||
@given(parsers.parse("there are {start:d} cucumbers"), target_fixture="cucumbers")
|
||||
def given_cucumbers(start):
|
||||
assert isinstance(start, int)
|
||||
dump_obj(start)
|
||||
return {"start": start}
|
||||
|
||||
|
||||
@when(parsers.parse("I eat {eat:g} cucumbers"))
|
||||
def eat_cucumbers(start_cucumbers, eat):
|
||||
def eat_cucumbers(cucumbers, eat):
|
||||
assert isinstance(eat, float)
|
||||
dump_obj(eat)
|
||||
start_cucumbers["eat"] = eat
|
||||
cucumbers["eat"] = eat
|
||||
|
||||
|
||||
@then(parsers.parse("I should have {left} cucumbers"))
|
||||
def should_have_left_cucumbers(start_cucumbers, start, eat, left):
|
||||
def should_have_left_cucumbers(cucumbers, left):
|
||||
assert isinstance(left, str)
|
||||
dump_obj(left)
|
||||
assert start - eat == int(left)
|
||||
assert start_cucumbers["start"] == start
|
||||
assert start_cucumbers["eat"] == eat
|
||||
assert cucumbers["start"] - cucumbers["eat"] == int(left)
|
||||
|
||||
"""
|
||||
|
||||
|
|
|
@ -76,24 +76,22 @@ def test_step_trace(testdir):
|
|||
def a_failing_step():
|
||||
raise Exception('Error')
|
||||
|
||||
@given(parsers.parse('there are {start:d} cucumbers'), target_fixture="start_cucumbers")
|
||||
def start_cucumbers(start):
|
||||
@given(parsers.parse('there are {start:d} cucumbers'), target_fixture="cucumbers")
|
||||
def given_cucumbers(start):
|
||||
assert isinstance(start, int)
|
||||
return {"start": start}
|
||||
|
||||
|
||||
@when(parsers.parse('I eat {eat:g} cucumbers'))
|
||||
def eat_cucumbers(start_cucumbers, eat):
|
||||
def eat_cucumbers(cucumbers, eat):
|
||||
assert isinstance(eat, float)
|
||||
start_cucumbers['eat'] = eat
|
||||
cucumbers['eat'] = eat
|
||||
|
||||
|
||||
@then(parsers.parse('I should have {left} cucumbers'))
|
||||
def should_have_left_cucumbers(start_cucumbers, start, eat, left):
|
||||
def should_have_left_cucumbers(cucumbers, left):
|
||||
assert isinstance(left, str)
|
||||
assert start - eat == int(left)
|
||||
assert start_cucumbers['start'] == start
|
||||
assert start_cucumbers['eat'] == eat
|
||||
assert cucumbers['start'] - cucumbers['eat'] == int(left)
|
||||
|
||||
|
||||
scenarios('test.feature')
|
||||
|
|
Loading…
Reference in New Issue