---
title: "JUnit"
description: "The run as a JUnit XML report — the format Azure DevOps, GitLab, GitHub Actions and Jenkins turn into a test report"
url: "https://docs.justcat.it/reference/outputs/junit/"
---
# JUnit


## When to use it

In a pipeline, when the platform should show the tests — green and red per test, the failure message on click, trend over runs — rather than a log. JUnit is the report format every CI platform reads: Azure DevOps (*Publish Test Results*, `JUnit`), GitLab (`artifacts:reports:junit`), GitHub Actions (reporter actions), Jenkins (*JUnit* plugin). It carries the result and the message of each test, not the full definition; keep [JSON](https://docs.justcat.it/reference/outputs/json/ "JSON") next to it when a step needs the data. On Azure DevOps [TRX](https://docs.justcat.it/reference/outputs/trx/ "TRX") is the alternative; elsewhere JUnit is the one to use.

## How to set it

```yaml
Output: junit
```

writes `TestResults/cat-test-results-{timestamp}.xml`. A pipeline usually wants a fixed name to publish:


**Properties**



Format
: junit

File
: TestResults/cat-junit.xml





**YAML**


```yaml
Output:
- Format: junit
  File: TestResults/cat-junit.xml
```




See [Settings](https://docs.justcat.it/reference/outputs/settings/ "Settings"). Not available on the Starter and Professional plans (MS Excel only). How each platform picks the file up is in [Integrations](https://docs.justcat.it/reference/integrations/ "Integrations").

## What it looks like

The [sample run](https://docs.justcat.it/reference/outputs/overview/#the-sample-run "The sample run"), complete:

```xml
<?xml version="1.0" encoding="utf-8"?>
<testsuites>
  <testsuite name="Smoke tests" timestamp="2026-08-21T09:06:38" hostname="build-agent-01" tests="2" failures="0" errors="1" skipped="0" time="6.3247960999999995">
    <testsuite name="" timestamp="2026-08-21T09:06:38" hostname="build-agent-01" tests="2" failures="0" errors="1" skipped="0" time="6.3247960999999995">
      <testcase name="[Smoke tests].[Airline dimension matches the source]" classname="[Smoke tests].[Airline dimension matches the source]" time="0.0755756" />
      <testcase name="[Smoke tests].[Flights table is loaded]" classname="[Smoke tests].[Flights table is loaded]" time="6.2492205">
        <error>Invalid object name 'dbo.Flights'.</error>
      </testcase>
    </testsuite>
  </testsuite>
  <testsuite name="Data quality" timestamp="2026-08-21T09:06:38" hostname="build-agent-01" tests="1" failures="1" errors="0" skipped="0" time="0.1389169">
    <testsuite name="" timestamp="2026-08-21T09:06:38" hostname="build-agent-01" tests="1" failures="1" errors="0" skipped="0" time="0.1389169">
      <testcase name="[Data quality].[No booking without a passenger]" classname="[Data quality].[No booking without a passenger]" time="0.1389169">
        <failure>No row was expected, but at least 1 row exists.
MaximumErrorsLogged setting is set to 1. To see more data in the error message, set it to value between 2 and 50.
If the logs should not contain any data, set MaximumErrorsLogged to 0.

┌──────────┬────────┐
│BookingId │Airline │
╞══════════╪════════╡
│BK-1001   │CSA     │
└──────────┴────────┘

CAT did NOT scan the entire set. There may be additional rows.


Description: A booking must reference an existing passenger.
First Data Source: DWH
First Query:

SELECT 'BK-1001' AS BookingId, 'CSA' AS Airline UNION ALL SELECT 'BK-1002', 'LH'

</failure>
      </testcase>
    </testsuite>
  </testsuite>
</testsuites>
```

## Details

**Structure.** `<testsuites>` holds one `<testsuite>` per test **suite**; inside it one `<testsuite>` per test **case** (named `""` when the tests have no `Test case`); inside that one `<testcase>` per test. `name` and `classname` of a test case are both the test's [full name](https://docs.justcat.it/reference/tests/properties/#full-name "Full name"). Every suite element carries `tests`, `failures`, `errors`, `skipped`, `time` (seconds) and `timestamp` of its first test, and `hostname` — the machine that ran it.

**Result mapping.**

| Result | In the report |
|---|---|
| `Passed` | `<testcase>` with no child element |
| `Failed` | `<failure>` holding the complete message — verdict, sample of rows, description, queries |
| `Error` | `<error>` holding the exception message |
| `Inconclusive` | `<skipped message="…">` with the reason; counted under `skipped` |

Platforms show `<failure>` and `<error>` text on the test's detail page — the box-drawing sample of a failed test is legible there when the viewer uses a monospace font, which Azure DevOps and GitLab do.

**Written once, after the run.** Publishing a JUnit report does not by itself fail a pipeline; configure the publish step to fail on test failures when that is wanted (Azure DevOps: *Fail if there are test failures*).

## Related

* [TRX](https://docs.justcat.it/reference/outputs/trx/ "TRX") — the Visual Studio report format, for Azure DevOps.
* [Integrations](https://docs.justcat.it/reference/integrations/ "Integrations") — Azure DevOps, GitLab, GitHub Actions and Jenkins, step by step.
* [Results](https://docs.justcat.it/reference/tests/results/ "Results") — the four result values.

