# pytest reporter

Source: https://docs.qualflare.com/docs/reporters/pytest · Last updated: 2026-10-29

Install the qualflare-pytest plugin with pip, set options in pytest.ini or pyproject.toml, and upload the qualflare-results folder with the Qualflare CLI.

`qualflare-pytest` is the Qualflare reporter for pytest 7.0 or later on Python 3.9 or later: the plugin writes each run's results, with per-attempt retries, steps and attachments, to `qualflare-results`, and `qf <identifier> collect` uploads the folder as one launch.

| Fact                 | Detail                                                                                                    |
| -------------------- | --------------------------------------------------------------------------------------------------------- |
| Package              | [`qualflare-pytest`](https://pypi.org/project/qualflare-pytest/) on PyPI                                  |
| Works with           | pytest 7.0 or later, Python 3.9 or later                                                                  |
| qf                   | (requires qf 0.1.24 or later) for file attachments                                                        |
| License              | Apache-2.0                                                                                                |
| Source               | [Qualflare/qualflare-pytest](https://github.com/Qualflare/qualflare-pytest) on GitHub                     |
| Without the reporter | `--format python` with [pytest's `--junitxml` report](https://docs.qualflare.com/docs/cli/formats#python) |

## Before you begin

* The Qualflare CLI, `qf`: [Install the CLI](https://docs.qualflare.com/docs/cli/installation).
* A saved login: `qf login <identifier>` with a project access token whose creator still holds the project role that uploads need (requires the Editor role or higher in the project) ([Authenticate with qf login](https://docs.qualflare.com/docs/cli/authentication)).
* The **Identifier** of the environment the results belong to ([Environments](https://docs.qualflare.com/docs/runs/environments#identifier)).

## Install

```bash
pip install qualflare-pytest
```

The plugin registers itself when installed: there is no `-p` flag to add. `qf` is a separate binary, not a Python package: [install it](https://docs.qualflare.com/docs/cli/installation) with Homebrew, npm or a release binary.

## Configure

In `pytest.ini`:

```ini
[pytest]
qualflare_environment = staging
qualflare_output_dir = qualflare-results
```

or in `pyproject.toml`:

```toml
# pyproject.toml
[tool.pytest.ini_options]
qualflare_environment = "staging"
```

The plugin reads `pytest.ini`, `pyproject.toml`, `setup.cfg` and `tox.ini`.

| Option | Type | Default | Required | Description |
| --- | --- | --- | --- | --- |
| `qualflare_environment` | `string` | `development` | No | The environment's Identifier. Variable `QUALFLARE_ENVIRONMENT`. |
| `qualflare_output_dir` | `string` | `qualflare-results` | No | Point every shard at the same folder. Variable `QUALFLARE_OUTPUT_DIR`. |
| `qualflare_platform` | `string` | `api` | No | One of `api`, `web`, `desktop`, `android`, `ios`. Variable `QUALFLARE_PLATFORM`. |
| `qualflare_enabled` | `boolean` | `true` | No | false writes no report. Variable `QUALFLARE_ENABLED`. |

Every reporter shares the other settings: see [Reporter configuration](https://docs.qualflare.com/docs/reporters/configuration).

Set `qualflare_environment` to the environment's Identifier: a name such as `Staging` fails the upload with HTTP 400 ([Environment](https://docs.qualflare.com/docs/reporters/configuration#environment)).

## Run and upload

```bash
pytest
qf <identifier> collect ./qualflare-results
```

## Run in CI

```yaml
- name: Upload results to Qualflare
  if: ${{ !cancelled() }}
  env:
    QF_TOKEN: ${{ secrets.QF_TOKEN }}
    QF_BRANCH: ${{ github.head_ref || github.ref_name }}
    QF_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
  run: |
    npm install -g @qualflare/cli
    qf login ci --force
    qf ci collect ./qualflare-results
```

`if: ${{ !cancelled() }}` uploads the results when tests fail, and `QF_BRANCH` and `QF_COMMIT` record a pull request's own branch and commit ([Pull request branches](https://docs.qualflare.com/docs/cli/ci-cd#pull-request-branches)). For GitLab CI/CD, Jenkins and Azure Pipelines, see [Run the upload when tests fail](https://docs.qualflare.com/docs/cli/ci-cd#run-when-tests-fail).

## Sharding and retries

`pytest -n auto` works with no configuration: the controller writes one report for the whole run, and each test's xdist worker becomes its shard index.

`pytest-rerunfailures` is supported: every attempt's status and error is uploaded.

For shards that run as separate CI jobs, see [Merge sharded CI jobs into one launch](https://docs.qualflare.com/docs/cli/sharding#merge-sharded-ci-jobs).

## What gets uploaded

* Each test's status, with its per-attempt retry history and flakiness
* Steps and attachments
* Labels, links, tags, priority and parameters

Markers such as `@pytest.mark.smoke` become tags, and with `pytest-bdd` installed, Gherkin steps keep their keyword and location.

```python
import os
from qualflare_pytest import qualflare

def test_checks_out():
    qualflare.label("feature", "checkout")

    with qualflare.step("add to cart"):
        qualflare.parameter("sku", "widget")
        qualflare.parameter("token", os.environ["TOKEN"], masked=True)
```

## Troubleshooting

* `xfail` and `xpass` upload as skipped and passed; under `xfail(strict=True)` an unexpected pass reads as a pass.
* `record_property` is ignored: use `qualflare.parameter()` or `qualflare.label()`.
* Captured stdout and stderr aren't attached: attach what you need.
* `environment "Staging" does not exist in this project`: use the environment's Identifier, or pass `--environment` on the upload ([Environment](https://docs.qualflare.com/docs/reporters/configuration#environment)).
* Screenshots can't be downloaded: `qf` is older than 0.1.24. [Upgrade qf](https://docs.qualflare.com/docs/cli/installation#upgrading).

## Related

* **Guides:** [Reporters](https://docs.qualflare.com/docs/reporters) · [Upload results with qf collect](https://docs.qualflare.com/docs/cli/collect) · [Sharded runs and result directories](https://docs.qualflare.com/docs/cli/sharding) · [Upload screenshots, videos and traces](https://docs.qualflare.com/docs/cli/artifacts)
* **Reference:** [Reporter configuration](https://docs.qualflare.com/docs/reporters/configuration) · [pytest format](https://docs.qualflare.com/docs/cli/formats#python)
* **More:** [pytest test reporting in Qualflare](https://qualflare.com/pytest-test-reporting/)
