brianium/paratest
ParaTest brings zero-configuration parallel testing to PHPUnit. Run tests across multiple processes by TestCase or Test, and combine code coverage into one report. Install via Composer and use vendor/bin/paratest with no extra bootstrap needed.
composer require --dev.@internal classes to avoid re-implementing the runner. That is the classic "don't build it" argument: any in-house parallel test harness we write becomes a permanent maintenance liability against a moving PHPUnit target. Adopt and contribute upstream instead of owning worker orchestration, result-file merging, and coverage aggregation ourselves.flock) surface latent test pollution. Deciding to adopt it is really a decision to fund a test-isolation cleanup — and to stop accepting PRs that introduce cross-test global state.--shard option (v7.13) plus --functional mode gives us a choice between vertical parallelism (more workers on one node) and horizontal sharding across a matrix. That's a cost/latency trade-off we can now measure rather than guess at.--exclude-source-from-xml-coverage). This unblocks enforcing coverage thresholds in CI without running the suite twice or serially.paratest_for_phpstorm binary plus "Rerun failed tests" support means faster inner-loop feedback without asking engineers to change how they run tests. Good DX spend with measurable effect on PR size and review latency.TEST_TOKEN/UNIQUE_TEST_TOKEN, enforcing time limits per test (--enforce-time-limit), TestDox text/HTML reporting for stakeholder-facing test summaries, and detecting worker crashes before result files are written (v7.16.1) so flaky infrastructure doesn't masquerade as green builds.Adopt when:
php artisan test --parallel or Pest's parallel plugin — both of which sit on top of ParaTest, so the real decision is often already made for you).TEST_TOKEN are the typical first fix.Look elsewhere or defer when:
WrapperRunner explicitly does not support this, and the fix (extract shared code out of test classes) can be a large refactor.flock/touch lock-file pattern has to be adopted deliberately rather than discovered in a flaky CI run.Metadata caveat worth flagging: ParaTest is a dev-dependency, not a runtime library, so registry "dependents" counts systematically understate its real footprint. The better adoption signal is that major frameworks wrap it; the ~2.5k stars reflect the maintainer-facing audience, not end-user reach. Judge it on ecosystem coupling and release cadence (frequent, version-pinned releases tracking PHPUnit 12 and PHP 8.5), not star count.
To executives: ParaTest is a free, MIT-licensed, drop-in parallel test runner for our PHP stack. Installation is a single dev dependency with no configuration, it's reversible in one commit, and it typically cuts CI test time roughly in proportion to available cores. It directly reduces the two costs leadership feels most: PR cycle time and CI spend. The primary strategic cost is a standing commitment to keep PHPUnit current — treat that as a scheduled maintenance line item, not a surprise. Recommended: adopt on one high-traffic repository, measure suite runtime and CI cost for two weeks, then decide on broader rollout.
To engineering leadership and platform teams: It's the de facto standard parallel runner for PHPUnit, and it's the engine underneath Laravel's and Pest's built-in parallel testing — meaning we're likely already transitively dependent on it. We get combined coverage reports, sharding across CI nodes, per-worker database isolation via TEST_TOKEN, time-limit enforcement, and a PHPStorm helper for local runs. Known constraints are well-documented and manageable: no shared statics or reflection across test classes, and per-process initialization needs an explicit file-lock pattern. There is a real onboarding cost in fixing test pollution; that work is valuable independent of the tool.
To the engineering team: Install with composer require --dev brianium/paratest, run vendor/bin/paratest to parallelize by TestCase or --functional to parallelize by individual test. Before rollout: audit for shared static state and cross-test class coupling, switch per-process databases to TEST_TOKEN, adopt the documented lock-file pattern for one-time setup, and enable --verbose when triaging subprocess failures (the failing command is printed and can be copy-pasted). Plan a short burn-in period where parallel-only failures are triaged rather than retried.
How can I help you explore Laravel packages today?