---
title: "JSON"
description: "The whole run as one JSON document — counts, and every result with its message, timing and definition"
url: "https://docs.justcat.it/reference/outputs/json/"
---
# JSON


## When to use it

For anything that reads the results by program: a pipeline step that fails the build on a failed test, a script that mails someone when a suite's pass rate drops, a job that loads results somewhere CAT has no output for. JSON is read natively by PowerShell, Python and every CI platform. It carries everything — the complete test definition included — so nothing has to be looked up in the project file afterwards. For a human reading the file, [YAML](https://docs.justcat.it/reference/outputs/yaml/ "YAML") is the same data in a friendlier shape; for a test report in a pipeline, [JUnit](https://docs.justcat.it/reference/outputs/junit/ "JUnit") or [TRX](https://docs.justcat.it/reference/outputs/trx/ "TRX").

## How to set it

```yaml
Output: json
```

writes `TestResults/cat-test-results-{timestamp}.json` next to the project file. To choose the name:


**Properties**



Format
: json

File
: results/latest.json





**YAML**


```yaml
Output:
- Format: json
  File: results/latest.json
```




See [Settings](https://docs.justcat.it/reference/outputs/settings/ "Settings"). Not available on the Starter and Professional plans (MS Excel only).

## What it looks like

The [sample run](https://docs.justcat.it/reference/outputs/overview/#the-sample-run "The sample run") — the first result in full, the other two elided:

```json
{
  "executionGuid": "78084065-0bde-4628-b49f-f977c0f803df",
  "startedOn": "2026-08-21T09:06:37.4369592+00:00",
  "finishedOn": "2026-08-21T09:06:44.7333889+00:00",
  "duration": "00:00:07.2964297",
  "results": [
    {
      "executionGuid": "2ecab40f-fbcd-4d94-a2a0-28b1134f9a5c",
      "testResult": "Passed",
      "message": "The sets match.\n\nDescription: Every airline in the source must land in the dimension, nothing more.\nFirst Data Source: DWH\nFirst Query:\n\nSELECT 'CSA' AS Code UNION ALL SELECT 'LH' ORDER BY Code\n\nSecond Data Source: DWH\nSecond Query:\n\nSELECT 'CSA' AS Code UNION ALL SELECT 'LH' ORDER BY Code\n\n",
      "rawMessage": "The sets match.",
      "startTime": "2026-08-21T09:06:38.2510955+00:00",
      "endTime": "2026-08-21T09:06:38.3266711+00:00",
      "duration": "00:00:00.0755756",
      "exceptionMessage": null,
      "exceptions": null,
      "testDefinition": {
        "testDefinitionID": "aa6f2ccd-6e99-4c0e-8f4d-775c7904a628",
        "suite": "Smoke tests",
        "name": "Airline dimension matches the source",
        "testFullName": "[Smoke tests].[Airline dimension matches the source]",
        "description": "Every airline in the source must land in the dimension, nothing more.",
        "firstDataSource": "DWH",
        "firstQuery": "SELECT 'CSA' AS Code UNION ALL SELECT 'LH' ORDER BY Code",
        "secondDataSource": "DWH",
        "secondQuery": "SELECT 'CSA' AS Code UNION ALL SELECT 'LH' ORDER BY Code",
        "expectation": "sets match",
        "timeout": 0,
        "maximumErrorsLogged": 1,
        "tags": [],
        "settings": {
          "Name": "Airline dimension matches the source",
          "Suite": "Smoke tests",
          "Description": "Every airline in the source must land in the dimension, nothing more.",
          "First data source": "DWH",
          "First query": "SELECT 'CSA' AS Code UNION ALL SELECT 'LH' ORDER BY Code",
          "Second data source": "DWH",
          "Second query": "SELECT 'CSA' AS Code UNION ALL SELECT 'LH' ORDER BY Code",
          "Expectation": "sets match"
        }
      },
      "testDefinitionGuid": "aa6f2ccd-6e99-4c0e-8f4d-775c7904a628",
      "testName": "Airline dimension matches the source",
      "testFullName": "[Smoke tests].[Airline dimension matches the source]",
      "testSuite": "Smoke tests",
      "testCase": null,
      "description": "Every airline in the source must land in the dimension, nothing more.",
      "firstDataSource": "DWH",
      "firstQuery": "SELECT 'CSA' AS Code UNION ALL SELECT 'LH' ORDER BY Code",
      "secondDataSource": "DWH",
      "secondQuery": "SELECT 'CSA' AS Code UNION ALL SELECT 'LH' ORDER BY Code",
      "expectation": "sets match",
      "numberOfErrors": null,
      "threadNumber": 0
    },
    { "testResult": "Failed", "rawMessage": "No row was expected, but at least 1 row exists. …", "…": "…" },
    { "testResult": "Error", "exceptionMessage": "Invalid object name 'dbo.Flights'.", "…": "…" }
  ],
  "passedCount": 1,
  "failedCount": 1,
  "errorCount": 1,
  "inconclusiveCount": 0,
  "totalCount": 3,
  "passRate": 33.3,
  "failedRate": 33.3,
  "errorRate": 33.3,
  "inconclusiveRate": 0
}
```

## Details

**One document, the run at the top.** `executionGuid`, `startedOn`, `finishedOn`, `duration`, then `results` — one object per test — and after them the counts and rates of the whole run (`passedCount`, `failedCount`, `errorCount`, `inconclusiveCount`, `totalCount`, `passRate`, …). Keys are camelCase.

**One object per result.** `testResult` (`Passed` · `Failed` · `Error` · `Inconclusive`), `message` and `rawMessage` as described on [Properties](https://docs.justcat.it/reference/outputs/properties/ "Properties"), `startTime` / `endTime` / `duration`, `threadNumber`, `numberOfErrors`, `exceptionMessage` plus `exceptions` — the exception chain with type and stack trace, for `Error` only — and `testDefinition`: the complete definition as CAT resolved it, including `settings`, the properties exactly as they were written in the source. Properties of the definition come twice: resolved (`firstQuery`) and as written before environment variables were expanded (`firstQueryRaw`). The shown sample leaves most of the definition out; the file has all of it.

**Dates and durations.** ISO 8601 with offset for the times (`2026-08-21T09:06:38.2510955+00:00`), `hh:mm:ss.fffffff` for durations.

**The file starts with a byte-order mark** (UTF-8 BOM). PowerShell's `ConvertFrom-Json` and .NET readers skip it; Python's `json.load` does not — open the file with `encoding="utf-8-sig"`.

```powershell
$run = Get-Content TestResults/latest.json -Raw | ConvertFrom-Json
$run.results | Where-Object testResult -ne Passed | Select-Object testFullName, testResult, rawMessage
if ($run.failedCount + $run.errorCount -gt 0) { exit 1 }
```

```python
import json
with open("TestResults/latest.json", encoding="utf-8-sig") as f:
    run = json.load(f)
failed = [r for r in run["results"] if r["testResult"] != "Passed"]
```

**Written once, after the run**, whatever the results; a run that is killed leaves no file. A pipeline that must fail on a failed test reads `failedCount` and `errorCount` from here — no CAT tool turns results into an exit code on its own.

## Related

* [YAML](https://docs.justcat.it/reference/outputs/yaml/ "YAML") — the same document in YAML.
* [Properties](https://docs.justcat.it/reference/outputs/properties/ "Properties") — what each field holds.
* [Results](https://docs.justcat.it/reference/tests/results/ "Results") — the result values.

