Help Center/Automation & CI/CD/Your CI provider

Jenkins: Publish JUnit Test Results to TestCollab

Generate a JUnit XML report in Jenkins and publish test results to TestCollab with @testcollab/cli.

Publish JUnit test results from a Jenkins Pipeline to TestCollab with @testcollab/cli. The pipeline creates a TestCollab plan, runs the automated tests, reports their results, and then lets Jenkins retain the same JUnit XML.

This integration does not require a TestCollab Jenkins plugin. For CLI installation and workflow options, see TestCollab CLI: Install and First Run.

The core workflow is createTestPlan → tests → report. Build traceability and quality gating are separate, optional extensions.

Prerequisites

  • A Jenkins agent with Node.js 18 or newer and npm available.
  • A repository whose npm test command runs Jest.
  • jest-junit installed as a development dependency.
  • A TestCollab project with a CI tag applied to the automated cases.
  • The TestCollab project ID, tag ID, and assignee user ID.
  • A TestCollab API token belonging to the assignee.
npm install --save-dev jest-junit

Store the API token in Jenkins

  1. Open Manage Jenkins > Credentials.
  2. Add the TestCollab API token as a Secret text credential.
  3. Set its credential ID to testcollab-token, or update the Jenkinsfile to match your chosen ID.

If you need a token, follow Getting an API Token generated. Do not place the token directly in the Jenkinsfile.

Complete declarative Jenkinsfile

This Jenkinsfile preserves the test exit status while still uploading failed results. It assumes the Jenkins agent already provides Node.js 18 or newer.

pipeline {
  agent any

  environment {
    TESTCOLLAB_TOKEN = credentials('testcollab-token')
    TC_PROJECT_ID = '123'
    TC_CI_TAG_ID = '45'
    TC_ASSIGNEE_ID = '67'
    TC_API_URL = 'https://api.testcollab.io'
  }

  stages {
    stage('Install dependencies') {
      steps {
        sh 'npm ci'
      }
    }

    stage('Test and report') {
      steps {
        sh '''
          set -e

          npx @testcollab/cli createTestPlan \
            --project "$TC_PROJECT_ID" \
            --ci-tag-id "$TC_CI_TAG_ID" \
            --assignee-id "$TC_ASSIGNEE_ID" \
            --api-url "$TC_API_URL"

          . tmp/tc_test_plan
          mkdir -p test-results

          set +e
          JEST_JUNIT_OUTPUT_DIR=./test-results \
          JEST_JUNIT_OUTPUT_NAME=results.xml \
            npm test -- --ci --reporters=default --reporters=jest-junit
          TEST_EXIT=$?

          npx @testcollab/cli report \
            --project "$TC_PROJECT_ID" \
            --test-plan-id "$TESTCOLLAB_TEST_PLAN_ID" \
            --format junit \
            --result-file ./test-results/results.xml \
            --api-url "$TC_API_URL"
          REPORT_EXIT=$?
          set -e

          if [ "$REPORT_EXIT" -ne 0 ]; then
            exit "$REPORT_EXIT"
          fi
          exit "$TEST_EXIT"
        '''
      }
    }
  }

  post {
    always {
      junit allowEmptyResults: true,
        testResults: 'test-results/results.xml'
      archiveArtifacts allowEmptyArchive: true,
        artifacts: 'test-results/results.xml'
    }
  }
}

The Jenkins JUnit step is only for Jenkins' own test view. TestCollab receives the result through tc report, so both systems can use the same XML.

How the Jenkins pipeline works

  1. The credentials helper exposes the Secret text value as TESTCOLLAB_TOKEN during the build.
  2. createTestPlan creates a plan from the CI-tagged cases and writes its ID to tmp/tc_test_plan.
  3. The shell loads the plan ID, runs Jest, and saves Jest's status.
  4. tc report uploads the JUnit results to the matching TestCollab executions.
  5. The shell returns a reporting failure first, otherwise the original test status. Failed assertions therefore keep the Jenkins build failed.
  6. The declarative post { always { ... } } block publishes and archives the XML after passing or failing stages.

Use a Jenkins freestyle project

Set the five variables from the Jenkinsfile in the job environment, then add this as an Execute shell step after checkout:

set -e
npm ci

npx @testcollab/cli createTestPlan \
  --project "$TC_PROJECT_ID" \
  --ci-tag-id "$TC_CI_TAG_ID" \
  --assignee-id "$TC_ASSIGNEE_ID" \
  --api-url "$TC_API_URL"

. tmp/tc_test_plan
mkdir -p test-results

set +e
JEST_JUNIT_OUTPUT_DIR=./test-results \
JEST_JUNIT_OUTPUT_NAME=results.xml \
  npm test -- --ci --reporters=default --reporters=jest-junit
TEST_EXIT=$?

npx @testcollab/cli report \
  --project "$TC_PROJECT_ID" \
  --test-plan-id "$TESTCOLLAB_TEST_PLAN_ID" \
  --format junit \
  --result-file ./test-results/results.xml \
  --api-url "$TC_API_URL"
REPORT_EXIT=$?
set -e

if [ "$REPORT_EXIT" -ne 0 ]; then
  exit "$REPORT_EXIT"
fi
exit "$TEST_EXIT"

Map Jenkins results with [TC-42]

Include the TestCollab case ID in each result-producing test title. Matching is case-insensitive and supports [TC-42], TC-42, id-42, and testcase-42.

test('[TC-42] customer can sign in', async () => {
  // Test steps and assertions
});

The case must be part of the plan created from the CI tag and assigned to the API token owner.

Use another JUnit runner

Replace the Jest command with your framework's JUnit command, then keep one combined XML path consistent in tc report, junit, and archiveArtifacts.

# Playwright
PLAYWRIGHT_JUNIT_OUTPUT_NAME=test-results/results.xml \
  npx playwright test --reporter=junit

# pytest
pytest --junitxml=test-results/results.xml

tc report accepts one file per command. Merge a directory of Surefire or parallel-runner XML files before uploading.

Optional build traceability and quality gates

Once reporting is working, you can optionally record a deployed build and link the plan to its version. You can separately run a quality gate after tc report. Neither one is required, and you do not need to adopt both.

Use the EU region

For an EU account, change TC_API_URL in the Jenkinsfile or freestyle environment to:

https://api-eu.testcollab.io

Troubleshooting

npx or Node.js is not found

Install Node.js 18 or newer on the Jenkins agent and make it available on the build user's PATH. The TestCollab CLI does not require a Jenkins-specific plugin.

No API key provided

Confirm testcollab-token is a Secret text credential visible to the job. If you use a different credential ID, update credentials('testcollab-token').

The JUnit publisher finds no files

Confirm the reporter creates test-results/results.xml. Use the same path in the test command, tc report, and Jenkins junit step.

The TestCollab cases remain unexecuted

Inspect the JUnit <testcase name> values for [TC-42]. Confirm the case is selected by the CI tag and assigned to the token owner.

Last updated 2026-08-26.