refactor to use exec
This commit is contained in:
parent
bca5206677
commit
05e3c0e171
|
@ -1,7 +1,9 @@
|
|||
"""Pytest-bdd markers."""
|
||||
import inspect
|
||||
|
||||
from pytest_bdd.steps import recreate_function, get_caller_module, get_caller_function
|
||||
import pytest
|
||||
|
||||
from pytest_bdd.steps import execute, recreate_function, get_caller_module, get_caller_function
|
||||
|
||||
from pytest_bdd import scenario as bdd_scenario
|
||||
|
||||
|
@ -19,7 +21,28 @@ def scenario(feature_name, scenario_name, encoding='utf-8', example_converters=N
|
|||
|
||||
args = inspect.getargspec(request).args
|
||||
|
||||
_scenario = recreate_function(_scenario, name=request.__name__, module=caller_module, add_args=args)
|
||||
if 'request' not in args:
|
||||
args.insert(0, 'request')
|
||||
|
||||
g = globals().copy()
|
||||
g.update(locals())
|
||||
|
||||
pytestbdd_params = _scenario.pytestbdd_params
|
||||
scenario = _scenario.scenario
|
||||
|
||||
sc_args = list(scenario.example_params)
|
||||
if 'request' not in sc_args:
|
||||
sc_args.insert(0, 'request')
|
||||
|
||||
code = """def _decorated_scenario({0}):
|
||||
_scenario({1})""".format(', '.join(args), ', '.join(sc_args))
|
||||
|
||||
execute(code, g)
|
||||
|
||||
_scenario = recreate_function(g['_decorated_scenario'], module=caller_module, add_args=args)
|
||||
|
||||
if pytestbdd_params:
|
||||
_scenario = pytest.mark.parametrize(*pytestbdd_params)(_scenario)
|
||||
|
||||
return _scenario
|
||||
|
||||
|
|
|
@ -11,22 +11,20 @@ test_publish_article = scenario(
|
|||
)
|
||||
|
||||
"""
|
||||
|
||||
import collections
|
||||
import os
|
||||
import imp
|
||||
|
||||
import sys
|
||||
import inspect # pragma: no cover
|
||||
from os import path as op # pragma: no cover
|
||||
|
||||
import pytest
|
||||
|
||||
from future import utils as future_utils
|
||||
|
||||
from _pytest import python
|
||||
|
||||
from pytest_bdd.feature import Feature, force_encode # pragma: no cover
|
||||
from pytest_bdd.steps import recreate_function, get_caller_module, get_caller_function
|
||||
from pytest_bdd.steps import execute, recreate_function, get_caller_module, get_caller_function
|
||||
from pytest_bdd.types import GIVEN
|
||||
|
||||
from pytest_bdd import plugin
|
||||
|
@ -110,7 +108,6 @@ def _find_step_function(request, name, encoding):
|
|||
|
||||
pattern = getattr(fixturedef.func, 'pattern', None)
|
||||
match = pattern.match(name) if pattern else None
|
||||
|
||||
if match:
|
||||
converters = getattr(fixturedef.func, 'converters', {})
|
||||
for arg, value in match.groupdict().items():
|
||||
|
@ -121,7 +118,7 @@ def _find_step_function(request, name, encoding):
|
|||
raise
|
||||
|
||||
|
||||
def _validate_scenario(feature, scenario, request):
|
||||
def _validate_scenario(feature, scenario):
|
||||
"""Validate the scenario."""
|
||||
if scenario.params and scenario.example_params and scenario.params != set(scenario.example_params):
|
||||
raise ScenarioExamplesNotValidError(
|
||||
|
@ -132,21 +129,6 @@ def _validate_scenario(feature, scenario, request):
|
|||
)
|
||||
|
||||
|
||||
def _execute_scenario_outline(feature, scenario, request, encoding, example_converters=None):
|
||||
"""Execute the scenario outline."""
|
||||
errors = []
|
||||
# tricky part, basically here we clear pytest request cache
|
||||
for example in scenario.examples:
|
||||
request._funcargs = {}
|
||||
request._arg2index = {}
|
||||
try:
|
||||
_execute_scenario(feature, scenario, request, encoding, example=dict(zip(scenario.example_params, example)))
|
||||
except Exception as e:
|
||||
errors.append([e, sys.exc_info()[2]])
|
||||
for error in errors:
|
||||
raise future_utils.raise_with_traceback(error[0], error[1])
|
||||
|
||||
|
||||
def _execute_step_function(request, feature, step, step_func, example=None):
|
||||
"""Execute step function."""
|
||||
kwargs = {}
|
||||
|
@ -177,8 +159,6 @@ def _execute_step_function(request, feature, step, step_func, example=None):
|
|||
def _execute_scenario(feature, scenario, request, encoding, example=None):
|
||||
"""Execute the scenario."""
|
||||
|
||||
_validate_scenario(feature, scenario, request)
|
||||
|
||||
givens = set()
|
||||
# Execute scenario steps
|
||||
for step in scenario.steps:
|
||||
|
@ -265,6 +245,8 @@ def scenario(
|
|||
'Scenario "{0}" in feature "{1}" is not found.'.format(scenario_name, feature_name)
|
||||
)
|
||||
|
||||
_validate_scenario(feature, scenario)
|
||||
|
||||
if scenario.examples:
|
||||
params = []
|
||||
for example in scenario.examples:
|
||||
|
@ -276,12 +258,18 @@ def scenario(
|
|||
else:
|
||||
params = []
|
||||
|
||||
def _scenario(request, *args, **kwargs):
|
||||
_execute_scenario(feature, scenario, request, encoding)
|
||||
g = globals().copy()
|
||||
g.update(locals())
|
||||
|
||||
code = """def _scenario(request, {0}):
|
||||
_execute_scenario(feature, scenario, request, encoding)""".format(','.join(scenario.example_params))
|
||||
|
||||
execute(code, g)
|
||||
|
||||
_scenario = recreate_function(
|
||||
_scenario, module=caller_module, firstlineno=caller_function.f_lineno,
|
||||
add_args=scenario.example_params)
|
||||
g['_scenario'], module=caller_module, firstlineno=caller_function.f_lineno)
|
||||
if params:
|
||||
_scenario = pytest.mark.parametrize(*params)(_scenario)
|
||||
_scenario.pytestbdd_params = params
|
||||
_scenario.scenario = scenario
|
||||
return _scenario
|
||||
|
|
|
@ -234,7 +234,6 @@ def contribute_to_module(module, name, func):
|
|||
|
||||
"""
|
||||
func = recreate_function(func, module=module)
|
||||
|
||||
setattr(module, name, func)
|
||||
|
||||
|
||||
|
@ -247,3 +246,7 @@ def get_caller_module(depth=2):
|
|||
def get_caller_function(depth=2):
|
||||
"""Return caller function."""
|
||||
return sys._getframe(depth)
|
||||
|
||||
|
||||
def execute(code, g):
|
||||
exec(code, g)
|
||||
|
|
1
setup.py
1
setup.py
|
@ -54,7 +54,6 @@ setup(
|
|||
cmdclass={'test': Tox},
|
||||
install_requires=[
|
||||
'pytest',
|
||||
'future'
|
||||
],
|
||||
# the following makes a plugin available to py.test
|
||||
entry_points={
|
||||
|
|
|
@ -37,15 +37,14 @@ def should_have_left_cucumbers(start_cucumbers, start, eat, left):
|
|||
|
||||
def test_wrongly_outlined(request):
|
||||
"""Test parametrized scenario when the test function lacks parameters."""
|
||||
@mark.scenario(
|
||||
'outline.feature',
|
||||
'Outlined with wrong examples',
|
||||
)
|
||||
def wrongly_outlined(request):
|
||||
pass
|
||||
|
||||
with pytest.raises(ScenarioExamplesNotValidError) as exc:
|
||||
wrongly_outlined(request, 1, 2, 3, 4)
|
||||
@mark.scenario(
|
||||
'outline.feature',
|
||||
'Outlined with wrong examples',
|
||||
)
|
||||
def wrongly_outlined(request):
|
||||
pass
|
||||
|
||||
assert re.match(
|
||||
"""Scenario \"Outlined with wrong examples\" in the feature \"(.+)\" has not valid examples\. """
|
||||
|
|
Loading…
Reference in New Issue