Merge pull request #431 from pytest-dev/then-when-target-fixture
Support `target_fixture` in `when` and `then` steps.
This commit is contained in:
commit
98f67019de
|
@ -3,6 +3,7 @@ Changelog
|
|||
|
||||
Unreleased
|
||||
-----------
|
||||
- `when` and `then` steps now can provide a `target_fixture`, just like `given` does. Discussion at https://github.com/pytest-dev/pytest-bdd/issues/402.
|
||||
- Drop compatibility for python 2 and officially support only python >= 3.6.
|
||||
- Fix error when using `--cucumber-json-expanded` in combination with `example_converters` (marcbrossaissogeti).
|
||||
- Fix `--generate-missing` not correctly recognizing steps with parsers
|
||||
|
|
41
README.rst
41
README.rst
|
@ -359,6 +359,47 @@ it will stay untouched. To allow this, special parameter `target_fixture` exists
|
|||
In this example existing fixture `foo` will be overridden by given step `I have injecting given` only for scenario it's
|
||||
used in.
|
||||
|
||||
Sometimes it is also useful to let `when` and `then` steps to provide a fixture as well.
|
||||
A common use case is when we have to assert the outcome of an HTTP request:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# test_blog.py
|
||||
|
||||
from pytest_bdd import scenarios, given, when, then
|
||||
|
||||
from my_app.models import Article
|
||||
|
||||
scenarios("blog.feature")
|
||||
|
||||
|
||||
@given("there is an article", target_fixture="article")
|
||||
def there_is_an_article():
|
||||
return Article()
|
||||
|
||||
|
||||
@when("I request the deletion of the article", target_fixture="request_result")
|
||||
def there_should_be_a_new_article(article, http_client):
|
||||
return http_client.delete(f"/articles/{article.uid}")
|
||||
|
||||
|
||||
@then("the request should be successful")
|
||||
def article_is_published(request_result):
|
||||
assert request_result.status_code == 200
|
||||
|
||||
|
||||
.. code-block:: gherkin
|
||||
|
||||
# blog.feature
|
||||
|
||||
Feature: Blog
|
||||
Scenario: Deleting the article
|
||||
Given there is an article
|
||||
|
||||
When I request the deletion of the article
|
||||
|
||||
Then the request should be successful
|
||||
|
||||
|
||||
Multiline steps
|
||||
---------------
|
||||
|
|
|
@ -61,35 +61,37 @@ def given(name, converters=None, target_fixture=None):
|
|||
:param name: Step name or a parser object.
|
||||
:param converters: Optional `dict` of the argument or parameter converters in form
|
||||
{<param_name>: <converter function>}.
|
||||
:param target_fixture: Target fixture name to replace by steps definition function
|
||||
:param target_fixture: Target fixture name to replace by steps definition function.
|
||||
|
||||
:return: Decorator function for the step.
|
||||
"""
|
||||
return _step_decorator(GIVEN, name, converters=converters, target_fixture=target_fixture)
|
||||
|
||||
|
||||
def when(name, converters=None):
|
||||
def when(name, converters=None, target_fixture=None):
|
||||
"""When step decorator.
|
||||
|
||||
:param name: Step name or a parser object.
|
||||
:param converters: Optional `dict` of the argument or parameter converters in form
|
||||
{<param_name>: <converter function>}.
|
||||
:param target_fixture: Target fixture name to replace by steps definition function.
|
||||
|
||||
:return: Decorator function for the step.
|
||||
"""
|
||||
return _step_decorator(WHEN, name, converters=converters)
|
||||
return _step_decorator(WHEN, name, converters=converters, target_fixture=target_fixture)
|
||||
|
||||
|
||||
def then(name, converters=None):
|
||||
def then(name, converters=None, target_fixture=None):
|
||||
"""Then step decorator.
|
||||
|
||||
:param name: Step name or a parser object.
|
||||
:param converters: Optional `dict` of the argument or parameter converters in form
|
||||
{<param_name>: <converter function>}.
|
||||
:param target_fixture: Target fixture name to replace by steps definition function.
|
||||
|
||||
:return: Decorator function for the step.
|
||||
"""
|
||||
return _step_decorator(THEN, name, converters=converters)
|
||||
return _step_decorator(THEN, name, converters=converters, target_fixture=target_fixture)
|
||||
|
||||
|
||||
def _step_decorator(step_type, step_name, converters=None, target_fixture=None):
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import textwrap
|
||||
import pytest
|
||||
|
||||
|
||||
def test_steps(testdir):
|
||||
|
@ -73,6 +72,59 @@ def test_steps(testdir):
|
|||
result.assert_outcomes(passed=1, failed=0)
|
||||
|
||||
|
||||
def test_all_steps_can_provide_fixtures(testdir):
|
||||
"""Test that given/when/then can all provide fixtures."""
|
||||
testdir.makefile(
|
||||
".feature",
|
||||
steps=textwrap.dedent(
|
||||
"""\
|
||||
Feature: Step fixture
|
||||
Scenario: Given steps can provide fixture
|
||||
Given Foo is "bar"
|
||||
Then foo should be "bar"
|
||||
Scenario: When steps can provide fixture
|
||||
When Foo is "baz"
|
||||
Then foo should be "baz"
|
||||
Scenario: Then steps can provide fixture
|
||||
Then foo is "qux"
|
||||
And foo should be "qux"
|
||||
"""
|
||||
),
|
||||
)
|
||||
|
||||
testdir.makepyfile(
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
from pytest_bdd import given, when, then, parsers, scenarios
|
||||
|
||||
scenarios("steps.feature")
|
||||
|
||||
@given(parsers.parse('Foo is "{value}"'), target_fixture="foo")
|
||||
def given_foo_is_value(value):
|
||||
return value
|
||||
|
||||
|
||||
@when(parsers.parse('Foo is "{value}"'), target_fixture="foo")
|
||||
def when_foo_is_value(value):
|
||||
return value
|
||||
|
||||
|
||||
@then(parsers.parse('Foo is "{value}"'), target_fixture="foo")
|
||||
def then_foo_is_value(value):
|
||||
return value
|
||||
|
||||
|
||||
@then(parsers.parse('foo should be "{value}"'))
|
||||
def foo_is_foo(foo, value):
|
||||
assert foo == value
|
||||
|
||||
"""
|
||||
)
|
||||
)
|
||||
result = testdir.runpytest()
|
||||
result.assert_outcomes(passed=3, failed=0)
|
||||
|
||||
|
||||
def test_when_first(testdir):
|
||||
testdir.makefile(
|
||||
".feature",
|
||||
|
|
Loading…
Reference in New Issue