Skip to main content

Uploading Test Results Using TestCollab CLI

Complete guide to using @testcollab/cli to create test plans and upload test results from any CI/CD pipeline — supports JUnit XML and Mochawesome JSON formats.

Updated today

Overview

The TestCollab CLI (@testcollab/cli) lets you create test plans and upload automated test results directly from your CI/CD pipeline. It supports two report formats:

  • JUnit XML — works with Java (JUnit, TestNG), Python (pytest), C# (NUnit, xUnit), Go, PHP, Robot Framework, and most other test frameworks

  • Mochawesome JSON — works with Cypress and Mocha-based frameworks

Installation

Requires Node.js 18+.

npm install -g @testcollab/cli

Or install as a dev dependency in your project:

npm install @testcollab/cli --save-dev
npx tc report ...

Authentication

The CLI authenticates using an API token. You can get your token from TestCollab → Account Settings → API Tokens.

Set it as an environment variable (recommended for CI/CD):

export TESTCOLLAB_TOKEN=your_api_token_here

Or pass it directly via flag:

tc report --api-key your_api_token_here ...

The --api-key flag takes precedence over the environment variable if both are set.

API Region

By default the CLI connects to https://api.testcollab.io (US region). If your account is on the EU region, pass:

--api-url https://api-eu.testcollab.io

Workflow: 3 Steps

The CLI follows a 3-step workflow in your CI pipeline:

  1. Create a test plantc createTestPlan creates a plan with tagged test cases and writes the plan ID to a file

  2. Run your tests — execute your test suite normally (Cypress, Playwright, pytest, JUnit, etc.)

  3. Upload resultstc report parses the result file and uploads it to the test plan

Step 1: Create Test Plan

tc createTestPlan \
  --project <project-id> \
  --ci-tag-id <tag-id> \
  --assignee-id <user-id>

Flag

Required

Description

--project

Yes

Your TestCollab project ID

--ci-tag-id

Yes

Tag ID — test cases with this tag are added to the plan

--assignee-id

Yes

User ID to assign the plan execution to

--api-key

No

API token (or set TESTCOLLAB_TOKEN env var)

--api-url

No

API base URL (defaults to US region)

This command creates a test plan and writes the plan ID to tmp/tc_test_plan in the format:

TESTCOLLAB_TEST_PLAN_ID=555

You can source this file in subsequent CI steps to get the plan ID.

Step 2: Run Your Tests

Run your test framework as usual. Make sure to output results in JUnit XML or Mochawesome JSON format. See the Supported Frameworks section below for specific commands.

Step 3: Upload Results

tc report \
  --project <project-id> \
  --test-plan-id <plan-id> \
  --format <mochawesome|junit> \
  --result-file <path-to-results>

Flag

Required

Description

--project

Yes

Your TestCollab project ID

--test-plan-id

Yes

Test plan ID (from Step 1)

--format

Yes

mochawesome or junit

--result-file

Yes

Path to the result file

--api-key

No

API token (or set TESTCOLLAB_TOKEN env var)

--api-url

No

API base URL (defaults to US region)

Test Case ID Mapping

For the CLI to match your test results to TestCollab test cases, include the test case ID in your test names using any of these patterns:

Pattern

Example Test Name

[TC-123]

[TC-42] Login should succeed

TC-123

TC-42 Login should succeed

id-123

Login should succeed id-42

testcase-123

Login should succeed testcase-42

All patterns are case-insensitive. The number after the prefix is the TestCollab test case ID.

Configuration Support

If your test plan uses multiple configurations (e.g., different browsers or environments), you can tag tests with a configuration ID:

  • Mochawesome: Use config-id-<id> as a top-level suite title

  • JUnit: Include config-id-<id> in the test case name or classname attribute

Results are grouped by configuration ID and matched to the correct execution in the test plan.

Supported Frameworks

Any framework that outputs JUnit XML or Mochawesome JSON works with the CLI. Here are common examples:

Framework

Output Command

Format

Cypress

Built-in mochawesome reporter

mochawesome

Playwright

--reporter=junit

junit

Jest

jest-junit package

junit

Pytest

--junitxml=results.xml

junit

JUnit 4/5

Native XML output

junit

TestNG

Native JUnit XML output

junit

NUnit / xUnit (.NET)

Native JUnit XML output

junit

Robot Framework

--xunit output.xml

junit

PHPUnit

--log-junit results.xml

junit

Go (go test)

go-junit-report

junit

Cucumber

JUnit formatter plugin

junit

WebdriverIO

@wdio/junit-reporter

junit

TestCafe

testcafe-reporter-junit

junit

Newman (Postman)

newman-reporter-junit

junit

CI/CD Examples

GitHub Actions

name: Tests
on:
  push:
    branches: [main]
jobs:
  test:
    runs-on: ubuntu-latest
    env:
      TESTCOLLAB_TOKEN: ${​{ secrets.TESTCOLLAB_TOKEN }​}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
      - run: npm install -g @testcollab/cli && npm ci
      - name: Create test plan
        run: |
          tc createTestPlan \
            --project ${​{ secrets.TC_PROJECT_ID }​} \
            --ci-tag-id ${​{ secrets.TC_CI_TAG_ID }​} \
            --assignee-id ${​{ secrets.TC_ASSIGNEE_ID }​}
      - name: Load test plan ID
        run: cat tmp/tc_test_plan >> $GITHUB_ENV
      - name: Run tests
        run: npx playwright test --reporter=junit --output=results.xml
      - name: Upload results
        if: always()
        run: |
          tc report \
            --project ${​{ secrets.TC_PROJECT_ID }​} \
            --test-plan-id $TESTCOLLAB_TEST_PLAN_ID \
            --format junit \
            --result-file ./results.xml

GitLab CI

test:
  image: node:22
  variables:
    TESTCOLLAB_TOKEN: $TESTCOLLAB_TOKEN
  script:
    - npm install -g @testcollab/cli && npm ci
    - tc createTestPlan --project $TC_PROJECT_ID --ci-tag-id $TC_CI_TAG_ID --assignee-id $TC_ASSIGNEE_ID
    - source tmp/tc_test_plan
    - npx playwright test --reporter=junit --output=results.xml
    - tc report --project $TC_PROJECT_ID --test-plan-id $TESTCOLLAB_TEST_PLAN_ID --format junit --result-file ./results.xml

Jenkins (Pipeline)

pipeline {
  agent any
  environment {
    TESTCOLLAB_TOKEN = credentials('testcollab-token')
    TC_PROJECT_ID = '42'
    TC_CI_TAG_ID = '10'
    TC_ASSIGNEE_ID = '5'
  }
  stages {
    stage('Setup') {
      steps {
        sh 'npm install -g @testcollab/cli && npm ci'
      }
    }
    stage('Create Plan') {
      steps {
        sh "tc createTestPlan --project ${TC_PROJECT_ID} --ci-tag-id ${TC_CI_TAG_ID} --assignee-id ${TC_ASSIGNEE_ID}"
        script {
          env.TESTCOLLAB_TEST_PLAN_ID = sh(script: "grep -oP '(?<=TESTCOLLAB_TEST_PLAN_ID=).*' tmp/tc_test_plan", returnStdout: true).trim()
        }
      }
    }
    stage('Test') {
      steps {
        sh 'npx playwright test --reporter=junit --output=results.xml'
      }
    }
    stage('Report') {
      steps {
        sh "tc report --project ${TC_PROJECT_ID} --test-plan-id ${TESTCOLLAB_TEST_PLAN_ID} --format junit --result-file ./results.xml"
      }
    }
  }
}

Azure DevOps

trigger:
  - main
pool:
  vmImage: 'ubuntu-latest'
steps:
  - task: NodeTool@0
    inputs:
      versionSpec: '22.x'
  - script: npm install -g @testcollab/cli && npm ci
    displayName: Install dependencies
  - script: |
      tc createTestPlan \
        --project $(TC_PROJECT_ID) \
        --ci-tag-id $(TC_CI_TAG_ID) \
        --assignee-id $(TC_ASSIGNEE_ID)
    displayName: Create test plan
    env:
      TESTCOLLAB_TOKEN: $(TESTCOLLAB_TOKEN)
  - script: |
      source tmp/tc_test_plan
      echo "##vso[task.setvariable variable=TESTCOLLAB_TEST_PLAN_ID]$TESTCOLLAB_TEST_PLAN_ID"
    displayName: Load test plan ID
  - script: npx playwright test --reporter=junit --output=results.xml
    displayName: Run tests
  - script: |
      tc report \
        --project $(TC_PROJECT_ID) \
        --test-plan-id $(TESTCOLLAB_TEST_PLAN_ID) \
        --format junit \
        --result-file ./results.xml
    displayName: Upload results
    condition: always()
    env:
      TESTCOLLAB_TOKEN: $(TESTCOLLAB_TOKEN)

Bitbucket Pipelines

pipelines:
  default:
    - step:
        name: Run Tests & Upload Results
        image: node:22
        script:
          - npm install -g @testcollab/cli && npm ci
          - tc createTestPlan --project $TC_PROJECT_ID --ci-tag-id $TC_CI_TAG_ID --assignee-id $TC_ASSIGNEE_ID
          - source tmp/tc_test_plan
          - npx playwright test --reporter=junit --output=results.xml
          - tc report --project $TC_PROJECT_ID --test-plan-id $TESTCOLLAB_TEST_PLAN_ID --format junit --result-file ./results.xml

Troubleshooting

Common Errors

Error

Solution

TESTCOLLAB_TOKEN not set

Set the TESTCOLLAB_TOKEN environment variable or pass --api-key

Project not found

Check the project ID and ensure your API token has access

Tag not found

Verify the tag ID belongs to the specified project

Result file not found

Check the path to your result file is correct

No <testcase> elements found

Your JUnit XML file may be empty or malformed

Warnings

Warning

Meaning

X testcase(s) missing TestCollab ID

Some test names don't include a recognized ID pattern (TC-123, id-123, etc.)

X testcase ID(s) not found in assigned executed cases

The test case ID exists but isn't assigned to the specified user in the plan

Prerequisites Checklist

Before setting up the CLI in your pipeline, make sure you have:

  1. A TestCollab API token (from Account Settings → API Tokens)

  2. Your project ID (visible in the project URL or settings)

  3. A tag applied to the test cases you want to include in CI runs (note the tag ID)

  4. The assignee user ID for the pipeline executions

  5. Test case IDs embedded in your test names (e.g., [TC-42] Login test)

Did this answer your question?