# allure-python: adapters that turn Python test runs into Allure reports

> allure-python is a monorepo of adapters that let Python test frameworks write Allure results, covering pytest, pytest-bdd, behave, nose2 and Robot Framework on top of a shared commons engine. It is a reporting layer rather than a test runner, and each framework plugs into it differently.

**allure-framework/allure-python** — Allure integrations for Python test frameworks

- Repository: https://github.com/allure-framework/allure-python
- Website: https://allurereport.org/
- Stars: 820 · Forks: 262
- Language: Python
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/allure-framework-allure-python

## A monorepo of adapters around one common engine

The repository holds adapters for Python based test frameworks, and the top level layout makes the structure obvious: allure-pytest, allure-pytest-bdd, allure-behave, allure-robotframework, allure-nose2, allure-python-commons and allure-python-commons-test, plus a tests/ directory, requirements/ and a shared pyproject.toml.

At the base sits allure-python-commons, described as the common engine for all modules and stated to be useful for making an integration with your own homemade frameworks. That is the part worth understanding first, because it explains why the other packages are thin. The commons package holds the result model and the writing logic, and each adapter is responsible for translating its framework's events into that model.

The sibling package allure-python-commons-test is a pack of Hamcrest matchers for validating results in the allure2 JSON format. That is a small detail with a large implication: the format is a contract, and the project ships matchers so that a custom integration can be tested against it rather than eyeballed.

The distribution model is per framework. Each adapter has its own PyPI package, allure-pytest, allure-behave, allure-robotframework, allure-pytest-bdd and allure-nose2, which means a project installs only the one it needs rather than the whole suite.

## pytest and pytest-bdd arrive as plugins

The pytest integration is developed as a pytest plugin and distributed via PyPI as allure-pytest, and pytest-bdd is handled the same way through allure-pytest-bdd. Both follow the standard plugin contract, so they are enabled by being installed rather than by configuration.

The plugin model has a consequence that anyone building their own test tooling needs to know. Pytest discovers plugins automatically, and the repository's own configuration reflects that reality by disabling it during its own runs. The pytest section of the shared pyproject.toml sets the environment variable PYTEST_DISABLE_PLUGIN_AUTOLOAD to true for the test task, and the pytest ini options add the flags that turn the two Allure plugins off:

```toml
addopts = [
    "-p", "no:allure_pytest",
    "-p", "no:allure_pytest_bdd"
]
```

That is the project avoiding its own adapter interfering with the tests that check the adapter. For an adopter it is a warning worth heeding, since a plugin that loads in every environment can change collection behaviour in ways that are hard to trace back to it.

## behave is a formatter, Robot Framework is a listener

The other two integrations hook into their frameworks differently, and the difference is not cosmetic.

The behave integration is described as just an external formatter that produces test results in the allure2 format. Behave has a formatter concept, so the adapter slots into the existing pipeline rather than replacing it. The output is the same allure2 format the other adapters write.

The Robot Framework integration is a Listener and, the README stresses, does not require changing the autotests. Robot Framework's listener interface is the extension point, and the adapter uses it to observe the run rather than to take it over. That is the least invasive integration in the set and the one that works best with an existing suite written for other tooling.

The nose2 integration, allure-nose2, is listed without further description, and the pytest-bdd integration is likewise a pytest plugin, but the key difference is the suite format it understands: pytest-bdd describes scenarios and steps, and the Allure model has its own vocabulary for steps and attachments, so a BDD style suite maps onto the report differently from a flat function test suite.

Each package in the repository also carries an examples directory, so the intended usage for every adapter is demonstrated rather than described.

## Producing results and rendering a report

The pipeline has two halves and they are separate pieces of software. The adapters produce allure2 JSON results into a directory, and a separate command line tool turns that directory into a report.

The repository's own task definitions show the shape of it. Collecting results runs pytest with the Allure plugin loaded, an output directory and a clean of that directory, plus a link pattern that turns an issue reference in a test name into a link into the tracker:

```bash
pytest -p allure_pytest --alluredir ./.allure-results --clean-alluredir --allure-link-pattern issue:https://github.com/allure-framework/allure-python/issues/{0}
```

Generating and viewing the report are two more tasks:

```bash
allure generate --clean --output ./.allure-report ./.allure-results
allure open ./.allure-report
```

The allure binary itself is not part of this repository, so it has to be present in the environment that runs those tasks. In CI that usually means a container image with the Allure command line tool alongside Python.

The output is a directory of static files. Allure Report is a browser application that loads that directory, which is why the project hosts a live demo at demo.allurereport.org and why the documentation lives at allurereport.org with the official documentation under the docs path.

## Building the adapters themselves

The repository uses Poe to define its tasks, which keeps the commands in the shared pyproject.toml rather than in shell scripts.

The task list covers the obvious work. linter runs ruff check. tests runs pytest with plugin autoload disabled as described earlier. allure-collect runs the pytest collection with the Allure plugin, the results directory and the issue link pattern. allure-generate and allure-open wrap the two Allure commands, and the reports land in ./.allure-report and ./.allure-results in the working tree.

The linting setup is small and deliberate. Ruff is configured with a line length of 120 and a rule selection of flake8-builtins, pycodestyle errors, pyflakes, flake8-quotes and pycodestyle warnings, with two explicit exclusions for paths under the behave acceptance test data.

The pytest configuration pins the test path to the tests directory and disables the two Allure plugins in addopts, which is the pattern the project itself follows and the one an adopter copying this repository would inherit.

Versioning is shared across the packages. The recent releases 2.16.0 dated 2026-04-27, 2.16.1 dated 2026-09-18 and 2.16.2 dated 2026-09-29 apply to the integration set as a whole, so the adapters move together and a mixed set of versions in one environment is not a state the project intends.

## Where allure-python is the wrong tool

Three situations point elsewhere.

If you only need a pass or fail signal in CI, this is a lot of machinery for the job. The alternative is the JUnit XML that pytest and the other runners can emit natively, consumed directly by the CI system's own test tab. The difference in approach is that JUnit XML is a fixed schema that the CI platform already understands, while Allure writes a richer allure2 JSON format with steps, attachments and history, and then needs the separate Allure command line tool to turn it into something a human reads. Richer output, extra step.

Second, if you run a framework that has no adapter here, you are in the commons package territory. The README states that allure-python-commons is the common engine and is useful for making an integration with your homemade frameworks, so writing an adapter is a supported path, but it is work you now own rather than work the maintainers do.

Third, the report is a directory of files that has to be published somewhere for anyone to read. That is a deployment problem the format does not solve, and for a team with no place to host static artifacts the JUnit XML path into the existing CI dashboard is the cheaper answer.

One more constraint comes from the packaging itself. Each adapter is a separate PyPI package with its own release line, and they are versioned together, so a team that pins versions should pin the whole set rather than mixing an old allure-pytest with a new allure-behave.

## Conclusion

Adopt allure-python if your team already runs pytest, behave, pytest-bdd or Robot Framework and wants a browsable report with attachments and history instead of a bare pass and fail log, and if you are willing to add the Allure command line tool to your CI image. Do not adopt it for a quick script that only needs to know whether the suite passed, since the report generation is an extra tool and an extra artifact. Verify three things first: that the adapter matches the framework you actually run, because behave is an external formatter and Robot Framework is a listener while pytest and pytest-bdd are plugins with different configuration surfaces; that plugin autoloading in your CI environment does not pick up an adapter you did not intend, which is why the repository's own test tasks disable plugin autoload; and how you will serve the generated report, since the output is a directory of static files. The licence is Apache-2.0, the last push was on 2026-10-10, and the newest release is 2.16.2 dated 2026-09-29.

## FAQ

### What does allure-python contain?

It contains adapters for Python test frameworks: allure-pytest and allure-pytest-bdd as pytest plugins, allure-behave as an external formatter, allure-robotframework as a Robot Framework listener, and allure-nose2. They share the allure-python-commons engine, and allure-python-commons-test ships Hamcrest matchers for validating allure2 JSON results.

### How do I produce an Allure report from pytest?

Run pytest with the Allure plugin loaded and an output directory, for example pytest -p allure_pytest --alluredir ./.allure-results --clean-alluredir, then run allure generate --clean --output ./.allure-report ./.allure-results and allure open ./.allure-report. The allure command line tool is a separate installation.

### Does the behave integration need changes to my feature files?

The behave adapter is described as just an external formatter that produces test results in the allure2 format, so it fits into behave's existing formatter mechanism rather than replacing it. The Robot Framework adapter is a listener and the README states that it does not require changing the autotests.

### What licence does allure-python use?

Apache-2.0, so it can be used in commercial and open source projects under its terms. The Allure Report ecosystem is documented at allurereport.org and a live report is hosted at demo.allurereport.org.

### Can I write my own Allure adapter for a custom framework?

Yes. The README describes allure-python-commons as the common engine for all modules and says it is useful for making an integration with your own homemade frameworks, and allure-python-commons-test provides Hamcrest matchers for validating results in the allure2 JSON format.

## Sources

- [allure-framework/allure-python on GitHub](https://github.com/allure-framework/allure-python)
- [License: Apache-2.0](https://github.com/allure-framework/allure-python/blob/master/LICENSE)
- [Project website](https://allurereport.org/)
- [README](https://github.com/allure-framework/allure-python/blob/master/README.md)
- [Releases](https://github.com/allure-framework/allure-python/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/allure-framework-allure-python
