ergebnis/phpunit-slow-test-detector

Provides facilities for detecting slow tests in phpunit/phpunit.

Installs: 7 334 352

Dependents: 74

Suggesters: 0

Security: 0

Stars: 143

Watchers: 3

Forks: 11

Open Issues: 8

pkg:composer/ergebnis/phpunit-slow-test-detector

2.22.1 2026-02-08 13:42 UTC

README

Integrate Merge Release Renew

Code Coverage

Latest Stable Version Total Downloads Monthly Downloads

This project provides a composer package and a Phar archive with an extension for detecting slow tests in phpunit/phpunit.

Example

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 (00:00.500).

 1. 00:01.604 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#9
 2. 00:01.505 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#8
 3. 00:01.403 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#7
 4. 00:01.303 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#6
 5. 00:01.205 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#5
 6. 00:01.103 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#4
 7. 00:01.005 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#3
 8. 00:00.905 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#2
 9. 00:00.805 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#1
10. 00:00.705 Ergebnis\PHPUnit\SlowTestDetector\Test\EndToEnd\Default\SleeperTest::testSleeperSleepsLongerThanDefaultMaximumDurationWithDataProvider#0

There is 1 additional slow test that is not listed here.

Time: 00:12.601, Memory: 8.00 MB

OK (13 tests, 13 assertions)

Compatibility

The extension is compatible with the following versions of phpunit/phpunit:

Installation

Installation with composer

Run

composer require --dev ergebnis/phpunit-slow-test-detector

to install ergebnis/phpunit-slow-test-detector as a composer package.

Installation as Phar

Download phpunit-slow-test-detector.phar from the latest release.

Usage

Bootstrapping the extension

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.

Bootstrapping the extension as a composer package

To bootstrap the extension as a composer package when using

  • phpunit/phpunit:^13.0.0
  • phpunit/phpunit:^12.0.0
  • phpunit/phpunit:^11.0.0
  • phpunit/phpunit:^10.0.0

adjust 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"
 >
+    <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.0
  • phpunit/phpunit:^8.5.19
  • phpunit/phpunit:^7.5.0

adjust 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"
 >
+    <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.0

adjust 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>

Bootstrapping the extension as a PHAR

To bootstrap the extension as a PHAR when using

  • phpunit/phpunit:^13.0.0
  • phpunit/phpunit:^12.0.0
  • phpunit/phpunit:^11.0.0
  • phpunit/phpunit:^10.0.0

adjust 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"
+    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.0
  • phpunit/phpunit:^8.5.19
  • phpunit/phpunit:^7.5.0

adjust 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"
+    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>

Configuring the extension

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 10
  • maximum-duration, an int, the maximum duration in milliseconds for a test before the extension considers it as a slow test, defaults to 500

The configuration mechanism depends on the version of phpunit/phpunit you are using.

Configuring the extension

To configure the extension when using

  • phpunit/phpunit:^13.0.0
  • phpunit/phpunit:^12.0.0
  • phpunit/phpunit:^11.0.0
  • phpunit/phpunit:^10.0.0

adjust your phpunit.xml configuration file and configure one or more

The 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.0
  • phpunit/phpunit:^8.5.19
  • phpunit/phpunit:^7.5.0

adjust your phpunit.xml configuration file and configure the

The 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>
-        <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>
+                </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.0

adjust your phpunit.xml configuration file and configure the

The 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"
 >
     <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>
+                </array>
+            </arguments>
+        </listener>
     </listeners>
     <testsuites>
         <testsuite name="unit">
             <directory>test/Unit/</directory>
        </testsuite>
     </testsuites>
 </phpunit>

Configuring the maximum duration per test case

You can configure the maximum duration for a single test case with

  • an Attribute\MaximumDuration attribute when using
    • phpunit/phpunit:^13.0.0
    • phpunit/phpunit:^12.0.0
    • phpunit/phpunit:^11.0.0
    • phpunit/phpunit:^10.0.0
  • a @maximumDuration annotation in the DocBlock when using
    • phpunit/phpunit:^9.0.0
    • phpunit/phpunit:^8.5.19
    • phpunit/phpunit:^7.5.0
    • phpunit/phpunit:^6.5.0
  • a @slowThreshold annotation in the DocBlock when using
    • phpunit/phpunit:^9.0.0
    • phpunit/phpunit:^8.5.19
    • phpunit/phpunit:^7.5.0
    • phpunit/phpunit:^6.5.0

The 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 @slowThreshold annotation exists only to help you move from johnkary/phpunit-speedtrap. It will be deprecated and removed in the near future.

Understanding measured test durations

Understanding measured test durations when using the new event system

When using

  • phpunit/phpunit:^13.0.0
  • phpunit/phpunit:^12.0.0
  • phpunit/phpunit:^11.0.0
  • phpunit/phpunit:^10.0.0

the 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.

Understanding measured test durations when using the hooks event system

When using

  • phpunit/phpunit:^9.0.0
  • phpunit/phpunit:^8.5.19
  • phpunit/phpunit:^7.5.0
  • phpunit/phpunit:^6.5.0

the 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/phpunit executes tests.

Changelog

The maintainers of this project record notable changes to this project in a changelog.

Contributing

The maintainers of this project suggest following the contribution guide.

Code of Conduct

The maintainers of this project ask contributors to follow the code of conduct.

General Support Policy

The maintainers of this project provide limited support.

You can support the maintenance of this project by sponsoring @ergebnis.

PHP Version Support Policy

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.

Security Policy

This project has a security policy.

License

This project uses the MIT license.

Credits

This package is inspired by johnkary/phpunit-speedtrap, originally licensed under MIT by John Kary.

Social

Follow @localheinz and @ergebnis on Twitter.