Publishing JUnit and Surefire test reports in Jenkins is how you get your automated test results visualized and actionable within your CI/CD pipeline.

Here’s a quick look at how that looks in the Jenkins UI after a build:

// Imagine this is a screenshot of a Jenkins build job
// Showing a "Test Results" section with a summary of passed, failed, and skipped tests.
// Clicking on "Test Results" reveals a detailed breakdown of each test case,
// including stack traces for failures.

The system that handles this is the Jenkins "JUnit" plugin, which is actually a bit of a misnomer because it parses XML reports generated by various build tools, not just JUnit. Maven Surefire and Failsafe, Gradle, and Ant all produce reports in a format the JUnit plugin understands. The core idea is to collect these XML files, which contain the raw test outcomes, and present them in a human-readable and interactive way within Jenkins.

This process solves a critical problem: without it, your build might pass even if tests fail, or you’d have to sift through raw console output to find test errors. By publishing these reports, Jenkins provides a centralized, historical view of your test quality, allowing you to quickly identify regressions and understand the health of your codebase over time.

Let’s break down the internal mechanics. When your build tool (like Maven or Gradle) runs tests, it generates XML files in a specific directory structure. For Maven Surefire, this is typically in target/surefire-reports/. For Gradle, it’s usually build/test-results/test/. These XML files adhere to a standard format that describes each test method, its status (passed, failed, skipped, error), and any associated error messages or stack traces.

The Jenkins "JUnit" plugin is configured within your Jenkins job. You specify the Ant-style path to these XML report files. When Jenkins archives the build artifacts, it also scans for these XML files. It then parses them and stores the aggregated results. This enables features like trend graphs showing test pass rates over time, the ability to click into specific failed tests to see details, and marking builds as unstable or failed based on test outcomes.

To get this working, you need to ensure your build tool is configured to generate these reports.

For Maven, your pom.xml likely already includes the Surefire plugin, and it generates reports by default. You just need to tell Jenkins where to find them.

For Gradle, the test task by default produces reports in the build/test-results/test directory.

The Jenkins configuration itself is straightforward. In your job’s configuration, under "Post-build Actions," you add "Publish JUnit test result report."

In the "Test report XMLs" field, you enter the path relative to your workspace. Common entries include:

  • **/target/surefire-reports/*.xml (for Maven)
  • **/build/test-results/test/*.xml (for Gradle)

The ** is an Ant wildcard that means "match any directory zero or more times." This ensures Jenkins can find the reports regardless of where they are nested within the workspace.

The "Retest all" checkbox is useful for ensuring that tests that were skipped or did not run due to earlier failures are still reported. "Fail if no tests found" is a good safety net to catch misconfigurations where test execution might have been skipped entirely. "Skip publishing if tests are disabled" is for scenarios where you might intentionally disable test reporting for certain builds.

Once configured, after a build that runs tests, you’ll see a "Test Result" link on the build’s page. Clicking this takes you to a summary. You can then drill down into packages and individual test classes to see the status of each test.

The most surprising true thing about this process is that the "JUnit" plugin in Jenkins doesn’t actually care if your tests are written in JUnit, TestNG, or any other Java testing framework, as long as the output is in that specific XML format. It’s really a generic XML report parser for test results.

The next step you’ll likely encounter is configuring build stability rules based on these test results.

Want structured learning?

Take the full Jenkins course →