ScreenshotNeo

BlogHow-to

How to Generate Automated Test Reports with Jenkins

Run your tests, publish their result files in Jenkins, and choose the right publisher for JUnit XML, other formats, or HTML reports.

By the ScreenshotNeo team4 October 20268 min read

To generate automated test reports with Jenkins, configure your test runner to write report files, then publish those files from a Pipeline. For JUnit XML, the usual Declarative Pipeline approach is the junit step in post { always { ... } }. Jenkins records and displays results; it does not run your test framework or create reports that the framework did not produce.

Use the publisher that matches the files your test runner actually writes:

  • JUnit-style XML: use Jenkins’ junit step for the test results UI, failure tracking, and trends.
  • Another supported test format: use a format-specific publisher, such as xUnit or NUnit.
  • An HTML report already generated by a tool: use the HTML Publisher plugin. It publishes the HTML; it does not convert JUnit XML into HTML.

Jenkins’ official guide describes recording and aggregating results when the test runner can output result files. See Recording tests and artifacts.

1. Publish JUnit XML from a Declarative Pipeline

First, make sure the test command writes JUnit-compatible XML into the workspace. Then set testResults to an Ant-style glob that matches those files and only those files. This complete example runs a Gradle check and publishes XML under build/reports:

pipeline {
    agent any

    stages {
        stage('Test') {
            steps {
                sh './gradlew check'
            }
        }
    }

    post {
        always {
            junit 'build/reports/**/*.xml'
        }
    }
}

Change both the test command and the glob to match your project. For example, a Maven project might write Surefire results under target/surefire-reports; in that case, use a matching pattern such as target/surefire-reports/TEST-*.xml. Confirm the actual output path in your test runner’s configuration or by inspecting the workspace.

The always post condition attempts publication after the stage completes, including when the test command fails. This is useful because a failed test run can still have results worth reviewing. It cannot publish files that were never created, were written outside the workspace, or were deleted before the post action runs.

Choose a precise result pattern

The JUnit step accepts an Ant-style glob in testResults. Recursive patterns such as **/TEST-*.xml can cover multiple module directories, but broad patterns can accidentally include unrelated XML. Jenkins’ reference specifically cautions against including non-report files. Start with the narrowest pattern that covers the test runner’s output, then expand it only if the project has multiple report directories.

Runner output location Example pattern Check
One known directory build/test-results/test/*.xml Does the runner use this directory for the current job?
Nested module directories **/build/test-results/**/*.xml Could another module or tool place unrelated XML there?
Maven Surefire reports target/surefire-reports/TEST-*.xml Does the command run Surefire and leave reports in the workspace?

JUnit XML is also used by TestNG. The XML dialect and runner configuration still matter: verify that the generated files are compatible with the publisher, and do not assume every file with an .xml extension is a test report. See the JUnit Pipeline step reference and the JUnit plugin page.

2. Configure result handling deliberately

The basic junit call is enough for many pipelines. The plugin also offers controls for missing results, build and stage status, output retention, and optional SCM checks. These options affect whether a report problem is visible and how much diagnostic data Jenkins retains. Confirm option availability and syntax against the plugin version installed on your controller.

Missing or empty reports

By default, a missing matching report is an error. That makes a bad path or a test runner that stopped producing results visible. The allowEmptyResults option changes that behavior:

junit testResults: 'build/reports/**/*.xml', allowEmptyResults: true

Use allowEmptyResults: true only when no reports is an expected outcome for that job. It can otherwise hide a broken glob, skipped test task, or failed report generation. A safer first step is to fix the path or configure the runner to write results even when tests fail.

Build and stage status on test failures

JUnit failures normally make the build and pipeline stage unstable while leaving the report available. The step has separate controls for suppressing instability at the build or stage level. Use them only if your CI policy intentionally treats reported failures differently from the normal unstable signal. Suppressing that signal can make failing tests less visible to downstream jobs and people monitoring the pipeline.

For example, the step supports settings such as skipMarkingBuildUnstable and skipMarkingStageUnstable in applicable plugin versions. Do not copy these into a pipeline without deciding which status your team expects and checking the installed plugin reference.

Retain test output based on its diagnostic value

The plugin’s stdioRetention setting supports all, failed, and none. Retaining output can make failures easier to investigate, but long test output can substantially increase Jenkins memory use. Choose the smallest retention level that gives your team enough detail, and use full output only when its troubleshooting value justifies the cost.

Optional SCM checks

The JUnit plugin can publish results to supported source-control checks integrations when the required integration is installed and configured. For GitHub, the plugin documentation describes using the GitHub Checks Plugin and GitHub App credentials; it also documents an option to disable checks publishing. This is an optional integration, not required for Jenkins’ own test results page. Check the plugin versions and SCM configuration on your controller before following version-specific setup steps.

3. Publish an existing HTML test report

Use HTML Publisher when your test tool already creates an HTML report directory and you want to browse that report from a Jenkins build. Install and configure the HTML Publisher plugin, then use its publishHTML Pipeline step. Paths are relative to the workspace.

pipeline {
    agent any

    stages {
        stage('Test') {
            steps {
                sh './gradlew testReport'
            }
        }
    }

    post {
        always {
            publishHTML(target: [
                allowMissing: false,
                alwaysLinkToLastBuild: true,
                keepAll: true,
                reportDir: 'build/reports/tests/test',
                reportFiles: 'index.html',
                reportName: 'Test Report'
            ])
        }
    }
}

Replace ./gradlew testReport, reportDir, and reportFiles with the command and paths used by your reporting tool. The example keeps reports for successful builds with keepAll: true. Set it to false if retaining a report for every successful build is unnecessary. Set allowMissing deliberately: allowing a missing report can be appropriate for optional output, but can conceal a broken report-generation step.

The HTML report is separate from the JUnit results view. If you want Jenkins to track test counts and trends, publish compatible XML with junit as well. The HTML Publisher Pipeline reference documents the step and its options.

4. Use a publisher for the format your runner emits

If your runner does not emit JUnit-style XML, select a publisher that understands its format. Jenkins documents Pipeline steps for xUnit and NUnit. The exact configuration depends on the plugin and report format; consult its reference rather than passing non-JUnit files to junit.

What you have Use What it gives you
JUnit-compatible XML junit Jenkins test results, failures, and trends
A supported non-JUnit test report format A matching publisher, such as xUnit or NUnit Parsing for that report format, subject to plugin support
An HTML report generated by the test tool HTML Publisher A Jenkins link to the rendered report
No report files Configure the test runner first The publisher alone cannot create test results

5. Troubleshoot missing or misleading results

Symptom Likely cause Fix
Jenkins reports no test results or says the pattern found no files The glob does not match the runner’s actual output, or the files are outside the workspace. Inspect the workspace after the test stage, verify the report directory, and adjust testResults. Avoid enabling allowEmptyResults just to silence the error.
The publisher runs after a failure but there is no report The test command failed before generating reports, or the runner is not configured to write them on failure. Configure the runner to emit results on failed runs where supported, then verify that the files exist before the post action executes.
The JUnit step rejects or misreads files The glob includes unrelated XML or the files are not in a compatible JUnit-style format. Narrow the glob to report filenames and use a publisher that supports the runner’s format.
Test failures appear but the build is not unstable A step option or downstream pipeline policy suppresses instability. Review the JUnit step’s status options and the job’s status handling; restore the expected signal if failures should mark the build or stage unstable.
HTML report link exists but the page or assets are broken The configured report file is wrong, or referenced assets are missing or not published with the report. Point reportDir at the generated directory, verify reportFiles, and ensure the report’s supporting files are present there.
Jenkins uses too much memory while retaining test details Verbose standard output and error are retained for many tests or builds. Review stdioRetention, reduce retention to failed tests or none when appropriate, and keep full output only when needed for diagnosis.
Results are absent only in some branches or modules Those paths use different output directories, skip the test task, or do not produce reports for that run. Compare workspace contents across the affected branches/modules and use a glob that covers only the intended report directories.

6. Keep the pipeline reliable and efficient

  • Publish in post { always { ... } } when reports matter on failure. This gives Jenkins an opportunity to collect files after an unsuccessful test stage.
  • Keep report paths workspace-relative and verify them. A correct-looking glob is not evidence that the runner writes there.
  • Keep patterns narrow. Avoid parsing unrelated XML, which can cause errors or misleading results.
  • Do not treat an empty report as success by accident. Allow empty results only when absence is part of the job’s intended behavior.
  • Manage retained output and HTML history. More retained diagnostics and per-build reports can increase storage use; retaining long test output can also raise Jenkins memory use.
  • Check the installed plugin version. Plugin options and integration setup can vary; use the documentation matching the controller’s installed versions.

Or skip the browser setup

If your Jenkins workflow also needs website screenshots for visual checks or documentation, ScreenshotNeo provides a website screenshot API and MCP server. It complements test reporting; it does not publish Jenkins test results or replace your test runner. Its API accepts one GET request and returns a PNG, JPEG, WebP, or PDF. See the API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for ScreenshotNeo’s free plan.

FAQ

Does Jenkins generate the test report?

No. The test runner generates result files; Jenkins publishers collect and display compatible files.

Can I use JUnit publishing with TestNG?

TestNG can output JUnit-style XML. Configure the runner to produce compatible XML and point the JUnit step at those files.

Yes. Publish compatible XML with junit and publish the generated HTML directory with HTML Publisher.

Should I allow empty results?

Only when a run legitimately may produce no reports. Otherwise, keeping the missing-results error helps catch broken paths and report generation.

References