How to use PHPUnit extensions with Symfony's PHPUnit Bridge?

1.2k views Asked by At

I'm using PHPUnit Bridge in my Symfony project. I'm currently using PHPUnit 7 and I want to upgrade to PHPUnit 8.

In PHPUnit 8 array subset assertions are deprecated and generate warnings. I want to use dms/phpunit-arraysubset-asserts package to provide them. With regular PHPUnit I'd just composer require it and call it a day.

Now, the Bridge doesn't have original PHPUnit as its dependency, instead it installs it to a temporary folder, patches it and runs from there. phpunit-arraysubset-asserts has PHPUnit dependency though and generates a warning:

Adding phpunit/phpunit as a dependency is discouraged in favor of Symfony's PHPUnit Bridge. 


  * Instead:
    1. Remove it now: composer remove --dev phpunit/phpunit
    2. Use Symfony's bridge: composer require --dev phpunit

I don't want to install phpunit/phpunit to avoid confusion.

I've tried to ignore it by adding a * replacement, but just adding the replacement to composer.json produces a Composer error:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - __root__ No version set (parsed as 1.0.0) conflicts with symfony/phpunit-bridge[v5.0.5].
    - symfony/phpunit-bridge v5.0.5 conflicts with __root__[No version set (parsed as 1.0.0)].
    - Installation request for __root__ No version set (parsed as 1.0.0) -> satisfiable by __root__[No version set (parsed as 1.0.0)].
    - Installation request for symfony/phpunit-bridge v5.0.5 -> satisfiable by symfony/phpunit-bridge[v5.0.5].

What's the correct way to add a PHPUnit extension when using PHPUnit Bridge?

2

There are 2 answers

0
thephilosoft On

WARNING I do not know phpunit-bridge well (in fact today was my first day with it), but I can see the way to achieve what you want. It's not that convenient, but possible. I think it's better to either check with symfony team (maybe there is a supported way for this) or just use plain phpunit (it seems easier and it should be possible to integrate it with symfony's phpunit-bridge without relaying on bridge to install phpunit itself)

# create new symfony project
symfony new gronostaj-phpunit
# cd in it
cd gronostaj-phpunit
# install phpunit-bridge
symfony composer req phpunit-bridge
# to change phpunit version to 9.5
vim phpunit.xml.dist
# install phpunit in symfony bridge way
bin/phpunit
# to update phpunit config
bin/phpunit --migrate-configuration
# black magic begins here
cd bin/.phpunit/phpunit-9.5-0
# to bypass `autoload-dev` in later dump-autoload
mkdir -p tests/_files ; touch tests/_files/CoverageNamespacedFunctionTest.php tests/_files/CoveredFunction.php tests/_files/NamespaceCoveredFunction.php
# install phpunit plugin
composer require --no-plugins dms/phpunit-arraysubset-asserts
# cd back to the root of project
cd -
# create test
--- phpunit/gronostaj-phpunit ‹master* M?› » cat tests/SubsetTest.php 
<?php

declare(strict_types=1);

namespace App\Tests;

use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
use DMS\PHPUnitExtensions\ArraySubset\Assert;
use PHPUnit\Framework\TestCase;

class SubsetTest extends TestCase
{
    use ArraySubsetAsserts;

    public function testWithTrait(): void
    {
        $expectedSubset = ['bar' => 0];
        $content = ['bar' => 0];

        self::assertArraySubset($expectedSubset, $content, true);
    }

    public function testWithDirectCall(): void
    {
        $expectedSubset = ['bar' => 0];
        $content = ['bar' => 0];

        Assert::assertArraySubset($expectedSubset, $content, true);
    }
}
# run test
--- phpunit/gronostaj-phpunit ‹master* M?› » bin/phpunit
PHPUnit 9.5.0 by Sebastian Bergmann and contributors.

Testing 
..                                                                  2 / 2 (100%)

Time: 00:00.006, Memory: 8.00 MB

OK (2 tests, 2 assertions)
# done

For phpunit 8, use phpunit verion 8.0 in phpunit.xml.dist and install your plugin like this composer require --no-plugins 'dms/phpunit-arraysubset-asserts:*', that will work.

To make it reproducible for others in your team you will need to provide composer scripts (to create dummy files and install plugin, but it should do the trick) and hook them into something like post-install and post-update events.

0
Nicolas Clavaud On

I have been struggling with this issue as well in the past, and found this tip in the PHPUnit Bridge documentation:

It is also possible to require additional packages that will be installed along the rest of the needed PHPUnit packages using the SYMFONY_PHPUNIT_REQUIRE env variable. This is specially useful for installing PHPUnit plugins without having to add them to your main composer.json file.

So basically, edit phpunit.xml.dist and declare the env variable under the existing <php> tag:

<php>
    <server name="SYMFONY_PHPUNIT_REQUIRE" value="dms/phpunit-arraysubset-asserts" />
</php>

To add multiple packages, use a space delimiter:

<php>
    <server name="SYMFONY_PHPUNIT_REQUIRE" value="dms/phpunit-arraysubset-asserts spatie/phpunit-snapshot-assertions" />
</php>