Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Phpunit Pretty Printer Laravel Package

diablomedia/phpunit-pretty-printer

A drop-in PHPUnit result printer that swaps the default console output for colorful, readable test results. See test progress, failures, exception diffs, and timing at a glance, with configurable verbosity for CI and local runs.

Deep Wiki
Context7

Getting Started

Install as a dev dependency so it never ships to production:

composer require --dev diablomedia/phpunit-pretty-printer

Verify the FQCN before wiring it up — the repo is unlisted, so confirm the class name from the vendor tree:

composer show diablomedia/phpunit-pretty-printer
grep -r "class .*Printer" vendor/diablomedia/phpunit-pretty-printer/src

Then register it as the run's result printer either per-run (safest first step, zero config changes):

vendor/bin/phpunit --printer 'DiabloMedia\PHPUnit\PrettyPrinter\PrettyPrinter'

…or persistently in your PHPUnit config. For PHPUnit 8/9, the printer class lives on the root <phpunit> element:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit printerClass="DiabloMedia\PHPUnit\PrettyPrinter\PrettyPrinter"
         colors="true"
         bootstrap="vendor/autoload.php">
    <testsuites>
        <testsuite name="unit">
            <directory>tests/Unit</directory>
        </testsuite>
    </testsuites>
</phpunit>

Look here first: phpunit.xml.dist (the committed default) and any phpunit.xml override. Keep the printer in the local phpunit.xml (gitignored) rather than .dist, so CI keeps the standard, machine-parseable output.

First use case: you have a suite where a handful of test files dominate wall-clock time but the default dot-progress output hides which ones. Run the suite with this printer, watch the per-file lines stream by with their timings, and immediately see which files are the hot spots — the natural next step is splitting those into a separate suite or parallelising them with paratest.

Implementation Patterns

Local-dev default, CI-standard output. Put the printer in phpunit.xml and leave phpunit.xml.dist untouched. PHPUnit merges phpunit.xml over .dist, so developers get pretty per-file progress while CI (which only checks out .dist) gets the vanilla output its parsers expect.

Composer script shortcut. Wrap the invocation so nobody has to remember the FQCN:

{
  "scripts": {
    "test": "phpunit",
    "test:pretty": "phpunit --printer 'DiabloMedia\\PHPUnit\\PrettyPrinter\\PrettyPrinter'",
    "test:ci": "phpunit --log-junit build/junit.xml --coverage-clover build/clover.xml"
  }
}

composer test:pretty becomes the everyday command; composer test:ci is what the pipeline calls.

Targeted runs while iterating. The printer pairs well with narrowing flags — the per-file header plus timing is most useful when you're running a slice of the suite:

vendor/bin/phpunit --printer '...' --testsuite unit
vendor/bin/phpunit --printer '...' tests/Feature/Checkout
vendor/bin/phpunit --printer '...' --filter 'test_authorize'

Timing-driven suite surgery. Use the output as an investigative tool, not just cosmetics:

  1. Run the full suite with the printer, capture output: composer test:pretty 2>&1 | tee /tmp/profile.txt
  2. Sort/scrape the reported per-file durations to rank files.
  3. Act: move slow integration-style tests out of the unit suite, convert to a @group slow and exclude by default, or fan out with paratest.

Pair it with a logger for data you can actually diff. The printer is for eyeballs; JUnit XML is for trend tracking. Run both in one invocation by using --printer on the CLI plus <logging> in config — loggers are independent of the result printer.

Team onboarding / demo pattern. Because it's a printer swap and not a test-listener, it has no effect on pass/fail. That makes it a low-risk thing to add to a shared dev Docker image or a Makefile target, and to drop in during pairing sessions when someone asks "why is the suite slow?"

Gotchas and Tips

It's a printerClass — API churn is the real risk. The last release was December 2021, squarely in the PHPUnit 8/9 era. PHPUnit 10 reworked the result-collector/event system and removed the XML printerClass attribute along with the older printer contract. Pin your PHPUnit major and confirm the printer loads before standardising on it — a silent fallback to the default printer with a deprecation notice is the most likely failure mode. If you're on PHPUnit 9 already, this is a comfortable fit; on 10+ treat it as unsupported until proven otherwise.

Keep it out of phpunit.xml.dist. Beyond CI parsing, printerClass in a committed config becomes a hard dependency for every contributor and every CI cache that doesn't run composer install with dev deps (--no-dev installs will fail to find the class and abort the run).

Any stray output corrupts the display. The printer draws streaming per-file lines; echo, var_dump, fwrite(STDERR, ...), and un-suppressed deprecations/notices from your own bootstrap will interleave and shred the layout. If the output looks scrambled, hunt for output in setUp, custom assertions, or a bootstrap that prints.

--debug and --testdox fight it. --debug swaps in its own printer, and --testdox is a separate formatter — don't expect them to compose. Pick one per run.

Colour and TTY assumptions. ANSI colour codes are emitted for terminals. On CI or when piping to a file, either rely on colors="false" in config or accept the escape sequences and strip them when post-processing (sed -r 's/\x1B\[[0-9;]*[mK]//g'). Non-UTF8 locales and very narrow terminals can wrap the per-file lines awkwardly.

Only one result printer at a time. You cannot have this and another printerClass simultaneously. If a teammate needs TeamCity output, that's a separate invocation — use <logging>/--log-junit for the machine-readable artefacts that can coexist.

Expect a small overhead on huge suites. Printing a line per file is cheap, but on thousands of files in a hot loop the I/O is non-zero. If you're micro-benchmarking, benchmark with the default printer and reserve this for profiling runs.

Extension points are thin by design. This is an output formatter, not a listener — it doesn't give you hooks to mutate tests. If you need per-test timing that feeds a custom report or a slow-test budget gate, don't try to bend the printer: write a proper PHPUnit extension/TestListener (or read the JUnit XML the printer run also produced) and let the printer stay a human-facing view.

Version-lock discipline. With a single 2021 release and 77 stars, treat it as unmaintained-but-stable: commit composer.lock, and note in your README/ADR why PHPUnit is pinned. If a future PHPUnit upgrade blocks you, the escape hatch is trivial — the data you actually want (per-file time) is in JUnit XML, so a small script over --log-junit output reproduces 90% of the value.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle