Problem/Motivation

PHPUnit has a faster release cadence than Drupal and drops support for PHP versions quicker than we do. See https://phpunit.de/supported-versions.html. This leads to issues like:

We're also always playing catch up and have to do issues like #2950132: Support PHPUnit 7 optionally in Drupal 8, while keeping support for ^6.5.

Proposed resolution

Symfony does not include phpunit in its composer.json. Instead it uses a custom PHPUnit runner called simple-phpunit that selects the correct PHPUnit version for the PHP version you are running on. It exists to:

Provides a modified version of PHPUnit that does not embed symfony/yaml nor prophecy to prevent any conflicts with these dependencies.

https://symfony.com/doc/current/components/phpunit_bridge.html

Remaining tasks

User interface changes

TBD

API changes

TDB

Data model changes

None

Release notes snippet

@todo

Comments

alexpott created an issue. See original summary.

gábor hojtsy’s picture

Issue tags: +Drupal 9
wim leers’s picture

You mean no more composer run-script drupal-phpunit-upgrade whenever switching core branches? Yes please! 👏

andypost’s picture

So testing_ui core module can expose dependency on simple-phpunit? and no more pain with drupal-phpunit-upgrade and less code to maintain

alexpott’s picture

StatusFileSize
new51.09 KB

Here's a start - this might be a Drupal 9 only thing because we can't have phpunit/phpunit in our autloader and this owrk.

This will not pass a single test on DrupalCI! - we need to work on run-tests.sh to use simple-phpunit to get phpunit's classes installed and into its autoloader. Of course being Drupal 9 only we could decide to gut run-test.sh and make it only about configuration and parallelisation.

However this does work from the command line. To test do something like ./vendor/bin/simple-phpunit -v -c ./core core/tests/Drupal/KernelTests/Core/TypedData/AllowedValuesConstraintValidatorTest.php and watch it get phpunit and run the test.

alexpott’s picture

I've successfully executed a test on PHP 5.5 / 5.6 and 7.2 using the above command :) And no having to run a composer run drupal-update-phpunit command

mondrake’s picture

Uhm, Symfony phpunit-bridge seems even more conservative than Drupal in the PHPUnit version used to run tests.

Trying to summarize below:

PHP Drupal Symfony 3.4 Symfony 4.2 Symfony master
5.5 PHPUnit 4.8.36 PHPUnit 4.8 PHPUnit 4.8 PHPUnit 4.8
5.6 PHPUnit 4.8.36 PHPUnit 5.7 PHPUnit 5.7 PHPUnit 5.7
7 PHPUnit 6.5.14 PHPUnit 5.7 PHPUnit 5.7 PHPUnit 6.5
7.1 PHPUnit 6.5.14 PHPUnit 5.7 PHPUnit 5.7 PHPUnit 7.4
7.2 PHPUnit 6.5.14 PHPUnit 6.5 PHPUnit 6.5 PHPUnit 7.4
7.3 PHPUnit 6.5.14 PHPUnit 6.5 PHPUnit 6.5 PHPUnit 7.4
alexpott’s picture

@mondrake we can do a couple things:

  • Come up with our own matrix but still leverage simple-phpunit using the SYMFONY_PHPUNIT_VERSION constant
  • File upstream PRs

I guess the most future proof will be to use the SYMFONY_PHPUNIT_VERSION constant.

larowlan’s picture

In terms of simpletest ui, we can add a hook_requirements at phase 'install' and prevent it from being installed if the class is missing.

alexpott’s picture

Status: Active » Needs review
StatusFileSize
new55.09 KB
new4.28 KB

Here's an effort at getting run-tests.sh to play nice with simple-phpunit - I think this points towards the idea that we should consider removing Simpletest discovery and relying only on PHPUnit once we don't have Simpletest anymore. We might have to deprecate it during Drupal 9 to make it simpler to do all the things as it hard to work out how to run Simpletest tests in Drupal 8 and get deprecate Simpletest discovery at the same time.

alexpott’s picture

StatusFileSize
new608 bytes
new55.22 KB

Ah we need prophecy...

alexpott’s picture

StatusFileSize
new1.15 KB
new56.36 KB

Fixing update tests

jibran’s picture

StatusFileSize
new1008 bytes
new39.84 KB

Reroll and PHPCS fixes.

jibran’s picture

Seeing following error on each test run.

11:31:37   [Symfony\Component\Console\Exception\RuntimeException]  
11:31:37   Not enough arguments (missing: "packages").             
11:31:37                                                 
alexpott’s picture

StatusFileSize
new1.73 KB
new53.88 KB

Fixing the package thing - interdiff back to #12 because I couldn't apply #13. So my interdiff also includes @jibran coding standards fixes.

alexpott’s picture

StatusFileSize
new70.45 KB

Rebased on 8.8.x now that PHPUnit 4 support has been removed.

alexpott’s picture

StatusFileSize
new1.34 KB
new70.13 KB

Multiple autoloaders are fun. Also this way of testing catches more usages of deprecated code!

xjm’s picture

Priority: Normal » Major
alexpott’s picture

Found an upstream issue whilst working on this. At the moment the Symfony tests listener is registered twice - once via our core/phpunit.xml.dist and once via \Symfony\Bridge\PhpUnit\Legacy\CommandForV6() because the Symfony code doesn't check the phpunit configuration to see if the listener is going to be registered that way. https://github.com/symfony/symfony/pull/31649 fixes this.

alexpott’s picture

StatusFileSize
new3.22 KB
new69.95 KB

Let's see how much a difference the upstream fix makes.

alexpott’s picture

StatusFileSize
new1.24 KB
new69.95 KB
alexpott’s picture

So the tests that are failing on DrupalCI are passing locally - it looks as though DrupalCI is not really using the forked version of phpunit bridge for some reason :(

mondrake’s picture

Don't know if it matters, but it looks like the PHPUnit version being loaded and run is 5.7.27 - not sure there's code to support that one

PHPUnit 5.7.27 by Sebastian Bergmann and contributors.

Testing Drupal\Tests\aggregator\Functional\AddFeedTest
...                                                                 3 / 3 (100%)

Time: 33.99 seconds, Memory: 4.00MB
alexpott’s picture

StatusFileSize
new689 bytes
new69.94 KB

@mondrake yeah that shouldn't be happening so let's fix that.

alexpott’s picture

StatusFileSize
new70.06 KB

Conflicted with commits

alexpott’s picture

StatusFileSize
new3.31 KB
new69.66 KB
mondrake’s picture

+++ b/core/tests/bootstrap.php
@@ -151,6 +151,20 @@ function drupal_phpunit_populate_class_loader() {
+if (!class_exists('PHPUnit_Runner_Version') && !class_exists('PHPUnit\Runner\Version')) {

PHPUnit_Runner_Version is old stuff

alexpott’s picture

@mondrake you're right but we should file another issue about PHPunit 4 code in core/tests/bootstrap.php there's more than just that one line so I think that that is out of scope.

mile23’s picture

Tired of things with the word 'simple' in their name.

That is all.

mile23’s picture

Adventures in simple-phpunit-land….

Note that these experiments don’t use the patch in #26.

It turns out that symfony/phpunit-bridge has different PHP requirements than other symphony components, so we can (and should) bump it right up to 4.3.x. https://packagist.org/packages/symfony/phpunit-bridge

So we do that by changing core/composer.json to have symfony/phpunit-bridge version constraint of @stable.

Then we do the composer shuffle:

$ composer config platform.php 7.0.8
$ composer update symfony/phpunit-bridge —with-dependencies

This gives us:

  - Updating symfony/phpunit-bridge (v3.4.26 => v4.3.1): Loading from cache

Now we can run simple-phpunit. I’ve pinned us to PHPUnit 6.5 since we’re not trying to target other PHPUnit versions in this issue, just get simple-phpunit working.

$ SYMFONY_PHPUNIT_VERSION=6.5 ./vendor/bin/simple-phpunit -c core/ --testsuite unit

This results in a bunch of fails based on deprecations, including this one which is my favorite:

  1x: The "Drupal\Tests\Listeners\DrupalListener" class extends "PHPUnit\Framework\BaseTestListener" that is deprecated Use TestListenerDefaultImplementation trait instead.
    1x in DebugClassLoader::loadClass from Symfony\Component\Debug

This deprecation was introduced in 6.4, so we can change it safely if our minimum PHPUnit is 6.5. https://phpunit.de/announcements/phpunit-7.html

But it's important to note that this deprecation isn't discovered through @trigger_error(). :-)

We can fix this deprecation in #3063182: Remove PHPUnit 4.8 class aliasing BC layer

There’s also a fail that looks like this:

........................................................FF.  2832 / 17904 ( 15%)
.............................................FFF
THE ERROR HANDLER HAS CHANGED!

This typically happens when a test class does not have a result object. That happens when the test errors out and doesn’t complete. So in this case:

[21-Jun-2019 12:04:06 Australia/Sydney] PHP Fatal error:  Cannot redeclare drupal_valid_test_ua() (previously declared in /Users/paul/projects/drupal/core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTest.php:248) in /Users/paul/projects/drupal/core/includes/bootstrap.inc on line 643

And there’s an issue for that: #3054649: DrupalKernelTest results in ERROR HANDLER CHANGED! and/or #3038513: Move drupal_generate_test_ua() into the test system

Applying the patch from #3054649-9: DrupalKernelTest results in ERROR HANDLER CHANGED! we get just a ton of deprecation fails and fails related to the UI test runner.

No doubt many of the deprecation fails relate to the upstream issue @alexpott mentions in #19. https://github.com/symfony/symfony/pull/31649 is targeting 3.4, but we don’t really need that as shown above.

Here concludeth the experimentation. I’m currently trying to figure out if we like this tool better or if we want to have run-tests.sh make code coverage for us: #2974911: Allow run-tests.sh to generate coverage reports

In that issue, we use phpdbg instead of php to run phpunit, and I’m not sure how that will map to using simple-phpunit instead. Also if we don't have a dependency on phpunit/phpunit but we do have a dependency on phpunit/phpcov, what will happen? :-)

mile23’s picture

andypost’s picture

@Mile23 so maybe use simpletest as wrapper to phpunit?

mile23’s picture

I guess I'm generally -1 on using simple-phpunit, for a few reasons:

  • simple-phpunit is Symfony's run-tests.sh. Now we'll have two of them. :-)
  • We don't need PHPUnit 4 any more for 8.8.x, so we can remove all the BC stuff and normalize on 6.5 for now, and make a plan to move on to 7+ as we get closer to Drupal core releases that don't support PHP 7.0. This script won't make that process any easier despite adding complexity.
  • If we shell out to it from run-tests.sh (instead of phpunit), it will go through a composer -> update phpunit phase for every single test class. This is mitigated a little bit by having the new phpunit installed after the first go-through, but it still has to do it.
  • We won't have a local PHPUnit in vendor, so your IDE won't autocomplete while you're writing tests.
  • They might deprecate the script: https://github.com/symfony/symfony/issues/31948

If we definitely need to update PHPUnit to a later version during testing, then we could do that in run-tests.sh. Basically instead of telling you to do it as with the old drupal-phpunit-upgrade script, it would just do it based on a version matrix we can define in the script. That way we can do it once, and then run the tests.

And avoid adding more things named 'simple.' :-)

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Postponed (maintainer needs more info)

Since this was 3 years ago and I imagine there have been many changes for phpunit since then. Is this still needed? and if so what should be done.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Following up if this is still a valid task?

alexpott’s picture

Priority: Major » Normal
Status: Postponed (maintainer needs more info) » Closed (won't fix)

I still think we have problems with the PHPUnit tail wagging the Drupal dog and removing PHPUnit from the dependency chain would be great. There's always a tension about having dependencies on tools.

That said I think closing this task is okay as no one is actively working on this.