How to Upgrade to PHPUnit 10 in Diffs

This feature is available since Rector 0.15.12.

PHPUnit 10 was released today. Do you fancy an early upgrade?

We'll show you how to do it with Rector and what other changes you have to handle. Ready?

What has changed regarding the dependencies?

  • PHPUnit 10 now requires PHP 8.1+
  • and it requires Sebastian/diff 5.0 instead of 4.0

The first is a hard requirement, so if you're stuck on PHP 8.0, do not upgrade.


The second one can be vendor locked by other packages. If the Sebastian/diff is a blocker for you, use the composer alias to allow it:

 {
     "require": {
-        "sebastian/diff": "^4.0"
+        "sebastian/diff": "5.0 as 4.0.4"
     }
 }

Update the Differ class

Do you use the sebastian/diff in your code? The Differ class now requires an explicit dependency via a constructor. So add it:

 use SebastianBergmann\Diff\Differ;
 use SebastianBergmann\Diff\Output\StrictUnifiedDiffOutputBuilder;

+$unifiedDiffOutputBuilder = new UnifiedDiffOutputBuilder();
-$differ = new Differ()
+$differ = new Differ($unifiedDiffOutputBuilder);

Update .gitignore paths

New PHPUnit 10 uses the whole directory for caching instead of a single file:

 # .gitignore
-.phpunit.result.cache
+/.phpunit.cache

And the Rest?

  • data providers must be static methods now
  • the @annotations are flipped to #[attributes]
  • the abstract "test" must have TestCase suffix
 use PHPUnit\Framework\TestCase;
+use PHPUnit\Framework\Attributes\DataProvider;

 final class SomeTest extends TestCase
 {
-    /**
-     * @dataProvider provideData()
-     */
+    #[DataProvider('provideData')]
     public function test(int $value)
     {
     }


-    public function provideData()
+    public static function provideData()
     {
        yield [10_0];
     }
}

Note: Do your data providers contain dynamic method calls? You'll need to refactor them to static ones first:

 public static function provideData()
 {
-    yield $this->loadDirectory(__DIR__ . '/Fixtures');
+    yield self::loadDirectory(__DIR__ . '/Fixtures');
 }

The abstract test now has to have *TestCase suffix:

 use PHPUnit\Framework\TestCase;

-abstract AbstractTypeTest extends TestCase
+abstract AbstractTypeTestCase extends TestCase
 {
 }

To handle these, add PHPUnit 10 upgrade set to the rector.php config:

use Rector\Config\RectorConfig;
use Rector\PHPUnit\Set\PHPUnitSetList;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig->sets([
        PHPUnitSetList::PHPUNIT_100,
    ]);
};

Then run Rector on tests to upgrade:

vendor/bin/rector tests

That's it! We made an upgrade of Rector tests based on this tutorial.


Enjoy your new PHPUnit 10 tests today!


Happy coding!