The PR implements the missing parts of Allure API in Pytest-BDD. Check #726 for the complete list of the implemented API pieces.
API usage notes
To use Allure API, apply a decorator or call a runtime function (allure.dynamic.*, allure.attach, or allure.attach.file).
Allure decorators
General usage: apply decorators to a scenario test function:
@allure.id("1001")@allure.epic("My Epic")@allure.issue("https://github.com/allure-framework/allure-python/issues/726", name="Issue 726")@scenario("my_feature.feature", "My Scenario")deftest_scenario():
pass
Warning
It is important to put Allure decorators above @scenario. In other words, the following won't work:
@scenario("my_feature.feature", "My Scenario")@allure.epic("My Epic") # This decorator will be lostdeftest_scenario():
pass
Apply to whole modules
All Allure decorators except @allure.title and @allure.step are also proper pytest markers, which means they can be applied to the whole module via the pytestmark global variable.
pytestmark= [
allure.epic("My Epic"),
allure.link("https://allurereport.org", name="Homepage"),
]
@scenario("my_feature.feature", "My Scenario 1")deftest_scenario_1(): # Gets the epic and the linkpass@scenario("my_feature.feature", "My Scenario 1")deftest_scenario_2(): # Gets the epic and the link as wellpass
Note
Although pytest markers can also be defined at the class level, Pytest-BDD doesn't support defining scenario test functions inside a class (see pytest-dev/pytest-bdd#325).
The scenarios shortcut
Allure decorators can't be applied directly to test functions defined with the scenarios shortcut. But you have some options to tackle that.
Option 1 is to define separate test functions with the @scenario decorator and apply Allure decorators to them. Make sure all such functions are defined before scenarios is called:
# defines a test function for a specific scenario from the feature file and assigns an Allure ID to the function@allure.id("1001")@scenario("my_feature.feature", "A scenario with ID")deftest_scenario_with_id():
pass# defines test functions for all other scenarios from the feature filescenarios("my_feature.feature")
This works well for scenario-specific information like IDs, titles, descriptions, issue links, etc.
Option 2 is to use pytestmark as in one of the above examples:
pytestmark= [
allure.epic("My Epic"),
allure.link("https://allurereport.org", name="Homepage"),
]
# Defines test functions for all scenarios from the feature file. The functions are affected by all of the above markers.scenarios("my_feature.feature")
This is preferable for information that applies to many scenarios, like epics, general links, suites, tags, etc.
Option 3: call the runtime counterparts from a step function:
When possible, prefer Allure decorators over runtime functions. The decorators will affect the test results regardless of the outcome. On the other hand, the runtime function calls may be skipped because of failures in fixtures or preceding steps.
About @allure.title
When applied to a scenario function, @allure.title supports interpolation of outline arguments and pytest parameters:
Feature: My featureScenario Outline: My scenario outlineGiven step 1
Examples:
| outline_arg | | gherkin |
The Allure Runtime API functions can be called anytime between pytest_bdd_before_scenario and the last call to pytest_runtest_makereport for the current item. That includes step implementations, scenario test functions, and some pytest hooks:
Unlike its decorator counterpart, allure.dynamic.title always changes the test result's name. It never affects a step's name.
As in allure-pytest, no interpolation is supported: the caller must fully construct a value.
@given("my step")def_():
allure.dynamic.title("A new name") # updates the test's name; doesn't change the step's name
allure.attach and allure.attach.file
These functions add attachments to the innermost scope. If a step is running, the attachment will go to the current step. If no step is running, the attachment will be added to the test result.
allure.dynamic.parameter
This function always adds a new parameter to the test result. It neither changes the value or metadata of an existing parameter nor adds parameters to steps.
Pytest-BDD 8.0 features data tables and doc strings. This PR supports both arguments by converting them to the corresponding attachments. This implements #844.
This also works for older versions of Pytest-BDD. In the case of data tables, you should name the argument datatable and define a type converter. The converter must return the data table as list[list[str]]:
defparse_data_table(text) ->list[list[str]]:
return [
[x.strip() forxinline.split("|")]
forlinein (x.strip("|") forxintext.splitlines())
]
@given(parsers.parse("a step with a data table\\n{datatable:Datatable}", extra_types={"Datatable": parse_data_table}))def_(datatable):
pass
For doc strings, you should only name the argument docstring. The type converter (if used) must return str:
@given(parsers.parse('a step with a doc string\\n"""{docstring}"""'))def_(docstring):
pass
Feature and scenario descriptions
Feature and scenario descriptions from feature files are now shown as test result descriptions (separated by an empty line).
@allure.description and allure.dynamic.description overwrite these descriptions.
Step arguments
Arguments of a step implementation function are now shown as the step's parameters in the report.
Xfail support
Allure Pytest-BDD now correctly interprets expected failures:
A scenario with an expected failure is reported as skipped (this includes satisfied @pytest.mark.xfail markers and calls to pytest.xfail).
A scenario with an unsatisfied expected failure (XPASS) is reported as passed with the status details.
A scenario with an unsatisfied strict expected failure (XPASS(strict)) is reported as broken.
Broken status support
Scenarios/steps with unexpected errors are now reported as broken (with yellow). Scenarios/steps with failed assertions are still reported as failed (with red).
Link templates
Link templates are now supported via the --allure-link-pattern CLI option. The format is the same as for allure-pytest. You may put this option in your pytest configuration to automatically add it on each run. For example, in pyproject.toml:
If a value passed to an Allure link API is already a proper URL, no template is used. The value will be reported as is.
Pytest and gherkin tags
Argument-less pytest markers (except built-in markers) are now converted to Allure tags. Since Pytest-BDD implements gherkin tags as custom pytest markers, those are converted to tags as well.
Given the following feature file:
@fooFeature: My feature@barScenario: My scenarioGiven my step
And the following Python file:
@pytest.mark.baz@scenario("my_feature.feature", "My scenario")deftest_my_scenario():
pass
The test result will contain three tags: foo, bar, and baz.
Minor changes and fixes
Pytest parameter values now are not included in the default test result name (they are already visible next to the name)
Skipped teardowns now don't overwrite original statuses of scenarios (including passed)
Classifiers for packages are fixed to reflect the currently supported Python versions (from 3.8 to 3.13)
Add the Topic :: Software Development :: Testing :: BDD classifier to allure-pytest-bdd.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
The PR implements the missing parts of Allure API in Pytest-BDD. Check #726 for the complete list of the implemented API pieces.
API usage notes
To use Allure API, apply a decorator or call a runtime function (allure.dynamic.*, allure.attach, or allure.attach.file).
Allure decorators
General usage: apply decorators to a scenario test function:
Warning
It is important to put Allure decorators above @scenario. In other words, the following won't work:
Apply to whole modules
All Allure decorators except @allure.title and @allure.step are also proper pytest markers, which means they can be applied to the whole module via the pytestmark global variable.
Note
Although pytest markers can also be defined at the class level, Pytest-BDD doesn't support defining scenario test functions inside a class (see pytest-dev/pytest-bdd#325).
The scenarios shortcut
Allure decorators can't be applied directly to test functions defined with the scenarios shortcut. But you have some options to tackle that.
Option 1 is to define separate test functions with the @scenario decorator and apply Allure decorators to them. Make sure all such functions are defined before scenarios is called:
This works well for scenario-specific information like IDs, titles, descriptions, issue links, etc.
Option 2 is to use pytestmark as in one of the above examples:
This is preferable for information that applies to many scenarios, like epics, general links, suites, tags, etc.
Option 3: call the runtime counterparts from a step function:
Note
When possible, prefer Allure decorators over runtime functions. The decorators will affect the test results regardless of the outcome. On the other hand, the runtime function calls may be skipped because of failures in fixtures or preceding steps.
About @allure.title
When applied to a scenario function, @allure.title supports interpolation of outline arguments and pytest parameters:
The test result will be displayed as Outline arg: gherkin, pytest arg: pytest. You can read more about the syntax of replacement fields here.
Note
Fixture values currently can't be interpolated into scenario names.
When applied to a step implementation, @allure.title will update the step's name. The following stuff can be interpolated:
Example:
Here, the title will be Outline arg: gherkin, pytest arg: pytest, fixture value: fixture, prev step result: step-result, step arg: 2
This implements #737.
Runtime functions
The Allure Runtime API functions can be called anytime between pytest_bdd_before_scenario and the last call to pytest_runtest_makereport for the current item. That includes step implementations, scenario test functions, and some pytest hooks:
In conftest.py:
allure.dynamic.title
Unlike its decorator counterpart, allure.dynamic.title always changes the test result's name. It never affects a step's name.
As in allure-pytest, no interpolation is supported: the caller must fully construct a value.
allure.attach and allure.attach.file
These functions add attachments to the innermost scope. If a step is running, the attachment will go to the current step. If no step is running, the attachment will be added to the test result.
allure.dynamic.parameter
This function always adds a new parameter to the test result. It neither changes the value or metadata of an existing parameter nor adds parameters to steps.
The mode and excluded arguments work just like in pytest.
allure.step
Substeps can now be added with allure.step. It works just like in pytest.
Other changes
Data tables and doc strings
Pytest-BDD 8.0 features data tables and doc strings. This PR supports both arguments by converting them to the corresponding attachments. This implements #844.
This also works for older versions of Pytest-BDD. In the case of data tables, you should name the argument datatable and define a type converter. The converter must return the data table as list[list[str]]:
For doc strings, you should only name the argument docstring. The type converter (if used) must return str:
Feature and scenario descriptions
Feature and scenario descriptions from feature files are now shown as test result descriptions (separated by an empty line).
@allure.description and allure.dynamic.description overwrite these descriptions.
Step arguments
Arguments of a step implementation function are now shown as the step's parameters in the report.
Xfail support
Allure Pytest-BDD now correctly interprets expected failures:
Broken status support
Scenarios/steps with unexpected errors are now reported as broken (with yellow). Scenarios/steps with failed assertions are still reported as failed (with red).
Link templates
Link templates are now supported via the --allure-link-pattern CLI option. The format is the same as for allure-pytest. You may put this option in your pytest configuration to automatically add it on each run. For example, in pyproject.toml:
Note
If a value passed to an Allure link API is already a proper URL, no template is used. The value will be reported as is.
Pytest and gherkin tags
Argument-less pytest markers (except built-in markers) are now converted to Allure tags. Since Pytest-BDD implements gherkin tags as custom pytest markers, those are converted to tags as well.
Given the following feature file:
And the following Python file:
The test result will contain three tags: foo, bar, and baz.
Minor changes and fixes
Fixes #655
Closes #726
Closes #737
Closes #844
Checklist