allure-reports
Skill2 starsChanged 3 months agoMITView on GitHub
Production-grade skill for generating rich test reports with Allure. Covers pytest, Behave, JUnit, annotations, attachments, steps, CI/CD integration, and custom categories.
- Installs packages
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 50
Test cases grouped by suite, feature, and story
- Very specific: line 603
Place this in allure-results/ before report generation:
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Allure Reports Skill
Description
Comprehensive skill for generating rich, interactive test reports with Allure. Covers integration with Python (pytest, Behave), Java (JUnit), annotations for metadata, step-by-step traceability, attachments (screenshots, logs, files), custom categories, and CI/CD integration (Jenkins, GitHub Actions).
Table of Contents
- Overview
- Installation & Setup
- Pytest Integration
- Behave Integration
- JUnit Integration
- Annotations & Metadata
- Steps & Nested Steps
- Attachments
- Report Generation
- CI/CD Integration
- Custom Categories
- Best Practices Checklist
- Common Pitfalls
- References
When to Invoke
- Setting up Allure reporting for a test suite (pytest, Behave, JUnit, Cypress)
- Annotating tests with features, stories, severity, and labels
- Adding screenshots, logs, or files to test reports
- Implementing step-by-step traceability in test methods
- Configuring custom defect categories in Allure
- Integrating Allure into Jenkins, GitLab CI, or GitHub Actions
- Generating and serving Allure reports locally or in CI
- Troubleshooting missing attachments or empty reports
1. Overview
Allure is a flexible, lightweight multi-language test report tool. It produces interactive HTML reports with:
- Test cases grouped by suite, feature, and story
- Step-by-step execution trace
- Attachments (screenshots, logs, network captures)
- Severity levels, tags, and links to issues/PRs
- Trends and history across builds
- Custom defect categories (e.g., "Product Defect" vs "Test Defect")
Supported Frameworks
| Language | Framework | Adapter |
| Python | pytest | allure-pytest |
| Python | Behave | allure-behave |
| Java | JUnit 4 | allure-junit4 |
| Java | JUnit 5 | allure-junit5 |
| JavaScript | Cypress | @shelex/cypress-allure-plugin |
2. Installation & Setup
Python (pytest)
pip install allure-pytestPython (Behave)
pip install allure-behaveJava (Maven)
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-junit5</artifactId>
<version>2.25.0</version>
<scope>test</scope>
</dependency>Allure Command-Line Tool
# macOS
brew install allure
# Windows (Scoop)
scoop install allure
# Linux
wget https://github.com/allure-framework/allure2/releases/download/2.25.0/allure-2.25.0.tgz
tar -xzf allure-2.25.0.tgz
sudo mv allure-2.25.0 /opt/allure
sudo ln -s /opt/allure/bin/allure /usr/local/bin/allureVerify Installation
allure --version3. Pytest Integration
pytest.ini
[pytest]
addopts = --alluredir=reports/allure-resultsBasic Test with Annotations
import allure
import pytest
@allure.feature("User Management")
@allure.story("Create User")
@allure.severity(allure.severity_level.CRITICAL)
@allure.title("Verify user creation with valid data")
@allure.description("This test validates that a new user can be created via the API.")
def test_create_user(api_client):
with allure.step("Send POST request to /users"):
response = api_client.post("/users", json={"name": "John", "email": "john@test.com"})
with allure.step("Verify response status is 201"):
assert response.status_code == 201
with allure.step("Verify response contains user ID"):
assert "id" in response.json()Fixtures with Allure Steps
@pytest.fixture
def authenticated_client():
with allure.step("Authenticate test user"):
client = ApiClient()
client.login("testuser", "password123")
yield client
with allure.step("Logout and cleanup"):
client.logout()Dynamic Titles and Descriptions
@allure.title("Dynamic title: {param1} + {param2}")
@pytest.mark.parametrize("param1,param2", [(1, 2), (3, 4)])
def test_dynamic_title(param1, param2):
allure.dynamic.title(f"Custom title for {param1} and {param2}")
allure.dynamic.description("This description was set at runtime.")
assert param1 + param2 > 0Labels and Links
@allure.label("owner", "qa-team")
@allure.label("layer", "api")
@allure.link("https://jira.example.com/PROJ-123", name="JIRA-123")
@allure.issue("https://bugzilla.example.com/456", name="BUG-456")
def test_with_metadata():
pass4. Behave Integration
behave.ini
[behave]
format=allure_behave.formatter:AllureFormatter
outfiles=reports/allure-resultsFeature File with Tags
@allure.feature.user_management
@allure.story.create_user
Feature: User Management
@allure.severity.critical
@allure.label.owner:qa_team
Scenario: Create a new user
Given the API is available
When I send a POST request to /users with valid data
Then the response status should be 201
And the response should contain a user IDEnvironment Hooks with Allure
# features/environment.py
import allure
from allure_commons.types import AttachmentType
def before_scenario(context, scenario):
allure.dynamic.feature("User Management")
allure.dynamic.story(scenario.name)
def after_step(context, step):
if step.status == "failed":
if hasattr(context, "browser"):
screenshot = context.browser.get_screenshot_as_png()
allure.attach(
screenshot,
name="Failure Screenshot",
attachment_type=AttachmentType.PNG
)Attachments in Steps
# features/steps/api_steps.py
import allure
from allure_commons.types import AttachmentType
import json
@when('I send a POST request to {endpoint} with valid data')
def step_send_post(context, endpoint):
payload = {"name": "Test User", "email": "test@example.com"}
allure.attach(
json.dumps(payload, indent=2),
name="Request Payload",
attachment_type=AttachmentType.JSON
)
context.response = context.client.post(endpoint, json=payload)
allure.attach(
json.dumps(context.response.json(), indent=2),
name="Response Body",
attachment_type=AttachmentType.JSON
)5. JUnit Integration
JUnit 5 Example
import io.qameta.allure.*;
import org.junit.jupiter.api.Test;
@Feature("User Management")
@Story("Create User")
@Severity(SeverityLevel.CRITICAL)
@Owner("qa-team")
@Link(name = "JIRA-123", url = "https://jira.example.com/PROJ-123")
public class UserTest {
@Step("Send POST request to /users")
public Response createUser(String name, String email) {
return apiClient.post("/users", Map.of("name", name, "email", email));
}
@Test
@Title("Verify user creation with valid data")
@Description("This test validates that a new user can be created.")
public void testCreateUser() {
Response response = createUser("John", "john@test.com");
Assertions.assertEquals(201, response.getStatusCode());
}
@Attachment(value = "Request Payload", type = "application/json")
public byte[] attachRequestPayload(String payload) {
return payload.getBytes();
}
}6. Annotations & Metadata
Severity Levels
| Level | Use Case |
BLOCKER | Critical functionality broken; blocks release |
CRITICAL | Core feature failure |
NORMAL | Standard test |
MINOR | Edge case or cosmetic issue |
TRIVIAL | Documentation or typo check |
Python Decorators
@allure.feature("Feature Name")
@allure.story("Story Name")
@allure.severity(allure.severity_level.CRITICAL)
@allure.title("Custom test title")
@allure.description("Detailed description")
@allure.description_html("<b>HTML</b> description")
@allure.tag("regression", "smoke")
@allure.label("owner", "qa-team")
@allure.label("layer", "ui")
@allure.link("https://docs.example.com", name="Documentation")
@allure.issue("https://jira.example.com/PROJ-456", name="PROJ-456")
@allure.testcase("https://testrail.example.com/C123", name="TestRail C123")Dynamic Annotations (Runtime)
def test_dynamic_metadata():
allure.dynamic.feature("Dynamic Feature")
allure.dynamic.story("Dynamic Story")
allure.dynamic.title("Dynamic Title")
allure.dynamic.description("Set at runtime based on conditions.")
allure.dynamic.label("owner", "dynamic-owner")7. Steps & Nested Steps
Python (pytest)
import allure
def test_with_steps():
with allure.step("Step 1: Prepare test data"):
user = {"name": "Alice", "email": "alice@example.com"}
with allure.step("Step 2: Execute API call"):
with allure.step("Step 2.1: Send request"):
response = api.post("/users", json=user)
with allure.step("Step 2.2: Verify response"):
assert response.status_code == 201
with allure.step("Step 3: Verify database state"):
db_user = db.query(User).filter_by(email="alice@example.com").first()
assert db_user is not NoneDecorator Style (Python)
@allure.step("Create user with name={name} and email={email}")
def create_user(name: str, email: str):
return api.post("/users", json={"name": name, "email": email})
def test_using_step_function():
response = create_user("Bob", "bob@example.com")
assert response.status_code == 201Java (JUnit)
@Step("Verify user exists in database: {email}")
public void verifyUserInDatabase(String email) {
User user = userRepository.findByEmail(email);
assertNotNull(user);
}8. Attachments
Python Attachments
import allure
from allure_commons.types import AttachmentType
import json
def test_with_attachments(browser):
# Screenshot
allure.attach(
browser.get_screenshot_as_png(),
name="Homepage Screenshot",
attachment_type=AttachmentType.PNG
)
# JSON payload
allure.attach(
json.dumps({"user": "test", "role": "admin"}, indent=2),
name="Request Body",
attachment_type=AttachmentType.JSON
)
# Log file
allure.attach.file(
"/var/log/app.log",
name="Application Log",
attachment_type=AttachmentType.TEXT
)
# Plain text
allure.attach(
"This is a plain text attachment",
name="Notes",
attachment_type=AttachmentType.TEXT
)Attachment Types
| Type | Constant |
| PNG image | AttachmentType.PNG |
| JPEG image | AttachmentType.JPG |
| JSON | AttachmentType.JSON |
| XML | AttachmentType.XML |
| HTML | AttachmentType.HTML |
| Plain text | AttachmentType.TEXT |
| CSV | AttachmentType.CSV |
| URI | AttachmentType.URI |
Java Attachments
@Attachment(value = "Screenshot", type = "image/png")
public byte[] takeScreenshot() {
return ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
}
@Attachment(value = "Page Source", type = "text/html")
public String attachPageSource() {
return driver.getPageSource();
}9. Report Generation
Generate Results
# pytest
pytest --alluredir=reports/allure-results
# Behave
behave -f allure_behave.formatter:AllureFormatter -o reports/allure-results
# JUnit (Maven)
mvn clean test allure:reportServe Report (Local Development)
allure serve reports/allure-resultsGenerate Static HTML
allure generate reports/allure-results -o reports/allure-report --cleanReport Structure
reports/
allure-results/ # Raw JSON data (commit to CI artifacts)
allure-report/ # Generated HTML (do not commit)10. CI/CD Integration
GitHub Actions
# .github/workflows/tests.yml
name: Tests with Allure
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install allure-pytest
- name: Run tests
run: pytest --alluredir=reports/allure-results
- name: Generate Allure Report
if: always()
run: |
allure generate reports/allure-results -o reports/allure-report --clean
- name: Upload Report
if: always()
uses: actions/upload-artifact@v4
with:
name: allure-report
path: reports/allure-reportJenkins
pipeline {
agent any
stages {
stage('Test') {
steps {
sh 'pytest --alluredir=reports/allure-results'
}
}
}
post {
always {
allure([
includeProperties: false,
jdk: '',
properties: [],
reportBuildPolicy: 'ALWAYS',
results: [[path: 'reports/allure-results']]
])
}
}
}GitLab CI
stages:
- test
- report
test:
stage: test
script:
- pytest --alluredir=allure-results
artifacts:
when: always
paths:
- allure-results/
allure:
stage: report
image: frankescobar/allure-docker-service
script:
- allure generate allure-results -o allure-report --clean
artifacts:
paths:
- allure-report/11. Custom Categories
Allure categorizes failures by default into "Product defects" and "Test defects". You can customize this.
categories.json
Place this in allure-results/ before report generation:
[
{
"name": "Infrastructure Issues",
"matchedStatuses": ["broken"],
"messageRegex": ".*Connection refused.*"
},
{
"name": "Known Flaky Tests",
"matchedStatuses": ["failed"],
"messageRegex": ".*TimeoutException.*"
},
{
"name": "Validation Errors",
"matchedStatuses": ["failed"],
"traceRegex": ".*AssertionError.*"
}
]Environment Properties
# environment.properties
Browser=Chrome 120
OS=Ubuntu 22.04
Test.Environment=Staging
API.Version=v2.1Executor Info
{
"name": "jenkins",
"type": "jenkins",
"url": "http://jenkins.example.com",
"buildOrder": 42,
"buildName": "build #42",
"buildUrl": "http://jenkins.example.com/job/42",
"reportUrl": "http://jenkins.example.com/job/42/allure",
"reportName": "Allure Report"
}12. Best Practices Checklist
- Every test has a
@featureand@storyannotation - Severity is assigned based on business impact (
BLOCKER>CRITICAL>NORMAL) - Steps describe actions, not assertions (
"Click login"not"Verify login works") - Attach screenshots on UI test failures
- Attach request/response bodies for API test failures
- Attach logs when a test breaks (not just fails)
- Use dynamic annotations for parameterized tests
- Link tests to JIRA/Trello/TestRail tickets
- Label tests by layer (
ui,api,unit) for filtering - Use
@allure.title()for human-readable test names - Keep
allure-results/as CI artifacts for history - Generate reports with
--cleanto avoid stale data - Add
environment.propertiesfor context (browser, OS, API version) - Use
categories.jsonto group failures by root cause - Do not commit generated HTML reports to version control
- Use nested steps for complex workflows (login → navigate → perform action)
- Set
allure.descriptionorallure.description_htmlfor complex test logic
13. Common Pitfalls
| Problem | Cause | Solution |
| Empty report | No allure-results data or wrong path | Check --alluredir path matches allure serve path |
| Missing screenshots | Attachment after test failure | Add screenshot in after_step or on_exception hook |
| Duplicate test names | Same @title across parameterized tests | Use dynamic title with parameter values |
| Broken links in report | Relative paths or missing categories.json | Use absolute URLs in @link and provide categories.json |
| Report not showing history | Missing allure-results from previous runs | Persist allure-results between CI builds |
| Steps not visible | Missing with allure.step() or wrong import | Ensure import allure and use context manager |
| Large report size | Too many screenshots/videos | Compress images or attach only on failure |
| Attachments not opening | Wrong attachment_type | Use correct AttachmentType constant |
| CI report not generated | allure CLI not installed | Install CLI tool in CI image or use Docker |
| Flaky test categories missing | No categories.json in results | Copy categories.json before report generation |
14. References
- Allure Framework
- Allure pytest
- Allure Behave
- Allure JUnit 5
- Allure Cypress
- Allure CLI
- Related skills:
behave-bdd,python-testing-patterns,java-junit,playwright-best-practices,cypress-author
In this repository45 other files it gives its agents.
- AGENTS.mdAGENTS.md
- android-nativeSkill
- appian-lowcodeSkill
- appium-mobileSkill
- behave-bddSkill
- BiDiWave Cross-BrowserSkill
- BiDiWave Network InterceptionSkill
- CDPWave DebuggingSkill
- CDPWave TestingSkill
- db2-oracleSkill
- ebook-writerSkill
- flask-apiSkill
- flet-desktopSkill
- google-crawling-indexingSkill
- google-ranking-appearanceSkill
- google-seo-fundamentalsSkill
- google-seo-monitoringSkill
- jinja2-templatesSkill
- jmeter-load-testingSkill
- k6-load-testingSkill
- karate-api-testingSkill
- octane-almSkill
- paramiko-sshSkill
- postman-api-automationSkill
- prestashop-moduleSkill
- prompt-engineering-best-practicesSkill
- pytest-advancedSkill
- robot-frameworkSkill
- salesforce-devSkill
- sonarqube-quality-gatesSkill
- sql-serverSkill
- Skill NameSkill
- testcontainersSkill
- wave-ecosystem-guideSkill
- WaveXis AccessibilitySkill
- WaveXis CI/CD IntegrationSkill
- wavexis-cli-automationSkill
- wavexis-mcp-agent-integrationSkill
- WaveXis Network TestingSkill
- WaveXis Performance AuditSkill
- WaveXis Session RecordingSkill
- WaveXis Web ScrapingSkill
- webdriverioSkill
- wordpress-themesSkill
- xctest-iosSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

