Skip to main content

Result Upload

The CLI ships three result-upload commands that share a single workflow:

qasphere junit-upload [options] <files..>
qasphere playwright-json-upload [options] <files..>
qasphere allure-upload [options] <directories..>

All three match test results to existing QA Sphere test cases using markers in the test name (or framework-specific annotations) and upload them as a new or existing test run.

For language- and framework-specific setup, see the per-framework guides:

Supported report formats and framework coverage​

The CLI is language- and framework-agnostic. It speaks three report formats, with JUnit XML acting as the universal lingua franca:

  • JUnit XML (junit-upload) — supported by virtually every test framework across every language. If your tool can produce JUnit-style XML, the CLI can upload it.
  • Playwright JSON (playwright-json-upload) — Playwright's native JSON report. Adds support for test annotations as a more reliable matching method than markers in test names.
  • Allure (allure-upload) — Allure results directories (*-result.json). Adds TMS link matching for test case linking.

The CLI itself ships as an npm package, but it does not require your project to be JavaScript:

LanguageFrameworks / tools
JavaScript / TypeScriptPlaywright, Cypress, Jest, Mocha, WebdriverIO, Vitest
Pythonpytest, unittest, Robot Framework
Java / KotlinJUnit 4/5, TestNG, Selenium, Appium
Gogo test (with -v and go-junit-report)
C# / .NETNUnit, xUnit, MSTest
Rustcargo test (with cargo2junit)
RubyRSpec, Minitest
PHPPHPUnit

If your stack isn't listed but can emit JUnit XML, Playwright JSON, or Allure results, it works.

Upload modes​

Each command supports two modes:

  • Upload into an existing run — pass -r, --run-url <url> pointing at a QA Sphere run. The project code and run ID are extracted from the URL.
  • Create a new run — omit --run-url. Use --project-code, --run-name, and --create-tcases to control how the run is created.
# Upload into an existing run
qasphere junit-upload -r https://qas.eu1.qasphere.com/project/PRJ/run/23 ./test-results.xml

# Create a new run automatically
qasphere junit-upload ./test-results.xml

# Create a new run with explicit project and run name
qasphere junit-upload --project-code PRJ --run-name "v1.4.4-rc5" ./test-results.xml

Options​

All three upload commands share the same option surface.

OptionDescription
-r, --run-url <url>URL of an existing test run to upload into. Project code and run ID are extracted from the URL.
--project-code <code>Project code for creating a new run (when --run-url is not set). Can be auto-detected from markers, but explicit is recommended.
--run-name <template>Name template for the new test run. Supports {env:VAR} and date placeholders. Default: "Automated test run - {MMM} {DD}, {YYYY}, {hh}:{mm}:{ss} {AMPM}"
--create-tcasesCreate new test cases in QA Sphere for results that have no valid marker. Generates a mapping file (qasphere-automapping-YYYYMMDD-HHmmss.txt). Only applies when creating a new run.
--attachmentsDetect and upload file attachments (screenshots, videos, traces) alongside each result.
--forceIgnore API request errors, invalid test case mappings, or attachment problems and continue uploading.
--ignore-unmatchedSuppress individual unmatched-test messages; show a summary count only.
--skip-report-stdout <when>When to skip stdout from test results. Choices: on-success, never (default).
--skip-report-stderr <when>When to skip stderr from test results. Choices: on-success, never (default).
--verboseShow full stack traces on errors.
-h, --helpShow command help.

Run-name template placeholders​

The --run-name option supports the following placeholders. It is only honored when creating a new run (i.e. when --run-url is not set).

PlaceholderDescription
{env:VAR_NAME}Environment variable value
{YYYY}, {YY}4-digit / 2-digit year
{MMM}3-letter month (Jan, Feb, …)
{MM}2-digit month
{DD}2-digit day
{HH}2-digit hour, 24-hour format
{hh}2-digit hour, 12-hour format
{mm}, {ss}Minutes / seconds
{AMPM}AM/PM indicator

Example:

qasphere junit-upload \
--project-code PRJ \
--run-name "CI Build {env:BUILD_NUMBER} - {YYYY}-{MM}-{DD}" \
./test-results.xml

With BUILD_NUMBER=v1.4.4-rc5 on 2026-01-01, this produces a run named CI Build v1.4.4-rc5 - 2026-01-01.

Test case matching​

Results are linked to QA Sphere test cases via markers. The CLI checks them in the order shown below and falls back to the next format if a result doesn't match.

JUnit XML​

JUnit XML supports three marker styles, checked in order:

  1. Hyphenated marker (all languages): PROJECT-SEQUENCE anywhere in the test name. PROJECT is your project code; SEQUENCE is the test case number (minimum 3 digits, zero-padded if needed). Matched case-insensitively.

    • PRJ-002: Login with valid credentials
    • Login with invalid credentials: PRJ-1312
  2. Underscore-separated hyphenless marker (pytest, Go, Rust, …): for languages where hyphens aren't allowed in test names. The test name must start with test (case-insensitive).

    • test_prj002_login_with_valid_credentials
    • test_login_with_invalid_credentials_prj1312
  3. CamelCase hyphenless marker (Go, Java): detected at the start (after the Test prefix) or end of the name. The test name must start with Test (case-insensitive).

    • TestPrj002LoginWithValidCredentials
    • TestLoginWithValidCredentialsPrj1312

Playwright JSON​

Playwright JSON supports two methods, checked in order:

  1. Test annotations (recommended) — add a Playwright test annotation with type: "test case" (case-insensitive) and the full QA Sphere test case URL as description:

    test(
    'user login',
    {
    annotation: {
    type: 'test case',
    description: 'https://qas.eu1.qasphere.com/project/PRJ/tcase/123',
    },
    },
    async ({ page }) => {
    // test code
    }
    )
  2. Hyphenated marker in the test name — same PROJECT-SEQUENCE format as JUnit. Hyphenless markers are not supported for Playwright JSON.

Allure​

Allure results use one *-result.json file per test in a results directory. allure-upload matches via:

  1. TMS links (recommended) — links[] entries with:
    • type: "tms"
    • url: QA Sphere test case URL, e.g. https://qas.eu1.qasphere.com/project/PRJ/tcase/123
  2. TMS link name fallback — if url is not a QA Sphere URL, the marker in links[].name is used (e.g. PRJ-123)
  3. Marker in name — same PROJECT-SEQUENCE format as JUnit

Only Allure JSON result files (*-result.json) are supported. Legacy Allure 1 XML files are ignored.

If a result has no marker

If markers are missing, the upload fails by default. Use --create-tcases to automatically create test cases in QA Sphere for unmatched results, or --ignore-unmatched / --force to bypass the mismatch without creating them.

Run-level logs​

The CLI automatically detects global or suite-level failures (typically setup/teardown issues that aren't tied to a specific test case) and uploads them as run-level logs:

  • JUnit XML — suite-level <system-err> elements and empty-name <testcase> entries with <error> or <failure> (e.g. Maven Surefire's synthetic entries for setup/teardown failures).
  • Playwright JSON — top-level errors[] entries (global setup/teardown failures).
  • Allure — failed or broken befores / afters fixtures in *-container.json files (e.g. pytest session/module-level setup/teardown failures).

Common examples​

# Upload with attachments
qasphere junit-upload --attachments ./test1.xml

# Force upload even with missing test cases or attachments
qasphere junit-upload --force ./test-results.xml

# Suppress per-test unmatched messages (gradual test-case linking)
qasphere junit-upload --ignore-unmatched ./test-results.xml

# Skip stdout for passed tests to reduce payload size
qasphere junit-upload --skip-report-stdout on-success ./test-results.xml

# Allure upload into an existing run
qasphere allure-upload -r https://qas.eu1.qasphere.com/project/P1/run/23 ./allure-results

# Continue Allure upload when some *-result.json files are malformed
qasphere allure-upload --force -r https://qas.eu1.qasphere.com/project/P1/run/23 ./allure-results