DocumentationAzure DevOps integration

Azure DevOps JUnit artifacts

Keep test execution in Azure Pipelines. Generate JUnit XML, publish the same files as a retained Pipeline artifact, and let QaCockpit import the exact build evidence through the connected Azure identity.

01

Expose safe YAML parameters

QaCockpit discovers non-secret top-level YAML parameters and validates launch values against their type, required state, defaults, and allowed values. Keep environment labels in QaCockpit unless your pipeline independently requires a target parameter.

azure-pipelines.yml — launch parameters
trigger: none
pr: none

parameters:
  - name: browser
    displayName: Playwright project
    type: string
    default: chromium
    values: [chromium, firefox, webkit]
  • Do not pass a QaCockpit token or internal execution ID as a parameter.
  • Keep service credentials in Azure secret variables or Key Vault-backed configuration.
  • Retain the result artifact even when the test command reports failed tests.

02

Create and retain Playwright JUnit XML

Azure Pipeline steps — Playwright
- bash: |
    mkdir -p test-results
    npx playwright test --project="${BROWSER}" --reporter=junit
  displayName: Run Playwright and create JUnit XML
  continueOnError: true
  env:
    BROWSER: ${{ parameters.browser }}
    PLAYWRIGHT_JUNIT_OUTPUT_FILE: test-results/junit.xml

- task: PublishTestResults@2
  displayName: Show results in Azure DevOps
  condition: always()
  inputs:
    testResultsFormat: JUnit
    testResultsFiles: test-results/junit.xml
    failTaskOnMissingResultsFile: true

- task: PublishPipelineArtifact@1
  displayName: Retain JUnit XML for QaCockpit
  condition: always()
  inputs:
    targetPath: test-results
    artifact: playwright-test-evidence
    publishLocation: pipeline

- bash: exit 1
  displayName: Preserve failed test conclusion
  condition: eq(variables['Agent.JobStatus'], 'SucceededWithIssues')

The example deliberately uses continueOnError, always publishes both Azure's test view and the retained files, then restores the failed job conclusion. Install Node.js, dependencies, and Playwright browsers before these steps.

03

Retain Maven Surefire reports

Azure Pipeline steps — JUnit 5 and REST Assured
- bash: mvn --batch-mode test
  displayName: Run REST Assured and create Surefire XML
  continueOnError: true

- task: PublishTestResults@2
  displayName: Show results in Azure DevOps
  condition: always()
  inputs:
    testResultsFormat: JUnit
    testResultsFiles: target/surefire-reports/TEST-*.xml
    failTaskOnMissingResultsFile: true

- task: PublishPipelineArtifact@1
  displayName: Retain JUnit XML for QaCockpit
  condition: always()
  inputs:
    targetPath: target/surefire-reports
    artifact: rest-assured-test-evidence
    publishLocation: pipeline

- bash: exit 1
  displayName: Preserve failed test conclusion
  condition: eq(variables['Agent.JobStatus'], 'SucceededWithIssues')

Surefire commonly creates one TEST-*.xml file per test class. Publish the whole report directory so a partial wildcard or copy step cannot silently drop classes.

04

PublishTestResults is useful, but not sufficient

PublishTestResults@2 makes test cases visible inside Azure DevOps. QaCockpit's retained-evidence import requires the source XML files to remain downloadable from the exact pipeline run, so add PublishPipelineArtifact@1as a separate step.

Azure test view

PublishTestResults@2

Displays and aggregates results inside Azure DevOps.

QaCockpit evidence

PublishPipelineArtifact@1

Retains the original JUnit files for trusted import.

Azure DevOps Server does not support Pipeline artifacts. Its equivalent isPublishBuildArtifacts@1; confirm provider compatibility before using an on-premises Azure DevOps installation.

05

What happens after the pipeline completes

  1. The verified Azure Service Hook identifies the completed pipeline run.
  2. QaCockpit resolves the exact Build ID and downloads its retained artifact.
  3. Compatible JUnit XML is discovered by content and normalized into the Test Source.
  4. Pipeline lifecycle, result intake, and test outcome remain separate signals.