Skip to content

Commit 30076d4

Browse files
Merge pull request #193 from The-Compiler/pytest30
[WIP] Initial attempt at pytest 3.0 compatibility
2 parents 544c81f + 7f16bc9 commit 30076d4

File tree

8 files changed

+81
-23
lines changed

8 files changed

+81
-23
lines changed

pytest_bdd/scenario.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
recreate_function,
4040
)
4141
from .types import GIVEN
42-
from .utils import get_args
42+
from .utils import get_args, get_fixture_value
4343

4444
if six.PY3: # pragma: no cover
4545
import runpy
@@ -71,7 +71,7 @@ def find_argumented_step_fixture_name(name, type_, fixturemanager, request=None)
7171
parser_name = get_step_fixture_name(parser.name, type_)
7272
if request:
7373
try:
74-
request.getfuncargvalue(parser_name)
74+
get_fixture_value(request, parser_name)
7575
except pytest_fixtures.FixtureLookupError:
7676
continue
7777
return parser_name
@@ -89,12 +89,12 @@ def _find_step_function(request, step, scenario, encoding):
8989
"""
9090
name = step.name
9191
try:
92-
return request.getfuncargvalue(get_step_fixture_name(name, step.type, encoding))
92+
return get_fixture_value(request, get_step_fixture_name(name, step.type, encoding))
9393
except pytest_fixtures.FixtureLookupError:
9494
try:
9595
name = find_argumented_step_fixture_name(name, step.type, request._fixturemanager, request)
9696
if name:
97-
return request.getfuncargvalue(name)
97+
return get_fixture_value(request, name)
9898
raise
9999
except pytest_fixtures.FixtureLookupError:
100100
raise exceptions.StepDefinitionNotFoundError(
@@ -129,7 +129,7 @@ def _execute_step_function(request, scenario, step, step_func):
129129
kw["step_func_args"] = {}
130130
try:
131131
# Get the step argument values.
132-
kwargs = dict((arg, request.getfuncargvalue(arg)) for arg in get_args(step_func))
132+
kwargs = dict((arg, get_fixture_value(request, arg)) for arg in get_args(step_func))
133133
kw["step_func_args"] = kwargs
134134

135135
request.config.hook.pytest_bdd_before_step_call(**kw)

pytest_bdd/steps.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ def article(author):
4949
StepError,
5050
)
5151
from .parsers import get_parser
52-
from .utils import get_args
52+
from .utils import get_args, get_fixture_value, get_fixture_value_raw, set_fixture_value, get_request_fixture_defs, \
53+
get_request_fixture_names
5354

5455

5556
def get_step_fixture_name(name, type_, encoding=None):
@@ -81,7 +82,7 @@ def given(name, fixture=None, converters=None, scope='function', target_fixture=
8182
module = get_caller_module()
8283

8384
def step_func(request):
84-
return request.getfuncargvalue(fixture)
85+
return get_fixture_value(request, fixture)
8586

8687
step_func.step_type = GIVEN
8788
step_func.converters = converters
@@ -161,7 +162,7 @@ def decorator(func):
161162
func = pytest.fixture(scope=scope)(func)
162163

163164
def step_func(request):
164-
result = request.getfuncargvalue(func.__name__)
165+
result = get_fixture_value(request, func.__name__)
165166
if target_fixture:
166167
inject_fixture(request, target_fixture, result)
167168
return result
@@ -302,23 +303,23 @@ def inject_fixture(request, arg, value):
302303
fd = pytest_fixtures.FixtureDef(**fd_kwargs)
303304
fd.cached_result = (value, 0, None)
304305

305-
old_fd = getattr(request, "_fixturedefs", {}).get(arg)
306-
old_value = request._funcargs.get(arg)
306+
old_fd = get_request_fixture_defs(request).get(arg)
307+
old_value = get_fixture_value_raw(request, arg)
307308
add_fixturename = arg not in request.fixturenames
308309

309310
def fin():
310311
request._fixturemanager._arg2fixturedefs[arg].remove(fd)
311-
getattr(request, "_fixturedefs", {})[arg] = old_fd
312-
request._funcargs[arg] = old_value
312+
get_request_fixture_defs(request)[arg] = old_fd
313+
set_fixture_value(request, arg, old_value)
313314
if add_fixturename:
314-
request.fixturenames.remove(arg)
315+
get_request_fixture_names(request).remove(arg)
315316

316317
request.addfinalizer(fin)
317318

318319
# inject fixture definition
319320
request._fixturemanager._arg2fixturedefs.setdefault(arg, []).insert(0, fd)
320321
# inject fixture value in request cache
321-
getattr(request, "_fixturedefs", {})[arg] = fd
322-
request._funcargs[arg] = value
322+
get_request_fixture_defs(request)[arg] = fd
323+
set_fixture_value(request, arg, value)
323324
if add_fixturename:
324-
request.fixturenames.append(arg)
325+
get_request_fixture_names(request).append(arg)

pytest_bdd/utils.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,54 @@ def get_args(func):
2121
if param.kind == param.POSITIONAL_OR_KEYWORD]
2222
else:
2323
return inspect.getargspec(func).args
24+
25+
26+
def get_fixture_value(request, name):
27+
"""Get the given fixture from the pytest request object.
28+
29+
getfuncargvalue() is deprecated in pytest 3.0, so we need to use
30+
getfixturevalue() there.
31+
"""
32+
try:
33+
getfixturevalue = request.getfixturevalue
34+
except AttributeError:
35+
getfixturevalue = request.getfuncargvalue
36+
return getfixturevalue(name)
37+
38+
39+
def get_fixture_value_raw(request, name):
40+
"""Set the given raw fixture value from the pytest request object."""
41+
try:
42+
return request._fixture_values.get(name)
43+
except AttributeError:
44+
return request._funcargs.get(name)
45+
46+
47+
def set_fixture_value(request, name, value):
48+
"""Set the given fixture value on the pytest request object."""
49+
try:
50+
request._fixture_values[name] = value
51+
except AttributeError:
52+
request._funcargs[name] = value
53+
54+
55+
def get_request_fixture_defs(request):
56+
"""Get the internal list of FixtureDefs cached into the given request object.
57+
58+
Compatibility with pytest 3.0.
59+
"""
60+
try:
61+
return request._fixture_defs
62+
except AttributeError:
63+
return getattr(request, "_fixturedefs", {})
64+
65+
66+
def get_request_fixture_names(request):
67+
"""Get list of fixture names for the given FixtureRequest.
68+
69+
Get the internal and mutable list of fixture names in the enclosing scope of
70+
the given request object.
71+
72+
Compatibility with pytest 3.0.
73+
"""
74+
return request._pyfuncitem._fixtureinfo.names_closure

tests/feature/test_cucumber_json.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ def test_failing():
158158
"type": "scenario"
159159
}
160160
],
161-
"id": "test_step_trace0/test.feature",
161+
"id": os.path.join("test_step_trace0", "test.feature"),
162162
"keyword": "Feature",
163163
"line": 2,
164164
"name": "One passing scenario, one failing scenario",

tests/feature/test_multiline.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
scenario,
1111
then,
1212
)
13+
from pytest_bdd.utils import get_fixture_value
1314

1415

1516
@pytest.mark.parametrize(["feature_text", "expected_text"], [
@@ -72,7 +73,7 @@ def test_multiline(request, tmpdir, feature_text, expected_text):
7273

7374
@scenario(file_name.strpath, 'Multiline step using sub indentation')
7475
def test_multiline(request):
75-
assert request.getfuncargvalue('i_have_text') == expected_text
76+
assert get_fixture_value(request, 'i_have_text') == expected_text
7677
test_multiline(request)
7778

7879

tests/library/child/test_local_override.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from pytest_bdd import given
77
from pytest_bdd.steps import get_step_fixture_name, GIVEN
8+
from pytest_bdd.utils import get_fixture_value
89

910

1011
@given('I have locally overriden fixture')
@@ -21,10 +22,12 @@ def test_override(request, overridable):
2122
"""Test locally overriden fixture."""
2223

2324
# Test the fixture is also collected by the text name
24-
assert request.getfuncargvalue(get_step_fixture_name('I have locally overriden fixture', GIVEN))(request) == 'local'
25+
fixture = get_fixture_value(request, get_step_fixture_name('I have locally overriden fixture', GIVEN))
26+
assert fixture(request) == 'local'
2527

2628
# 'I have the overriden fixture' stands for overridable and is overriden locally
27-
assert request.getfuncargvalue(get_step_fixture_name('I have the overriden fixture', GIVEN))(request) == 'local'
29+
fixture = get_fixture_value(request, get_step_fixture_name('I have the overriden fixture', GIVEN))
30+
assert fixture(request) == 'local'
2831

2932
assert overridable == 'local'
3033

tests/library/test_parent.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
Check the parent givens are collected and overriden in the local conftest.
44
"""
55
from pytest_bdd.steps import get_step_fixture_name, WHEN
6+
from pytest_bdd.utils import get_fixture_value
67

78

89
def test_parent(parent, overridable):
@@ -16,4 +17,4 @@ def test_parent(parent, overridable):
1617

1718
def test_global_when_step(request):
1819
"""Test when step defined in the parent conftest."""
19-
request.getfuncargvalue(get_step_fixture_name('I use a when step from the parent conftest', WHEN))
20+
get_fixture_value(request, get_step_fixture_name('I use a when step from the parent conftest', WHEN))

tests/steps/test_steps.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import pytest
44
from pytest_bdd import given, when, then
55
from pytest_bdd.steps import get_step_fixture_name, WHEN, THEN
6+
from pytest_bdd.utils import get_fixture_value
67

78

89
@when('I do stuff')
@@ -21,10 +22,10 @@ def test_when_then(request):
2122
This test checks that when and then are not evaluated
2223
during fixture collection that might break the scenario.
2324
"""
24-
do_stuff_ = request.getfuncargvalue(get_step_fixture_name('I do stuff', WHEN))
25+
do_stuff_ = get_fixture_value(request, get_step_fixture_name('I do stuff', WHEN))
2526
assert callable(do_stuff_)
2627

27-
check_stuff_ = request.getfuncargvalue(get_step_fixture_name('I check stuff', THEN))
28+
check_stuff_ = get_fixture_value(request, get_step_fixture_name('I check stuff', THEN))
2829
assert callable(check_stuff_)
2930

3031

0 commit comments

Comments
 (0)