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:
- #3039275: phpunit-mock-objects is marked as "abandoned" when composer.lock is rebuilt
- #2927806: Use PHPUnit 6 for testing when PHP version >= 7.2
- #2937469: Automatic upgrade to PHPUnit 6 is dangerous
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
- Implement.
- I think we should consider moving to simple-phpunit in Drupal 8 and deprecating PHPUnit via composer.json somehow and then removing that in Drupal 9
- A big unresolved question is if we do this what happens to the testing user interface? It would need to detect that simple-phpunit has been run to get the dependencies or something like that. See #3028663: Split up simpletest into simpletest and testing_ui to enable easier decisions for Drupal 9 for more about the testing UI
User interface changes
TBD
API changes
TDB
Data model changes
None
Release notes snippet
@todo
| Comment | File | Size | Author |
|---|---|---|---|
| #26 | 3039344-26.patch | 69.66 KB | alexpott |
| #26 | 25-26-interdiff.txt | 3.31 KB | alexpott |
Comments
Comment #2
gábor hojtsyComment #3
wim leersYou mean no more
composer run-script drupal-phpunit-upgradewhenever switching core branches? Yes please! 👏Comment #4
andypostSo testing_ui core module can expose dependency on simple-phpunit? and no more pain with
drupal-phpunit-upgradeand less code to maintainComment #5
alexpottHere'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.phpand watch it get phpunit and run the test.Comment #6
alexpottI'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-phpunitcommandComment #7
mondrakeUhm, Symfony phpunit-bridge seems even more conservative than Drupal in the PHPUnit version used to run tests.
Trying to summarize below:
Comment #8
alexpott@mondrake we can do a couple things:
I guess the most future proof will be to use the SYMFONY_PHPUNIT_VERSION constant.
Comment #9
larowlanIn terms of simpletest ui, we can add a hook_requirements at phase 'install' and prevent it from being installed if the class is missing.
Comment #10
alexpottHere'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.
Comment #11
alexpottAh we need prophecy...
Comment #12
alexpottFixing update tests
Comment #13
jibranReroll and PHPCS fixes.
Comment #14
jibranSeeing following error on each test run.
Comment #15
alexpottFixing the package thing - interdiff back to #12 because I couldn't apply #13. So my interdiff also includes @jibran coding standards fixes.
Comment #16
alexpottRebased on 8.8.x now that PHPUnit 4 support has been removed.
Comment #17
alexpottMultiple autoloaders are fun. Also this way of testing catches more usages of deprecated code!
Comment #18
xjmComment #19
alexpottFound 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.
Comment #20
alexpottLet's see how much a difference the upstream fix makes.
Comment #21
alexpottComment #22
alexpottSo 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 :(
Comment #23
mondrakeDon'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
Comment #24
alexpott@mondrake yeah that shouldn't be happening so let's fix that.
Comment #25
alexpottConflicted with commits
Comment #26
alexpottComment #27
mondrakePHPUnit_Runner_Versionis old stuffComment #28
alexpott@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.
Comment #29
mile23Tired of things with the word 'simple' in their name.
That is all.
Comment #30
mile23Adventures 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:
This gives us:
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.
This results in a bunch of fails based on deprecations, including this one which is my favorite:
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:
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:
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? :-)
Comment #31
mile23There's also this: https://github.com/symfony/symfony/issues/31948
Comment #32
andypost@Mile23 so maybe use simpletest as wrapper to phpunit?
Comment #33
mile23I guess I'm generally -1 on using simple-phpunit, for a few reasons:
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.' :-)
Comment #41
smustgrave commentedSince 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.
Comment #43
smustgrave commentedFollowing up if this is still a valid task?
Comment #44
alexpottI 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.