ergebnis/phpunit-slow-test-detector
PHPUnit extension (Composer package and PHAR) that detects and reports slow tests during test runs. Configure a global maximum duration; when tests exceed it, the extension lists them with timings to help you spot and fix performance regressions.
composer require --dev ergebnis/phpunit-slow-test-detector
phpunit.xml:
<phpunit ...>
<extensions>
<bootstrap class="Ergebnis\PHPUnit\SlowTestDetector\Extension"/>
</extensions>
</phpunit>
./vendor/bin/phpunit
The tool will now report tests exceeding the default 500ms threshold.Identify slow tests in a CI/CD pipeline or local development to:
CI/CD Pipeline:
composer.json under require-dev.maximum-duration="1000" for 1-second tests).Local Development:
--debug to see detailed timing:
./vendor/bin/phpunit --debug
stderr output for cleaner terminal logs (PHPUnit 6–9):
<phpunit ... stderr="true">
Custom Thresholds:
<phpunit ...>
<extensions>
<bootstrap class="Ergebnis\PHPUnit\SlowTestDetector\Extension"/>
</extensions>
<parameters>
<parameter name="maximum-duration" value="2000" type="int"/>
<parameter name="maximum-count" value="5" type="int"/>
</parameters>
</phpunit>
phpunit.xml files for unit, feature, and integration tests with tailored thresholds.
Example: phpunit.feature.xml:
<phpunit ...>
<extensions>
<bootstrap class="Ergebnis\PHPUnit\SlowTestDetector\Extension"/>
</extensions>
<parameters>
<parameter name="maximum-duration" value="3000" type="int"/>
</parameters>
</phpunit>
phpunit Artisan command to pass custom configs:
// app/Console/Kernel.php
protected $commands = [
\Illuminate\Foundation\Console\Artisan::class,
\App\Console\Commands\RunSlowTests::class, // Custom command
];
// app/Console/Commands/RunSlowTests.php
public function handle()
{
$this->call('phpunit', [
'--configuration' => 'phpunit.slow.xml',
]);
}
PHPUnit Version Mismatch:
Class not found or Invalid configuration.<listeners>, while 10+ uses <extensions>).Threshold Overrides:
@slow) are used.<parameters> in phpunit.xml for global control.CI Timeouts:
maximum-duration conservatively (e.g., 2–3x your CI timeout).phpunit --debug output).maximum-duration="50" for fast tests).stderr to a file for CI logs:
./vendor/bin/phpunit 2> slow-tests.log
Custom Reporters:
Extend the Ergebnis\PHPUnit\SlowTestDetector\Reporter\DefaultReporter to format output (e.g., JSON for APIs):
use Ergebnis\PHPUnit\SlowTestDetector\Reporter\DefaultReporter;
use Ergebnis\PHPUnit\SlowTestDetector\Reporter\SlowTest;
class JsonReporter extends DefaultReporter {
public function report(SlowTest $slowTest) {
echo json_encode($slowTest->toArray()) . PHP_EOL;
}
}
Register it in phpunit.xml:
<extensions>
<bootstrap class="Ergebnis\PHPUnit\SlowTestDetector\Extension"/>
<service class="App\Tests\JsonReporter" method="register"/>
</extensions>
Dynamic Thresholds:
Use environment variables or Laravel’s .env to adjust thresholds:
<parameters>
<parameter name="maximum-duration" value="{env('TEST_SLOW_THRESHOLD')}" type="int"/>
</parameters>
Set in .env:
TEST_SLOW_THRESHOLD=1500
Excluding Tests: Skip specific tests from detection by annotating them:
/**
* @slow-exclude
*/
public function testExternalApiCall() { ... }
How can I help you explore Laravel packages today?