brianium/paratest
ParaTest runs PHPUnit tests in parallel with zero config—just use vendor/bin/paratest. Speed up suites by TestCase or individual tests, with support for unique per-process TEST_TOKEN env vars and combined code coverage reports across workers.
Installation:
composer require --dev brianium/paratest
Ensure your phpunit version is compatible (check PHPUnit compatibility).
First Run:
Replace phpunit with vendor/bin/paratest in your test command:
vendor/bin/paratest
Default behavior parallelizes tests by TestCase. For granular parallelism (by individual tests), use:
vendor/bin/paratest --functional
Key Environment Variables:
TEST_TOKEN: Unique per-process identifier (e.g., for isolated database connections).UNIQUE_TEST_TOKEN: Unique per-run and per-process (e.g., for shared state coordination).Replace your existing test command in package.json or CI/CD scripts:
"scripts": {
"test": "vendor/bin/paratest --coverage-text --coverage-clover=coverage.clover"
}
Note: Ensure your CI environment has sufficient CPU cores (e.g., GitHub Actions: jobs.test.env.CI=true).
Default Behavior:
ParaTest automatically splits tests by TestCase class. No configuration needed.
vendor/bin/paratest --processes=4 # Uses 4 CPU cores
Granular Parallelism (Functional Mode): Split tests by individual test methods (useful for large suites):
vendor/bin/paratest --functional --shard-test-distribution=random
round-robin: Distribute tests evenly across processes.random: Randomize test distribution (reduces flakiness from order-dependent tests).Integration with CI/CD:
- name: Run tests in parallel
run: vendor/bin/paratest --processes=$(nproc) --coverage-clover=coverage.clover
--passthru-php to enable pcov or xdebug:
vendor/bin/paratest --passthru-php="'-d pcov.enabled=1'"
Database Isolation:
Use TEST_TOKEN to create isolated database schemas:
$dbName = getenv('TEST_TOKEN') ? "test_{$token}" : 'test';
One-Time Initialization: Avoid static variables. Use filesystem locks for coordination:
public function setUp(): void {
$lockFile = fopen('/tmp/test_init.lock', 'w+');
flock($lockFile, LOCK_EX); // Block until first process acquires lock
if (!file_exists('/tmp/initialized')) {
self::initialize();
file_put_contents('/tmp/initialized', '1');
}
flock($lockFile, LOCK_UN);
}
Test Dependencies:
TestHelper).Combining Reports: ParaTest now correctly merges PHP coverage reports (fixed in v7.22.4):
vendor/bin/paratest --coverage-clover=coverage.clover
pcov (PHP 8+) and xdebug:
XDEBUG_MODE=coverage vendor/bin/paratest
Excluding Sources:
vendor/bin/paratest --exclude-source-from-xml-coverage="vendor/"
Verbose Output:
vendor/bin/paratest --verbose
php -d pcov.enabled=1 vendor/bin/phpunit --printer \NullPhpunitPrinter tests/Unit/UserTest
Rerunning Failures:
Use --failed to retry only failed tests:
vendor/bin/paratest --failed
Static State:
Order-Dependent Tests:
--shard-test-distribution=random to shuffle test order.Coverage Gaps:
pcov/xdebug may not work without --passthru-php.vendor/bin/paratest --passthru-php="'-d pcov.enabled=1'"
JUnit Reports:
--functional mode (fixed in v7.22.3).composer update brianium/paratest
Worker Crashes:
--debug to see raw PHPUnit output:
vendor/bin/paratest --debug
Resource Limits:
Allowed memory size exhausted.--processes or increase memory_limit in php.ini.Test Token Conflicts:
TEST_TOKEN collisions in CI.UNIQUE_TEST_TOKEN for per-run uniqueness.Custom Sharding:
Override test distribution via --shard:
vendor/bin/paratest --shard=1-10,20-30 # Run tests 1-10 and 20-30 in parallel
PHPStorm Integration:
ParaTest run configuration:
./vendor/bin/paratest_for_phpstorm.TestDox Reports: Generate human-readable test reports:
vendor/bin/paratest --testdox-text=report.txt --testdox-html=report.html
PHPUnit Events:
TestRunner\Started after TestSuite\Loaded (fixed in v7.14.1).Symfony Compatibility:
Deprecation Warnings:
--display-all-issues to show deprecations:
vendor/bin/paratest --display-all-issues
Max Processes:
Limit CPU usage with --max-processes:
vendor/bin/paratest --max-processes=2 # Use 2 cores max
Do Not Fail: Skip failures for specific test types:
vendor/bin/paratest --do-not-fail-on-risky --do-not-fail-on-incomplete
Useless Tests: Exclude skipped/useless tests from reports:
vendor/bin/paratest --do-not-report-useless-tests
How can I help you explore Laravel packages today?