Generating Rich Test Reports with Pytest and Allure

Overview

Allure is a flexible, multi-language test reporting framework developed in Java. It integrates with Pytest, JavaScript, PHP, Ruby, and CI servers such as Jenkins to provide detailed execution logs, step traces, and aggregated statistics for both technical teams and management.

Installation and Environment Setup

Download the Allure command-line distribution, extract the archive, and add the bin directory to your system PATH. On Windows, the path might resemble:

C:\tools\allure-2.25.0\bin

Confirm the installation by checking the version:

allure --version

For Pytest suport, install the adapter package:

pip install allure-pytest

Core Annotations

@allure.step

Use step decorators to decompose test cases into discrete, visible operations within the report.

import allure

@allure.step("Initialize user session")
def setup_session():
    authenticate("qa_user", "token")
    load_profile()

allure.attach

Supplement results with logs, screenshots, or arbitrary files.

@allure.step("Execute checkout")
def run_checkout():
    allure.attach(
        body="Payment processed",
        name="gateway_log",
        attachment_type=allure.attachment_type.TEXT
    )
    confirm_order()

@allure.title and @allure.description

Add readable names and comprehensive explanasions to each test.

import pytest
import allure
from time import sleep

@allure.title("Validate search indexing")
@allure.description("""
Confirms that newly added inventory items
appear in search results within seconds.
""")
@pytest.mark.parametrize("sku", range(5))
class TestCatalogIndexing:
    @allure.story("Index refresh")
    def test_update_visible(self, search_client, sku):
        sleep(0.5)
        assert item_searchable(sku)

    def test_rank_position(self, search_client, sku):
        sleep(0.5)
        assert rank_exists(sku)

@allure.feature and @allure.story

Organize suites by capability and user scenario.

@allure.feature("Fulfillment Workflow")
class TestShippingLabels:

    @allure.story("Generate return label")
    def test_return_label_created(self):
        shipment = create_shipment()
        result = shipment.generate_return_label()
        assert result["label_url"].endswith(".pdf")

@allure.severity

Prioritize tests by business impact.

class ImpactLevel:
    BLOCKER = "blocker"
    CRITICAL = "critical"
    NORMAL = "normal"
    MINOR = "minor"
    TRIVIAL = "trivial"

@allure.severity(ImpactLevel.CRITICAL)
def test_login_with_valid_credentials():
    ...

Severity guidelines:

  • Blocker — Complete workflow interruption; application unresponsive.
  • Critical — Core functionality unavailable.
  • Normal — Standard functional defect.
  • Minor — UI deviation from specification.
  • Trivial — Typo, missing placeholder text, or cosmetic issue.

Report Generation

Execute the suite and store raw results:

pytest -n auto --alluredir=./allure-results

Launch the interactive HTML report:

allure serve ./allure-results

Customizing Report Metadata

Environment Properties

Create environment.properties inside the results directory to display build context:

Browser=Chrome
Browser.Version=123.0
Environment=Production
ApiUrl=https://api.example.com
Python.Version=3.12.1

Defect Categories

Add categories.json to classify failures automatically:

[
  {
    "name": "Ignored",
    "matchedStatuses": ["skipped"]
  },
  {
    "name": "Product Bug",
    "matchedStatuses": ["failed"]
  },
  {
    "name": "Automation Bug",
    "matchedStatuses": ["broken"]
  },
  {
    "name": "Infrastructure Failure",
    "matchedStatuses": ["broken", "failed"],
    "messageRegex": ".*ConnectionError.*"
  }
]

Fixing Empty Trend Graphs

If the Trends tab lacks historical data, copy the history folder from a previous allure-report output into allure-results before the next generatoin. This enables pass/fail trend visualization across consecutive builds.

Tags: pytest allure python test-automation reporting

Posted on Tue, 28 Jul 2026 16:10:07 +0000 by goldlikesnow