Added hook before the step is executed with evaluated parameters

This commit is contained in:
Oleg Pidsadnyi 2015-04-28 14:57:02 +02:00
parent 34c5823a3e
commit 97de1158fd
7 changed files with 38 additions and 21 deletions

View File

@ -1,6 +1,12 @@
Changelog
=========
Unreleased
----------
- Added hook before the step is executed with evaluated parameters (olegpidsadnyi)
2.7.2
-----

View File

@ -919,6 +919,9 @@ which might be helpful building useful reporting, visualization, etc on top of i
* pytest_bdd_before_step(request, feature, scenario, step, step_func) - Called before step function
is executed and it's arguments evaluated
* pytest_bdd_before_step_call(request, feature, scenario, step, step_func, step_func_args) - Called before step
* function is executed with evaluated arguments
* pytest_bdd_after_step(request, feature, scenario, step, step_func, step_func_args) - Called after step function
is successfully executed

View File

@ -14,7 +14,6 @@ from .scenario import (
from .feature import get_features
from .types import STEP_TYPES
tw = py.io.TerminalWriter()
template_lookup = TemplateLookup(directories=[os.path.join(os.path.dirname(__file__), "templates")])
@ -62,6 +61,7 @@ def show_missing_code(config):
def print_missing_code(scenarios, steps):
"""Print missing code with TerminalWriter."""
tw = py.io.TerminalWriter()
scenario = step = None
for scenario in scenarios:
@ -160,6 +160,7 @@ def group_steps(steps):
def _show_missing_code_main(config, session):
"""Preparing fixture duplicates for output."""
tw = py.io.TerminalWriter()
session.perform_collect()
fm = session._fixturemanager

View File

@ -10,6 +10,10 @@ def pytest_bdd_after_scenario(request, feature, scenario):
def pytest_bdd_before_step(request, feature, scenario, step, step_func):
"""Called before step function is set up."""
def pytest_bdd_before_step_call(request, feature, scenario, step, step_func, step_func_args):
"""Called before step function is executed."""

View File

@ -55,11 +55,13 @@ def _inject_fixture(request, arg, value):
:param value: argument value
"""
fd = python.FixtureDef(
request._fixturemanager,
None,
arg,
lambda: value, None, None,
False,
fixturemanager=request._fixturemanager,
baseid=None,
argname=arg,
func=lambda: value,
scope="function",
params=None,
yieldctx=False,
)
fd.cached_result = (value, 0, None)
@ -147,14 +149,16 @@ def _execute_step_function(request, scenario, step, step_func, example=None):
:param function step_func: Step function.
:param example: Example table.
"""
request.config.hook.pytest_bdd_before_step(
kw = dict(
request=request,
feature=scenario.feature,
scenario=scenario,
step=step,
step_func=step_func,
)
kwargs = {}
request.config.hook.pytest_bdd_before_step(**kw)
if example:
for key in step.params:
value = example[key]
@ -162,22 +166,15 @@ def _execute_step_function(request, scenario, step, step_func, example=None):
value = step_func.converters[key](value)
_inject_fixture(request, key, value)
kw = dict(
request=request,
feature=scenario.feature,
scenario=scenario,
step=step,
step_func=step_func,
step_func_args=kwargs,
)
kw["step_func_args"] = {}
try:
# Get the step argument values.
kwargs = dict((arg, request.getfuncargvalue(arg)) for arg in inspect.getargspec(step_func).args)
kw["step_func_args"] = kwargs
request.config.hook.pytest_bdd_before_step_call(**kw)
# Execute the step.
step_func(**kwargs)
kw["step_func_args"] = kwargs
request.config.hook.pytest_bdd_after_step(**kw)
except Exception as exception:
request.config.hook.pytest_bdd_step_error(exception=exception, **kw)

View File

@ -162,6 +162,9 @@ def test_step_hooks(testdir):
calls = reprec.getcalls("pytest_bdd_before_step")
assert calls[0].request
calls = reprec.getcalls("pytest_bdd_before_step_call")
assert calls[0].request
calls = reprec.getcalls("pytest_bdd_after_step")
assert calls[0].request
@ -183,6 +186,9 @@ def test_step_hooks(testdir):
calls = reprec.getcalls("pytest_bdd_before_step")
assert len(calls) == 2
calls = reprec.getcalls("pytest_bdd_before_step_call")
assert len(calls) == 1
calls = reprec.getcalls("pytest_bdd_step_error")
assert calls[0].request

View File

@ -6,7 +6,8 @@ import py
def test_generate_missing(testdir):
tests = testdir.mkpydir("tests")
dirname = "test_generate_missing"
tests = testdir.mkpydir(dirname)
with open(os.path.join(os.path.dirname(__file__), "generation.feature")) as fd:
tests.join('generation.feature').write(fd.read())
@ -30,8 +31,7 @@ def test_generate_missing(testdir):
pass
"""))
result = testdir.runpytest(
"tests", "--generate-missing", "--feature", tests.join('generation.feature').strpath)
result = testdir.runpytest(dirname, "--generate-missing", "--feature", tests.join('generation.feature').strpath)
result.stdout.fnmatch_lines([
'Scenario "Code is generated for scenarios which are not bound to any tests" is not bound to any test *']