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

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, or from CI:

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

./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.

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.
  • 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.

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 →

Related