Bird
Raised Fist0
Jenkinsdevops~10 mins

JUnit test report publishing in Jenkins - Step-by-Step Execution

Choose your learning style10 modes available
Process Flow - JUnit test report publishing
Start Pipeline
↓
Run mvn test
↓
Tests Execute
↓
Post: always
↓
junit step parses XML
↓
Reports visible in Jenkins UI
↓
Build marked stable/unstable
The pipeline runs Maven tests which generate JUnit XML reports. Regardless of pass or fail, the post/always block runs the junit step to parse XML reports and display results in Jenkins UI.
Execution Sample
Jenkins
pipeline {
  agent any
  stages {
    stage('Test') {
      steps {
        sh 'mvn test'
      }
    }
  }
  post {
    always {
      junit 'target/surefire-reports/*.xml'
    }
  }
}
This Jenkins pipeline runs Maven tests and publishes JUnit XML reports from surefire-reports directory using the post/always block.
Process Table
StepActionWorkspace StateReports StateBuild StatusNext Step
1Pipeline starts, agent allocatedEmpty workspace checked outNo reports yetIn progressRun tests
2sh 'mvn test' executesSource compiled, tests runningNo reports yetIn progressTests complete
3Maven Surefire generates XML reportstarget/surefire-reports/*.xml createdXML files on disk (3 files)In progressEnter post block
4post/always block triggersWorkspace unchangedXML files on diskIn progressParse reports
5junit step parses XML reportsWorkspace unchanged10 tests: 8 passed, 1 failed, 1 skippedUnstable (has failures)Display results
6Test results visible in Jenkins UIWorkspace unchangedReport published with trendsUnstablePipeline ends
💡 Reports published successfully. Build marked UNSTABLE due to 1 test failure.
Status Tracker
VariableStartAfter Step 2After Step 3After Step 5Final
testsPassed00888
testsFailed00111
testsSkipped00111
reportsPublishedNoNoNoYesYes
buildStatusIn progressIn progressIn progressUnstableUnstable
Key Moments - 3 Insights
Why use post/always instead of putting junit inside the Test stage steps?
If junit is inside steps and mvn test fails (non-zero exit), the stage aborts before reaching the junit step. Using post/always ensures reports are published regardless of test pass or fail.
What is the difference between UNSTABLE and FAILURE build status?
UNSTABLE means tests ran but some failed — the junit step sets this automatically. FAILURE means the pipeline itself crashed (e.g., syntax error, agent unavailable). Test failures produce UNSTABLE, not FAILURE.
Where do the XML report files come from?
Maven Surefire plugin generates JUnit-format XML files in target/surefire-reports/ automatically when running mvn test. The junit step reads these files — it does not run tests itself.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table. At which step do XML report files first appear on disk?
AStep 1 — when the agent is allocated
BStep 2 — when mvn test runs
CStep 3 — when Surefire generates reports
DStep 5 — when junit step parses them
💡 Hint
Check the Reports State column — reports appear after Maven finishes running tests.
From the variable tracker, what is the build status after the junit step parses the reports?
ASuccess
BFailure
CUnstable
DIn progress
💡 Hint
Check the buildStatus row after Step 5 — failed tests cause UNSTABLE, not FAILURE.
What would happen if the junit path pattern 'target/surefire-reports/*.xml' matched zero files?
AJenkins publishes an empty report with 0 tests
BJenkins throws an error: No test report files found
CJenkins skips report publishing silently
DJenkins marks the build as SUCCESS
💡 Hint
The junit step requires at least one matching file — use allowEmptyResults: true to handle missing reports gracefully.
Concept Snapshot
JUnit test report publishing makes test results visible in Jenkins UI.
Maven Surefire generates XML reports in target/surefire-reports/.
The junit pipeline step parses XML files — it does not run tests.
Always use post/always to ensure reports publish even on failure.
Failed tests set build to UNSTABLE, not FAILURE.
Use allowEmptyResults: true if reports might not exist.
Full Transcript
This visual execution shows how Jenkins publishes JUnit test reports. The pipeline runs mvn test which executes unit tests. Maven Surefire plugin generates XML report files in the target/surefire-reports directory. After tests complete, whether they pass or fail, the post/always block triggers. The junit step reads and parses the XML files, extracting test counts for passed, failed, and skipped tests. Jenkins displays these results in the UI with trends over time. If any tests fail, the build is marked UNSTABLE. The key insight is that junit only parses reports — it does not run tests — and post/always ensures reports are always published.

Practice

(1/5)
1. What is the main purpose of publishing JUnit test reports in Jenkins?
easy
A. To run tests faster on Jenkins agents
B. To display test results clearly in Jenkins for easy review
C. To compile Java code before testing
D. To deploy the application automatically after tests

Solution

  1. Step 1: Understand JUnit report publishing

    Publishing JUnit reports in Jenkins helps show test results in a readable format.
  2. Step 2: Identify the main goal

    The main goal is to review test outcomes easily, not to run tests or deploy code.
  3. Final Answer:

    To display test results clearly in Jenkins for easy review -> Option B
  4. Quick Check:

    JUnit reports show test results [OK]
Hint: JUnit reports = test results display in Jenkins [OK]
Common Mistakes:
  • Confusing report publishing with running tests
  • Thinking it compiles code
  • Assuming it triggers deployment
2. Which Jenkins pipeline syntax correctly publishes JUnit test reports stored in target/surefire-reports/*.xml?
easy
A. post { always { junit 'target/surefire-reports/*.xml' } }
B. steps { junit 'target/surefire-reports/*.xml' }
C. post { junit 'target/surefire-reports/*.xml' }
D. publishJUnit 'target/surefire-reports/*.xml'

Solution

  1. Step 1: Identify correct placement of junit step

    The junit step must be inside a post block, usually with always to run after build.
  2. Step 2: Check syntax correctness

    post { always { junit 'target/surefire-reports/*.xml' } } uses post { always { junit 'path' } } which is correct syntax for publishing reports.
  3. Final Answer:

    post { always { junit 'target/surefire-reports/*.xml' } } -> Option A
  4. Quick Check:

    junit inside post always block [OK]
Hint: Put junit step inside post { always { ... } } [OK]
Common Mistakes:
  • Placing junit directly under steps without post
  • Using wrong step name like publishJUnit
  • Omitting the always block inside post
3. Given this Jenkins pipeline snippet, what will happen after the build if the test reports are saved in build/test-results/*.xml?
post {
  always {
    junit 'build/test-results/*.xml'
  }
}
medium
A. JUnit reports will be ignored because path is incorrect
B. Tests will rerun automatically after the build
C. Build will fail if no test reports are found
D. JUnit test results will be published and visible in Jenkins UI

Solution

  1. Step 1: Understand junit step behavior

    The junit step publishes test results from the given XML path after the build.
  2. Step 2: Check the path and effect

    The path build/test-results/*.xml matches where reports are saved, so results will be published and shown.
  3. Final Answer:

    JUnit test results will be published and visible in Jenkins UI -> Option D
  4. Quick Check:

    Correct path + junit step = results published [OK]
Hint: Correct path in junit step shows results in Jenkins [OK]
Common Mistakes:
  • Thinking tests rerun automatically
  • Assuming build fails if reports missing
  • Believing reports are ignored without error
4. You added this to your Jenkinsfile but test reports do not appear in Jenkins UI:
post {
  always {
    junit 'reports/*.xml'
  }
}
What is the most likely cause?
medium
A. The junit step must be inside the steps block, not post
B. The junit step requires a full absolute path
C. The report files are not saved in the 'reports' directory
D. The pipeline must use 'archiveArtifacts' to publish reports

Solution

  1. Step 1: Verify report file location

    If reports are not saved in 'reports/*.xml', junit cannot find them to publish.
  2. Step 2: Understand junit step requirements

    junit works with relative paths and does not require absolute paths or archiveArtifacts for publishing test results.
  3. Final Answer:

    The report files are not saved in the 'reports' directory -> Option C
  4. Quick Check:

    Wrong report path = no results shown [OK]
Hint: Check report file path matches junit pattern [OK]
Common Mistakes:
  • Placing junit outside post block
  • Using absolute paths unnecessarily
  • Confusing junit with archiveArtifacts
5. You want Jenkins to publish JUnit reports only if tests run successfully, but still archive reports even if tests fail. Which Jenkinsfile snippet achieves this?
hard
A. post { success { junit 'test-results/*.xml' } always { archiveArtifacts 'test-results/*.xml' } }
B. post { always { junit 'test-results/*.xml' archiveArtifacts 'test-results/*.xml' } }
C. post { failure { junit 'test-results/*.xml' } success { archiveArtifacts 'test-results/*.xml' } }
D. post { success { archiveArtifacts 'test-results/*.xml' } always { junit 'test-results/*.xml' } }

Solution

  1. Step 1: Understand conditions for junit and archiveArtifacts

    To publish JUnit reports only on success, place junit inside success block. To archive always, place archiveArtifacts inside always.
  2. Step 2: Match snippet to requirements

    post { success { junit 'test-results/*.xml' } always { archiveArtifacts 'test-results/*.xml' } } correctly uses success { junit } and always { archiveArtifacts }, meeting the goal.
  3. Final Answer:

    post { success { junit 'test-results/*.xml' } always { archiveArtifacts 'test-results/*.xml' } } -> Option A
  4. Quick Check:

    junit on success + archive always [OK]
Hint: Use success for junit, always for archiveArtifacts [OK]
Common Mistakes:
  • Putting junit in always block causing publish on failure
  • Swapping archiveArtifacts and junit blocks
  • Using failure block incorrectly
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard