I have the following test scenario:
Here is an example code to achieve that: Scenario:
@fixture.remove_edited_project
@web
Scenario: Edit a project data
Given Project was created with the following parameters
| project_name |
| my_project_to_edit |
When I edit the "my_project_to_edit" project
Then Project is edited
Step to save the data in some variable to be used in a teardown function(fixture):
@step('I edit the "{project_name}" project')
def step_impl(context, project_name):
# steps related to editing the project
# storing value in context variable to be used in fixture
context.edited_project_name = project_name
and an example fixture function to remove a project after scenario:
@fixture
def remove_edited_project(context):
yield
logging.info(f'Removing project: "{context.edited_project_name}"')
# Part deleting a project with name stored in context.edited_project_name
In such a configuration everything works fine and project is deleted by a fixture in any case(test failed or passed). Which is alright.
But, when I want to execute such a feature on a Feature level, means placing @fixture.remove_edited_project
decorator before Feature Keyword:
@fixture.remove_edited_project
Feature: My project Edit feature
, then this is not working. I know the reason already - the context.edited_project_name variable is cleaned after every scenario and it's no longer available for this fixture function later.
Is there any good way in passing a parameter somehow to a fixture on a feature level? Somehow globally? I was trying to use global variables as an option, but this started to be a bit dirty and problematic in this framework.
Ideally it would be to have something like @fixture.edited_project_name('my_project_to_edit')
Because the context gets cleaned of variables created during execution of the scenario you need a mechanism that persists through the feature. One way to do this would be to create a dictionary or other container in the context during setup of the fixture so that it will persist through the feature. The scenarios can set attributes or add to the container and because the dictionary was added during the feature, it will still exist during destruction of the fixture. E.g.,
@fixture
def remove_edited_project(context):
context.my_fixture_properties = {}
yield
logging.info(f'Removing project: "{context.my_fixture_properties['edited_project_name']}"')
@step('I edit the "{project_name}" project')
def step_impl(context, project_name):
# steps related to editing the project
# storing value in context variable to be used in fixture
context.my_fixture_properties['edited_project_name'] = project_name