# Share a Pest Test Report — From PHPUnit XML to a Link

Canonical: https://commareports.com/share-pest-report
Published: 2026-09-15

> Pest prints a beautiful terminal run and nothing you can send. Log JUnit, convert it, publish the page to Comma, and the suite becomes a URL the team can read and comment on.

# Share a Pest test report

Pest's terminal output is the reason people switch to it — the expectation
diff, the dataset row that failed, the `describe` nesting that actually reads
like the feature. Then the run finishes, CI throws the buffer away, and what
reaches the team is a screenshot of a terminal.

Pest runs on PHPUnit, which means every PHPUnit logger is available to you.

## Write JUnit, convert to HTML

```bash
composer require --dev pestphp/pest
pip install junit2html   # or: npm i -D junit-viewer

./vendor/bin/pest --log-junit junit.xml || true
junit2html junit.xml pest.html
```

`|| true` matters: `pest` exits non-zero on failures, and the failing run is
precisely the one worth publishing. Keep a separate, unmuted `pest` step if
you want the build to fail.

## Publish it

Drag `pest.html` into [the app](https://commareports.com/), or from CI:

```bash
curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html pest.html \
        --arg title "Pest — $GITHUB_REF_NAME" '{title: $title, html: $html}')"
```

One report id per suite. PATCH on every run and the link in your README always
shows the latest, with every earlier run kept as a revision.

## Coverage, if you have Xdebug or PCOV

```bash
./vendor/bin/pest --coverage --coverage-html coverage/
```

That writes a folder, not a file — drag the whole `coverage/` directory in and
the drill-down keeps working, because the per-file pages upload as assets and
their links are rewritten. Same story as any
[coverage report](/share-coverage-report).

## What the link gets you

- **Anchored threads** on the failure — "this one only fails on the CI Postgres
  version" — recorded next to the assertion rather than in a channel nobody
  searches. See [commenting on HTML](/comment-on-html).
- **Revisions**, so "was this red yesterday?" is a question the URL answers.
- **Access per report** — private, team, domain-gated, or named reviewers. See
  the [sharing model](/docs/sharing).

## Limits

- **Entry HTML: 5 MB.** Assets: 25 MB per file, 250 MB and 500 files total.
  A big suite's converted JUnit is small; the coverage tree is the one that
  approaches the file cap.
- **60 requests/minute per token.**

## Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision
history.

**[Publish a test report →](https://commareports.com/)**

### Related

- [Share a PHPUnit report](/share-phpunit-report) · [Share a PHPStan report](/share-phpstan-report)
- [Share a Psalm report](/share-psalm-report) · [Share a JUnit report](/share-junit-report)
- [Publish from CI](/docs/ci) · [Scheduled reports](/features/routines/scheduled-html-reports)
