How do I pass a parameter from a WHEN TO a THEN in pytest bdd?
For example, if I have the following code:
@when('<n1> is a number divisible by 10')
def n1_is_a_number_divisible_by_10(n1):
assert (n1 % 10) == 0
newN1 = n1/10
return newN1
@then('the result will also be divisible by 3')
def the_result_will_also_be_divisible_by_3(newN1):
assert newN1 % 3 == 0
How do I pass newN1 from the when to the then?
(I have tried making newN1 a global variable...this works but making things global is often frowned upon in python).
Parameter passing involves passing input parameters into a module (a function in C and a function and procedure in Pascal) and receiving output parameters back from the module. For example a quadratic equation module requires three parameters to be passed to it, these would be a, b and c.
The then method returns a Promise which allows for method chaining. If the function passed as handler to then returns a Promise , an equivalent Promise will be exposed to the subsequent then in the method chain. The below snippet simulates asynchronous code with the setTimeout function. Promise. resolve("foo") // 1.
Parameters are essential to functions, because otherwise you can't give the function-machine an input.
When you pass an argument by reference, you pass a pointer to the value in memory. The function operates on the argument. When a function changes the value of an argument passed by reference, the original value changes. When you pass an argument by value, you pass a copy of the value in memory.
In pytest-bdd
version 4.1.0 the when
step now supports target_fixture
like the given
step.
Here is an example from the pytest-bdd documentation
# 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") # <--- here
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
You can't pass anything from "when" to "then" by returning. Generally you want to avoid this situation. But if you have to, use a pytest fixture as a message box in both steps:
@pytest.fixture(scope='function')
def context():
return {}
@when('<n1> is a number divisible by 10')
def n1_is_a_number_divisible_by_10(n1, context):
assert (n1 % 10) == 0
newN1 = n1 / 10
context['partial_result'] = newN1
@then('the result will also be divisible by 3')
def the_result_will_also_be_divisible_by_3(context):
assert context['partial_result'] % 3 == 0
Result of the "context" fixture is passed to the "when" step, populated, then passed to the "then" part. It isn't recreated each time.
As a side note, it's suboptimal to test your tests - you're doing so in the "when" part, asserting the divisibility. But this is just some sample code I guess.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With