ergebnis/phpunit-slow-test-detector
Detect slow PHPUnit tests with an extension delivered as a Composer package or PHAR. Configure a global maximum duration and get a report of tests exceeding the threshold after each run—ideal for catching performance regressions in your suite.
This project provides a composer package and a Phar archive with an extension for detecting slow tests in phpunit/phpunit.
After installing, configuring, and bootstrapping the extension, when running your tests with phpunit/phpunit, the extension will report slow tests:
PHPUnit 10.0.0 by Sebastian Bergmann and contributors.
Runtime: PHP 8.1.0
Configuration: test/EndToEnd/Default/phpunit.xml
Random Seed: 1676103726
............. 13 / 13 (100%)
Detected 11 tests where the duration exceeded the global maximum duration (0.500).
# Duration Test
----------------------------------------------------------------------------------------------------------------------------------------------------
1 1.604 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#9
2 1.505 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#8
3 1.403 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#7
4 1.303 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#6
5 1.205 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#5
6 1.103 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#4
7 1.005 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#3
8 0.905 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#2
9 0.805 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#1
10 0.705 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#0
----------------------------------------------------------------------------------------------------------------------------------------------------
0.000
└─── seconds
There is 1 additional slow test that is not listed here.
Time: 00:12.601, Memory: 8.00 MB
OK (13 tests, 13 assertions)
The extension is compatible with the following versions of phpunit/phpunit:
phpunit/phpunit:^13.0.0phpunit/phpunit:^12.0.0phpunit/phpunit:^11.0.0phpunit/phpunit:^10.0.0phpunit/phpunit:^9.0.0phpunit/phpunit:^8.5.19phpunit/phpunit:^7.5.0phpunit/phpunit:^6.5.0composerRun
composer require --dev ergebnis/phpunit-slow-test-detector
to install ergebnis/phpunit-slow-test-detector as a composer package.
Download phpunit-slow-test-detector.phar from the latest release.
Before the extension can detect slow tests in phpunit/phpunit, you need to bootstrap it. The bootstrapping mechanism depends on the version of phpunit/phpunit you are using.
composer packageTo bootstrap the extension as a composer package when using
phpunit/phpunit:^13.0.0phpunit/phpunit:^12.0.0phpunit/phpunit:^11.0.0phpunit/phpunit:^10.0.0adjust your phpunit.xml configuration file and configure the
extensions element on phpunit/phpunit:^13.0.0extensions element on phpunit/phpunit:^12.0.0extensions element on phpunit/phpunit:^11.0.0extensions element on phpunit/phpunit:^10.0.0 <phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
>
+ <extensions>
+ <bootstrap class="Ergebnis\PHPUnit\SlowTestDetector\Extension"/>
+ </extensions>
<testsuites>
<testsuite name="unit">
<directory>test/Unit/</directory>
</testsuite>
</testsuites>
</phpunit>
To bootstrap the extension as a composer package when using
phpunit/phpunit:^9.0.0phpunit/phpunit:^8.5.19phpunit/phpunit:^7.5.0adjust your phpunit.xml configuration file and configure the
extensions element on phpunit/phpunit:^9.0.0extensions element on phpunit/phpunit:^8.5.19extensions element on phpunit/phpunit:^7.5.0 <phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
>
+ <extensions>
+ <extension class="Ergebnis\PHPUnit\SlowTestDetector\Extension"/>
+ </extensions>
<testsuites>
<testsuite name="unit">
<directory>test/Unit/</directory>
</testsuite>
</testsuites>
</phpunit>
To bootstrap the extension as a composer package when using
phpunit/phpunit:^6.5.0adjust your phpunit.xml configuration file and configure the
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
>
+ <listeners>
+ <listener class="Ergebnis\PHPUnit\SlowTestDetector\Extension"/>
+ </listeners>
<testsuites>
<testsuite name="unit">
<directory>test/Unit/</directory>
</testsuite>
</testsuites>
</phpunit>
To bootstrap the extension as a PHAR when using
phpunit/phpunit:^13.0.0phpunit/phpunit:^12.0.0phpunit/phpunit:^11.0.0phpunit/phpunit:^10.0.0adjust your phpunit.xml configuration file and configure the
extensionsDirectory attribute and the extensions element on phpunit/phpunit:^13.0.0extensionsDirectory attribute and the extensions element on phpunit/phpunit:^12.0.0extensionsDirectory attribute and the extensions element on phpunit/phpunit:^11.0.0extensionsDirectory attribute and the extensions element on phpunit/phpunit:^10.0.0 <phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
+ extensionsDirectory="directory/where/you/saved/the/extension/phars"
>
+ <extensions>
+ <extension class="Ergebnis\PHPUnit\SlowTestDetector\Extension"/>
+ </extensions>
<testsuites>
<testsuite name="unit">
<directory>test/Unit/</directory>
</testsuite>
</testsuites>
</phpunit>
To bootstrap the extension as a PHAR when using
phpunit/phpunit:^9.0.0phpunit/phpunit:^8.5.19phpunit/phpunit:^7.5.0adjust your phpunit.xml configuration file and configure the
extensionsDirectory attribute and the extensions element on phpunit/phpunit:^9.0.0extensionsDirectory attribute and the extensions element on phpunit/phpunit:^8.5.19extensionsDirectory attribute and the extensions element on phpunit/phpunit:^7.5.0 <phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
+ extensionsDirectory="directory/where/you/saved/the/extension/phars"
>
+ <extensions>
+ <bootstrap class="Ergebnis\PHPUnit\SlowTestDetector\Extension"/>
+ </extensions>
<testsuites>
<testsuite name="unit">
<directory>test/Unit/</directory>
</testsuite>
</testsuites>
</phpunit>
You can configure the extension with the following options in your phpunit.xml configuration file:
maximum-count, an int, the maximum count of slow test that should be reported, defaults to 10maximum-duration, an int, the maximum duration in milliseconds for a test before the extension considers it as a slow test, defaults to 500stderr, a bool, directs the slow test report output to stderr, defaults to false, only available on phpunit/phpunit:^6.5.0, phpunit/phpunit:^7.5.0, phpunit/phpunit:^8.5.19, and phpunit/phpunit:^9.0.0 (on phpunit/phpunit:^10.0.0 and later, the extension automatically respects the stderr configuration phpunit/phpunit)The configuration mechanism depends on the version of phpunit/phpunit you are using.
To configure the extension when using
phpunit/phpunit:^13.0.0phpunit/phpunit:^12.0.0phpunit/phpunit:^11.0.0phpunit/phpunit:^10.0.0adjust your phpunit.xml configuration file and configure one or more
parameter elements on phpunit/phpunit:^13.0.0parameter elements on phpunit/phpunit:^12.0.0parameter elements on phpunit/phpunit:^11.0.0parameter elements on phpunit/phpunit:^10.0.0The following example configures the maximum count of slow tests to three, and the maximum duration for all tests to 250 milliseconds:
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
>
<extensions>
- <bootstrap class="Ergebnis\PHPUnit\SlowTestDetector\Extension"/>
+ <bootstrap class="Ergebnis\PHPUnit\SlowTestDetector\Extension">
+ <parameter name="maximum-count" value="3"/>
+ <parameter name="maximum-duration" value="250"/>
+ </bootstrap>
</extensions>
<testsuites>
<testsuite name="unit">
<directory>test/Unit/</directory>
</testsuite>
</testsuites>
</phpunit>
To configure the extension when using
phpunit/phpunit:^9.0.0phpunit/phpunit:^8.5.19phpunit/phpunit:^7.5.0adjust your phpunit.xml configuration file and configure the
arguments element on phpunit/phpunit:^9.0.0arguments element on phpunit/phpunit:^8.5.19arguments element on phpunit/phpunit:^7.5.0The following example configures the maximum count of slow tests to three, the maximum duration for all tests to 250 milliseconds, and directs the slow test report output to stderr:
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
>
<extensions>
- <extension class="Ergebnis\PHPUnit\SlowTestDetector\Extension"/>
+ <extension class="Ergebnis\PHPUnit\SlowTestDetector\Extension">
+ <arguments>
+ <array>
+ <element key="maximum-count">
+ <integer>3</integer>
+ </element>
+ <element key="maximum-duration">
+ <integer>250</integer>
+ </element>
+ <element key="stderr">
+ <boolean>true</boolean>
+ </element>
+ </array>
+ </arguments>
+ </extension>
</extensions>
<testsuites>
<testsuite name="unit">
<directory>test/Unit/</directory>
</testsuite>
</testsuites>
</phpunit>
To configure the extension when using
phpunit/phpunit:^6.5.0adjust your phpunit.xml configuration file and configure the
The following example configures the maximum count of slow tests to three, the maximum duration for all tests to 250 milliseconds, and directs the slow test report output to stderr:
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
>
<listeners>
- <listener class="Ergebnis\PHPUnit\SlowTestDetector\Extension"/>
+ <listener class="Ergebnis\PHPUnit\SlowTestDetector\Extension">
+ <arguments>
+ <array>
+ <element key="maximum-count">
+ <integer>3</integer>
+ </element>
+ <element key="maximum-duration">
+ <integer>250</integer>
+ </element>
+ <element key="stderr">
+ <boolean>true</boolean>
+ </element>
+ </array>
+ </arguments>
+ </listener>
</listeners>
<testsuites>
<testsuite name="unit">
<directory>test/Unit/</directory>
</testsuite>
</testsuites>
</phpunit>
You can configure the maximum duration for a single test case with
Attribute\MaximumDuration attribute when using
phpunit/phpunit:^13.0.0phpunit/phpunit:^12.0.0phpunit/phpunit:^11.0.0phpunit/phpunit:^10.0.0@maximumDuration annotation in the DocBlock when using
phpunit/phpunit:^9.0.0phpunit/phpunit:^8.5.19phpunit/phpunit:^7.5.0phpunit/phpunit:^6.5.0@slowThreshold annotation in the DocBlock when using
phpunit/phpunit:^9.0.0phpunit/phpunit:^8.5.19phpunit/phpunit:^7.5.0phpunit/phpunit:^6.5.0The following example configures the maximum durations for single test cases to 5,000 ms, 4,000 ms, and 3,000 ms:
<?php
declare(strict_types=1);
use PHPUnit\Framework;
use Ergebnis\PHPUnit\SlowTestDetector;
final class ExtraSlowTest extends Framework\TestCase
{
#[SlowTestDetector\Attribute\MaximumDuration(5000)]
public function testExtraExtraSlow(): void
{
// ...
}
/**
* @maximumDuration 4000
*/
public function testAlsoQuiteSlow(): void
{
// ...
}
/**
* @slowThreshold 3000
*/
public function testQuiteSlow(): void
{
// ...
}
}
[!NOTE]
Support for the
@slowThresholdannotation exists only to help you move fromjohnkary/phpunit-speedtrap. It will be deprecated and removed in the near future.
When using
phpunit/phpunit:^13.0.0phpunit/phpunit:^12.0.0phpunit/phpunit:^11.0.0phpunit/phpunit:^10.0.0the extension uses the new event system of phpunit/phpunit, and measures the duration between the points in time when the PHPUnit\Event\Test\PreparationStarted and PHPUnit\Event\Test\Finished are emitted.
When using
phpunit/phpunit:^9.0.0phpunit/phpunit:^8.5.19phpunit/phpunit:^7.5.0phpunit/phpunit:^6.5.0the extension uses the hooks event system of phpunit/phpunit, and measures the duration that is passed to the PHPUnit\Runner\AfterTestHook. This is the duration of invoking PHPUnit\Framework\TestCase::runBare() and more.
[!NOTE] Because of this behavior, the measured test durations can and will vary depending on the order in which
phpunit/phpunitexecutes tests.
The maintainers of this project record notable changes to this project in a changelog.
The maintainers of this project suggest following the contribution guide.
The maintainers of this project ask contributors to follow the code of conduct.
The maintainers of this project provide limited support.
You can support the maintenance of this project by sponsoring @ergebnis.
This project supports PHP versions with active and security support.
The maintainers of this project add support for a PHP version following its initial release and drop support for a PHP version when it has reached the end of security support.
This project has a security policy.
This project uses the MIT license.
This package is inspired by johnkary/phpunit-speedtrap, originally licensed under MIT by John Kary.
Follow @localheinz and @ergebnis on Twitter.
How can I help you explore Laravel packages today?