Add pytest_bdd_apply_tag hook
This commit is contained in:
parent
6bed671dcf
commit
c53f7a7519
|
@ -6,6 +6,7 @@ Changelog
|
|||
|
||||
- Fix FixtureDef signature for newer pytest versions (The-Compiler)
|
||||
- Better error explanation for the steps defined outside of scenarios (olegpidsadnyi)
|
||||
- Add a ``pytest_bdd_apply_tag`` hook to customize handling of tags (The-Compiler)
|
||||
|
||||
|
||||
2.16.1
|
||||
|
|
13
README.rst
13
README.rst
|
@ -747,6 +747,19 @@ Note that if you use pytest `--strict` option, all bdd tags mentioned in the fea
|
|||
`markers` setting of the `pytest.ini` config. Also for tags please use names which are python-compartible variable
|
||||
names, eg starts with a non-number, underscore alphanumberic, etc. That way you can safely use tags for tests filtering.
|
||||
|
||||
You can customize how hooks are converted to pytest marks by implementing the
|
||||
``pytest_bdd_apply_tag`` hook and returning ``True`` from it:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def pytest_bdd_apply_tag(tag, function):
|
||||
if tag == 'todo':
|
||||
marker = pytest.mark.skip(reason="Not implemented yet")
|
||||
marker(function)
|
||||
return True
|
||||
else:
|
||||
# Fall back to pytest-bdd's default behavior
|
||||
return None
|
||||
|
||||
Test setup
|
||||
----------
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import pytest
|
||||
|
||||
"""Pytest-bdd pytest hooks."""
|
||||
|
||||
|
||||
|
@ -31,3 +33,13 @@ def pytest_bdd_step_validation_error(request, feature, scenario, step, step_func
|
|||
|
||||
def pytest_bdd_step_func_lookup_error(request, feature, scenario, step, exception):
|
||||
"""Called when step lookup failed."""
|
||||
|
||||
|
||||
@pytest.hookspec(firstresult=True)
|
||||
def pytest_bdd_apply_tag(tag, function):
|
||||
"""Apply a tag (from a ``.feature`` file) to the given scenario.
|
||||
|
||||
The default implementation does the equivalent of
|
||||
``getattr(pytest.mark, tag)(function)``, but you can override this hook and
|
||||
return ``True`` to do more sophisticated handling of tags.
|
||||
"""
|
||||
|
|
|
@ -74,3 +74,9 @@ def pytest_bdd_after_step(request, feature, scenario, step, step_func, step_func
|
|||
|
||||
def pytest_cmdline_main(config):
|
||||
generation.cmdline_main(config)
|
||||
|
||||
|
||||
def pytest_bdd_apply_tag(tag, function):
|
||||
mark = getattr(pytest.mark, tag)
|
||||
mark(function)
|
||||
return True
|
||||
|
|
|
@ -269,7 +269,7 @@ def _get_scenario_decorator(feature, feature_name, scenario, scenario_name, call
|
|||
_scenario = pytest.mark.parametrize(*param_set)(_scenario)
|
||||
|
||||
for tag in scenario.tags.union(feature.tags):
|
||||
_scenario = getattr(pytest.mark, tag)(_scenario)
|
||||
pytest.config.hook.pytest_bdd_apply_tag(tag=tag, function=_scenario)
|
||||
|
||||
_scenario.__doc__ = "{feature_name}: {scenario_name}".format(
|
||||
feature_name=feature_name, scenario_name=scenario_name)
|
||||
|
|
|
@ -95,3 +95,47 @@ def test_tags_after_background_issue_160(testdir):
|
|||
result = testdir.runpytest('-m', 'tag', '-vv').parseoutcomes()
|
||||
assert result['passed'] == 1
|
||||
assert result['deselected'] == 1
|
||||
|
||||
|
||||
def test_apply_tag_hook(testdir):
|
||||
testdir.makeconftest("""
|
||||
import pytest
|
||||
|
||||
@pytest.hookimpl(tryfirst=True)
|
||||
def pytest_bdd_apply_tag(tag, function):
|
||||
if tag == 'todo':
|
||||
marker = pytest.mark.skipif(True, reason="Not implemented yet")
|
||||
marker(function)
|
||||
return True
|
||||
else:
|
||||
# Fall back to pytest-bdd's default behavior
|
||||
return None
|
||||
""")
|
||||
testdir.makefile('.feature', test="""
|
||||
Feature: Customizing tag handling
|
||||
|
||||
@todo
|
||||
Scenario: Tags
|
||||
Given I have a bar
|
||||
|
||||
@skip
|
||||
Scenario: Tags 2
|
||||
Given I have a bar
|
||||
""")
|
||||
testdir.makepyfile("""
|
||||
from pytest_bdd import given, scenarios
|
||||
|
||||
@given('I have a bar')
|
||||
def i_have_bar():
|
||||
return 'bar'
|
||||
|
||||
scenarios('test.feature')
|
||||
""")
|
||||
result = testdir.runpytest('-rs')
|
||||
result.stdout.fnmatch_lines(
|
||||
[
|
||||
"SKIP *: Not implemented yet",
|
||||
"SKIP *: unconditional skip",
|
||||
"*= 2 skipped * =*"
|
||||
]
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue