---
title: Pytest-BDD reference
description: Reference documentation for Allure Pytest-BDD integration | Create attachments
---

# Allure Pytest-BDD reference

These are the attributes and methods that you can use to integrate your Pytest-BDD tests with Allure Report.

## Parametrized tests

In Gherkin, a [`Scenario Outline`](https://pytest-bdd.readthedocs.io/en/stable/#scenario-outlines) (or a `Scenario Template`) implements the [parametrized tests](/docs/v2/readability/#parametrized-tests) pattern. A scenario outline must contain an `Examples` table, from which Pytest-BDD loads sets of parameters, one row after another. Each set of parameters is being placed into the step declarations according to the placeholders, thus generating a new scenario based on the row. Pytest-BDD then runs each of them independently, as if it was a separate `Scenario`. The data can then be captured by Pytest-BDD and passed as separate arguments to the Python code.

Allure Pytest-BDD automatically recognizes this pattern. No additional configuration is required.

The example below shows a Gherkin file and a Python implementation file of a test. In this example, the four parameters for the “I enter my details...” step will be displayed in both instances of the scenario in the test report.

```gherkin
Feature: User management

  Scenario Outline: Registration
    When I go to the registration form
    And I enter my details: <login>, <password>, <name>, <birthday>
    Then the profile should be created

    Examples:
      | login   | password | name     | birthday   |
      | johndoe | qwerty   | John Doe | 1970-01-01 |
      | janedoe | 123456   | Jane Doe | 1111-11-11 |
```

```python
from pytest_bdd import given, parsers, scenario, then, when

@scenario('features/UserManagement.feature', 'Registration')
def test_parameters():
    pass

@when('I go to the registration form')
def i_go_to_registration_form():
    ...

@when(parsers.parse('I enter my details: {login}, {password}, {name}, {birthday}'))
def i_enter_my_details(login, password, name, birthday):
    ...

@then('the profile should be created')
def profile_should_be_created():
    ...
```

## Attaching content from variables

- `allure.attach(body, name=None, attachment_type="text/plain", extension="attach")`

Add `body` as an attachment to the test result under the given `name` (defaults to a unique pseudo-random string). The `body` must be of type `bytes` or `str`.

To ensure that the reader's web browser will display attachments correctly, it is recommended to specify each attachment's type. There are two ways to do this:

- Pass the media type of the content as `attachment_type` and, optionally, a filename extension as `extension`.

  Some popular media types are `image/png` and `image/jpeg` for screenshots and other images, `application/json` for JSON data, and `text/plain` for text files. The media type affects how the data will be displayed in the test report, while the filename extension is appended to the filename when user wants to save the file.

- Pass a value from the `allure.attachment_type` class as `attachment_type`.

  This will automatically set the media type and the appropriate filename extension.

```python
import allure
import requests
from pytest_bdd import then

@then("I open labels page")
def test_labels():
    ...
    png_bytes = requests.get('https://example.com/image.png').content
    allure.attach(png_bytes, name="my-image", attachment_type=allure.attachment_type.PNG)
```

## Reading attachments from files

- `allure.attach.file(source, name=None, attachment_type=None, extension=None)`

Same as [`attach()`](#attaching-content-from-variables), but the content is loaded from the existing `source` file.

```python
import allure
from pytest_bdd import then

@then("I open labels page")
def test_labels():
    ...
    allure.attach.file('/path/to/image.png', name="my-image", attachment_type=allure.attachment_type.PNG)
```
