CtrlK
BlogDocsLog inGet started
Tessl Logo

testland/allure-testops-case-management

Author and manage Allure TestOps test cases via the REST API - create cases, manage projects + suites, attach scenarios with nested steps, link to Jira / GitHub issues, sync with allure-results from CI runs. Covers Bearer-token auth, /api/rs/testcase CRUD endpoints, nested-step `scenario` shape, and the unique Allure TestOps feature of linking automated results back to manual case definitions. Use for pre-execution case authoring in teams using Allure TestOps as the canonical TCM.

73

Quality

92%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Overview
Quality
Evals
Security
Files

SKILL.md

name:
allure-testops-case-management
description:
Author and manage Allure TestOps test cases via the REST API - create cases, manage projects + suites, attach scenarios with nested steps, link to Jira / GitHub issues, sync with allure-results from CI runs. Covers Bearer-token auth, /api/rs/testcase CRUD endpoints, nested-step `scenario` shape, and the unique Allure TestOps feature of linking automated results back to manual case definitions. Use for pre-execution case authoring in teams using Allure TestOps as the canonical TCM.

allure-testops-case-management

Overview

Allure TestOps (formerly Allure Server, by Qameta Software) combines test case management with the Allure reporting framework that automated tests already emit. The unique feature: automated tests' allure-results JSON link back to manual case definitions in the TCM, providing automation-coverage visibility at the case level.

Per docs.qameta.io/allure-testops (Cloudflare-protected; cite by stable URL).

For canonical anatomy, see test-case-anatomy-reference.

When to use

  • Authoring cases in teams already using Allure framework for automated reporting.
  • Linking automated test results to manual case definitions.
  • Migrating from a legacy TCM to Allure TestOps.
  • Backing test-case quality scans for Allure TestOps-using teams.

Authoring

Authentication

Allure TestOps uses Bearer tokens (API tokens generated per user):

export ATO_BASE="https://your-tenant.qatools.cloud"   # or self-hosted URL
export ATO_TOKEN="<api-token>"
import requests, os

BASE = os.environ["ATO_BASE"]
HEADERS = {
    "Authorization": f"Bearer {os.environ['ATO_TOKEN']}",
    "Content-Type": "application/json",
}

Create a test case

POST /api/rs/testcase:

def create_case(project_id, name, description=None, precondition=None,
                scenario_steps=None, status="Active", layer_id=None,
                feature_id=None):
    """
    scenario_steps: list of {"keyword": "Given|When|Then|And",
                              "name": "...", "expectedResult": "..."}
    status: Active / Outdated / Archived
    layer_id: testing layer (UI / API / Component / Unit) - discover via
              /api/rs/testlayer
    """
    body = {
        "projectId": project_id,
        "name": name,
        "description": description,
        "precondition": precondition,
        "status": status,
        "layerId": layer_id,
        "featureId": feature_id,
    }
    r = requests.post(f"{BASE}/api/rs/testcase", json=body, headers=HEADERS)
    r.raise_for_status()
    created = r.json()
    if scenario_steps:
        attach_scenario(created["id"], scenario_steps)
    return created

Scenario + nested steps

Allure TestOps' scenario shape supports nested steps (steps with sub-steps), uniquely among the five TCMs covered here:

def attach_scenario(case_id, steps):
    """
    steps: nested tree, e.g.,
      [
        {"keyword": "Given", "name": "User is logged in",
         "steps": [
           {"name": "Navigate to /login"},
           {"name": "Enter credentials"},
           {"name": "Submit form"},
         ]},
        {"keyword": "When", "name": "User clicks Checkout"},
        {"keyword": "Then", "name": "Order is placed",
         "expectedResult": "Confirmation page shows order ID"},
      ]
    """
    r = requests.post(
        f"{BASE}/api/rs/testcase/{case_id}/scenario",
        json={"steps": steps},
        headers=HEADERS,
    )
    r.raise_for_status()

Nested steps unlock BDD-style hierarchies and step-reuse.

Layers + features

# Discover layers in a project
layers = requests.get(f"{BASE}/api/rs/testlayer",
                      params={"projectId": project_id},
                      headers=HEADERS).json()
# [{"id": 1, "name": "API"}, {"id": 2, "name": "UI"}, ...]

# Discover features
features = requests.get(f"{BASE}/api/rs/feature",
                        params={"projectId": project_id},
                        headers=HEADERS).json()

Layers + features are how Allure TestOps organises cases (in addition to suites).

Link to issue tracker (Jira / GitHub / Linear)

Allure TestOps integrates with multiple trackers; configure the integration in the UI, then link a case to an issue:

def link_to_issue(case_id, integration_id, issue_key):
    r = requests.post(
        f"{BASE}/api/rs/testcase/{case_id}/issue",
        json={"integrationId": integration_id, "key": issue_key},
        headers=HEADERS,
    )
    r.raise_for_status()

Tags + custom fields

def set_tags(case_id, tag_names):
    r = requests.post(
        f"{BASE}/api/rs/testcase/{case_id}/tag",
        json={"tags": [{"name": t} for t in tag_names]},
        headers=HEADERS,
    )
    r.raise_for_status()

Tags can be key-value: tags = ["severity:critical", "team:checkout"].

Get + list

case = requests.get(f"{BASE}/api/rs/testcase/{case_id}",
                    headers=HEADERS).json()

# Paginated list
def list_cases(project_id, page_size=100):
    out = []
    page = 0
    while True:
        r = requests.get(f"{BASE}/api/rs/testcase",
                         params={"projectId": project_id,
                                 "page": page, "size": page_size},
                         headers=HEADERS)
        r.raise_for_status()
        data = r.json()
        out.extend(data.get("content", []))
        if data.get("last", False):
            break
        page += 1
    return out

Response shape: {"content": [...], "page", "totalPages", "totalElements", "last"}.

Running

Sync allure-results into manual cases

The unique Allure TestOps integration - link automated tests' results to manual case IDs:

# In your automated test (using allure-pytest, allure-junit, etc.):
import allure

@allure.testcase("ATO-1234")  # links to Allure TestOps case ID 1234
def test_checkout_flow():
    ...

When the CI run uploads allure-results to Allure TestOps, results auto-attach to the linked case. Coverage report shows which manual cases have automation backing.

Migration target field map

Source fieldAllure TestOps field
Titlename
Description / objectivedescription
Preconditionprecondition
Stepsscenario.steps (with optional nesting)
TypelayerId (UI / API / Component / Unit)
ComponentfeatureId
Statusstatus (Active / Outdated / Archived)
Severitytags or custom field
Prioritytags or custom field
Requirement traceability/testcase/{id}/issue

Parsing results

POST /testcase returns {"id", "name", "createdDate", "createdBy", ...}. Build permalink:

url = f"{BASE}/project/{project_id}/test-cases/{case_id}"

CI integration

Upload allure-results after every CI run; Allure TestOps ingests and links to manual cases by ID:

- name: Run tests with Allure
  run: pytest --alluredir=allure-results

- name: Upload to Allure TestOps
  env:
    ATO_TOKEN: ${{ secrets.ALLURE_TESTOPS_TOKEN }}
    ATO_BASE: ${{ vars.ALLURE_TESTOPS_BASE }}
    ATO_PROJECT_ID: ${{ vars.ATO_PROJECT_ID }}
  run: |
    allurectl upload allure-results \
      --endpoint $ATO_BASE \
      --token $ATO_TOKEN \
      --project-id $ATO_PROJECT_ID \
      --launch-name "CI run ${GITHUB_RUN_NUMBER}"

(allurectl is the official CLI; pip install allurectl.)

Anti-patterns

Anti-patternWhy it failsFix
Flat steps for hierarchical workflowsLoses Allure TestOps' nested-step advantageUse nested scenario.steps
No layer assignmentCoverage reports lose the UI/API/Unit splitAlways set layerId
Manual cases not linked to automationCoverage shows 0% even when tests existUse @allure.testcase("ATO-1234") decorator + sync
Tag-based severity / priority without conventionCross-team queries breakAdopt prefix convention (severity: / priority:)
Single project for everythingHard to navigateProject per product / service
Skipping allurectl for results uploadManual upload error-proneAlways use allurectl upload

Limitations

  • Less ubiquitous than TestRail / Xray. Hiring market for Allure TestOps users is smaller; tool-specific expertise may be scarce.
  • Tight coupling to Allure framework. Maximum value comes from using allure-pytest / allure-junit / allure-jest in tests; teams not using Allure framework miss the automation-linking story.
  • Self-hosted complexity. Allure TestOps can be self-hosted; Cloud version is more common but requires SaaS commitment.
  • Custom field discipline. Like other TCMs, tenants vary in how custom fields are used.

References

  • Allure TestOps docs - docs.qameta.io/allure-testops (Cloudflare-protected; cite by stable URL).
  • Allure TestOps REST API - docs.qameta.io/allure-testops/integrations/rest-api/.
  • allurectl CLI - github.com/allure-framework/allurectl.
  • Sibling references: test-case-anatomy-reference.
  • Sibling skills: testrail-case-management, xray-case-management, zephyr-scale-case-management, qase-io-case-management.
  • Sibling-plugin neighbour: allure-reports (in the qa-test-reporting plugin) - different scope (allure-results parser; not case repository).

SKILL.md

tile.json