-
Notifications
You must be signed in to change notification settings - Fork 221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
parsers.parse with scenario outline - pytest_bdd.exceptions.StepDefinitionNotFoundError #293
Comments
Hi, You should define scenario outlines in following way:
As you can see I don't know if you can use scenario outlines together with parsers.
|
Good to know there is a way to do this like below:
I may cast them too... I just thought you could use parser to post-process them. I think there is a value to what you proposed if u use
Sorry formatting in GitHub 3rd edit: Also, it would be nice if |
Hi, I did get the same error when I was trying to combine "step arguments" with "scenario outlines". Scenario Outline: Basic DuckDuckGo API Query
Given the DuckDuckGo API is queried with "<phrase>" using "json" format
Then the response status code is "200"
And the response contains results for "<phrase>"
Examples: Animals
| phrase |
| panda |
| python |
| platypus |
Examples: Fruits
| phrase |
| peach |
| pineapple |
| papaya | scenarios('../features/service.feature', example_converters=dict(phrase=str))
@given(parsers.parse('the DuckDuckGo API is queried with "<phrase>" using "{fmt}" format'))
def ddg_response(phrase, fmt):
params = {'q': phrase, 'format': fmt}
response = requests.get(DUCKDUCKGO_API, params=params)
return response
@then('the response contains results for "<phrase>"')
def ddg_response_contents(ddg_response, phrase):
assert phrase.lower() == ddg_response.json()['Heading'].lower()
@then(parsers.parse('the response status code is "{code:d}"'))
def ddg_response_code(ddg_response, code):
assert ddg_response.status_code == code Can anyone confirm if this is the way to do this or am I just lucky that it works as I want it? :) |
@Evolter I can confirm that Take this example: Scenario Outline: Animals are cute
Given a <animal>
When the <animal> is a baby
Then the <animal> is cute
Examples:
| animal |
| dog |
| cat |
Scenario: Some animals are cuter
Given a puppy
When the puppy is a baby
Then the puppy is cuter than cats In from behave import given, when, then
@given('a {}')
def step_impl(context, animal):
pass
@when('the {} is a baby')
def step_impl(context, animal):
pass
@then('the {} is cute')
def step_impl(context, animal):
pass
@then('the {} is cuter than {}')
def step_impl(context, animal, other_animal):
pass However, in from pytest_bdd import given, when, scenarios, then
from pytest_bdd.parsers import parse
scenarios('animals.feature')
@given(parse('a {animal}'))
@given('a <animal>')
def animal(animal):
pass
@when(parse('the {animal} is a baby'))
@when('the <animal> is a baby')
def animal_is_baby(animal):
pass
@then(parse('the {animal} is cute'))
@then('the <animal> is cute')
def animal_is_cute(animal):
pass
@then(parse('the {animal} is cuter than {other_animal}'))
def animal_is_cuter(animal, other_animal):
pass Personally I prefer the capabilities |
I have also found the above, which feels really silly to me. In addition to the syntactic ugliness of having to decorate evey step function twice, if you want it to work with a tabulated 'scenario outline' syntax in addition to the standlone 'scenario' syntax, it also doesn't properly respect parameter names. By this I mean you are forced to use the identical parameter names in your python step functions as is used in the outline. In my mind, this is unnecessary friction. For example, if a tester writes Scenario: SingleInput Validation
Given I am on the patient registration page
When I enter 12345 into mobilePhone
And I lose focus
Then I should see an error state on the mobilePhone field and Scenario Outline: Input Validation
Given I am on the patient registration page
When I enter <foo> into <field_name>
And I lose focus
Then I should see an error state on the <field_name> field
Examples:
| field_name | foo |
| mobilePhone | 01234 |
| homePhone | 12391 |
| email | rjiojr | and the step is defined as @when(parse("I enter {value} into {field_name}"))
@when("I enter <value> into <field_name>")
def enter_form_value(page_model: BasePage, value: str, field_name: str) -> None:
page_model.modify_form_field(field_name=field_name, value=value) .. then the second situation fails, as 'foo' is required in the signature of In my mind, the solution is for the scenario outline to "preprocess" the feature file before the individual lines are parsed. This would solve both problems: the proper parser decorator would work for everything, and the gherkin administrators can use any placeholder text for the dynamic aspects of the BDD. |
I will attempt to resolve this and make a PR. |
The tests demonstrate what I've done. Here you can see the given/when/then steps defined using the normal parse decorator. Note the parameter names: Now compare that to the syntax in the scenario outline. There is no longer a need for the names used in the outlines to be the same as the step functions' argument names. You are even free to define your steps completely separately, as long as they have a common syntax which matches! |
Spending some more time with this, I'm having second thoughts about whether the above PR is an overall step forward (pun intended). The issue is that if we implement the above, you then need to take a lot more care with the syntax of scenario outlines. For example. the following syntax will not work as cleanly, particularly if some of the parameters can be empty strings: given a <foo> <bar> <baz> you would need to add delimiters/quotes or similar to the BDD syntax to support this: given a '<foo>' '<bar>' '<baz>' ... which won't play nicely with quotes in the actual argument values. In short, the way I'm seeing it now, the price we would pay with my PR is probably too high to warrant it. |
Partly in response to this problem, I have started to make an alternative pytest plugin to support gherkin files. It attempts to address a few shortcomings of pytest-bdd, such as the problem of mixing steps in outlines and non-outlines. If you're interested in seeing the direction I am headed, take a look here: https://github.com/nicois/pytest-gherkin/tree/develop/tests |
Dear pytest-bdd team! |
This problem also affects our team.
|
Hi. New user here. I think I may be having a related issue. I have the following feature definition:
When I run:
I get the aforementioned How can I fix this? Thank you. |
I think you are missing |
Hey Guys,
I have a step in scenario outline:
In my glue code I write
@when(parsers.parse('thing {thing:d} is moved to position {position:d}'))
I when an error: pytest_bdd.exceptions.StepDefinitionNotFoundError: Step definition is not found: When
I tried When thing {thing} is moved to position {position}
When I use is passes it as a string. I though if I use parse I could make it an int. Is there some special way feature file has to be written?
The text was updated successfully, but these errors were encountered: