Problem/Motivation
Child of #3110543: [meta] Support PHPUnit 9 in Drupal 9, this is to effectively add support for PHPUnit 9. This also resolves half of the 29 dependency issues when attempting to make Drupal 9 core compatible with PHP 8. See #3109885: [meta] Ensure compatibility of Drupal 9 with PHP 8.0 (as it evolves).
Proposed resolution
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
Drupal 9 now uses PHPUnit 9 to run tests on PHP versions higher than PHP 7.3. This prepares Drupal core to support PHP 8 when it is released, but may require some small changes to tests in contributed or custom modules. See the change record for more details.
Comment | File | Size | Author |
---|---|---|---|
#111 | 3127141-111.patch | 38.99 KB | alexpott |
#111 | pseudo-interdiff.txt | 3.46 KB | alexpott |
#100 | 3127141-100.patch | 38.67 KB | mondrake |
#100 | interdiff_97-100.txt | 1.93 KB | mondrake |
Comments
Comment #2
mondrakeInitial patch. We're not that far, we basically only miss the remaining issues to replace the usage of reflection-enabled PHPUnit methods, plus silencing the new warnings actually being added in PHPUnit 9.
Comment #4
mondrakeConverting some calls to deprecated methods in tests that extend directly from PHPUnit's TestCase.
Comment #5
mondrakeWith some version dependency dance to allow both PHPUnit 8 and 9 results printers.
Comment #8
mondrakeComment #9
longwaveNice work!
We probably want to rename this trait to just e.g. PhpUnitWarnings now?
Comment #10
Neslee Canil PintoChanged as per #9
Comment #11
mondrake#9 yes, that trait is going to stay around, better have a more permanent naming...
Comment #12
mondrake@Neslee what @longwave means is to rename the trait and all its usages. For example from
PHPUnit8Warnings
ToPhpUnitWarningsCompatibiltyTrait
Comment #14
mondrakeLet’s wait for the PHPUnit8 deprecation issues to land, first.
Comment #15
mondrakeComment #16
mondrakeWe're in home run :)
Comment #18
mondrakePHPUnit 9 probably changed something in the checking of assertContains of arrays - now the sequence of the keys in the array matters, so prior to calling assertContains in nested arrays we need to ensure sorting of keys...
Comment #19
mondrakeAlso, type checking has become strict.
Comment #22
mondrakeSimplified the failing test, and made changes to allow running on PHP 7.3
Comment #23
longwaveInstead of sorting in #18 can we improve the assertions? We know the array key in at least some of the cases, I think?
Comment #24
mondrake#24 I do not see anything wrong in sorting before asserting. Actually for equality comparison there’s a
assertEqualsCanonicalizing
in pure PHPUnit... but no such thing as an assertContainsCanonicalizing AFAICS.Comment #25
longwaveWe don't need to sort the arrays or change MessengerTest - we can just use
assertContainsEquals()
which is less strict.Comment #26
mondrakeGood catch @longwave!
Unfortunately that method is not documented in the PHPUnit docs, although it’s clear that it is supported
https://thephp.cc/news/2019/02/help-my-tests-stopped-working
https://github.com/sebastianbergmann/phpunit/issues/3511
Comment #27
mondrakeFiled issue upstream reagrding the missing documentation,
https://github.com/sebastianbergmann/phpunit/issues/4181
Comment #28
mondrakeRerolled.
EDIT - note I've been using a
-M20%
argument forgit diff
to allow comparing the PHPUnitWarning traitComment #30
mondrakeLooks like PHPUnit 9.1.2 broke Symfony's PHPUnit Bridge. Pros and cons of getting closer to the edge of dependencies'. Let's just see this.
Comment #31
longwaveUpstream issue to follow for phpunit-bridge is https://github.com/symfony/symfony/issues/36499
Comment #32
mondrakeNevertheless, I think we should avoid a caret constraint for PHPUnit in composer.json, and work with ranges instead. Then extend the range only when tested OK. PHPUnit is rather aggressive on changing its internals (not blaming, it has pros and cons), and #31 is a smoking gun example of possible impacts.
Comment #33
mondrakeComment #34
longwaveSymfony fixed the issue on their side so I think we have to wait for new Symfony releases and then bump our dependency on the phpunit-bridge.
Comment #35
mondrakeRerolled.
Comment #36
mondrake#34 that would exclude the faulty 9.1.2 PHPUnit version too, nevertheless I think we should make it explicit ourselves either in the
require-dev
or theconflict
sections in composer.jsonComment #37
longwaveSymfony already added a conflict with PHPUnit 9.1.2 and kept a BC layer for <9.1.2 so I think we just have to bump the version of phpunit-bridge and we are all OK.
Comment #38
mondrakeSymfony 4.4.8 is out with the fix for #30.
Comment #39
mondrakeReuqesting the latest phpunit-bridge version, albeit not updating the lock file, yet.
Comment #41
mondrakeComment #42
longwaveWorks for me, let's see what core committers think.
Comment #43
alexpottI'm not a huge fan of this. PHPUnit 8 supports PHP 7.4 so we're enforcing an upgrade that's not necessary.
This doesn't look right.
Comment #44
mondrakeThanks @alexpott
Re. 1 what's next then? PHP 8.0 is still way to go. Moving D9 straight to PHPUnit9 seemed to me too long a step from D8 (which is still supporting PHPUnit6). IMHO testing PHP 7.3 on PHPUnit8 and PHP 7.4 on PHPUnit9 could be a compromise to start work on migrating the test assertions from Simpletest to PHPUnit native (and recent) ones, while at the same time keeping an eye on further evolutions of PHPUnit, starting earlier when possible any adjustment work.
Re. 2 it's not, and it's been corrected in #41.
Comment #45
longwaveI think I agree that until we have a PHP 8 to test on, testing PHP 7.3 on PHPUnit 8 and PHP 7.4 on PHPUnit 9 seems like a good compromise. Therefore the code in Drupal\Core\Composer\Composer::upgradePHPUnit does the right thing to get both of these tested on the testbot. However, the message in run-tests.sh is not strictly true - PHPUnit 9 is not strictly required on PHP 7.4, maybe we need to reword this?
The other option is just postpone this entirely until PHP 8 forces us to upgrade, I guess. We have still fixed all the deprecations to date - having said that there may be more to come, and it would be good to keep on top of them.
Comment #46
mondrakeComment #47
mondrakeRerolled.
Comment #48
mondrakeComment #49
mondrakeComment #50
mondrakeComment #51
mondrakeComment #52
mondrakeAn alternative for #43.1 could be not to upgrade to PHPUnit 9 based on the PHP verison, here. Just loosen the composer.json constraint. Then, in a NO-COMMIT issue, kept in RTBC, just add a container command to upgrade to PHPUnit 9, so that a regular run can report failures. Feels fragile, but also the only possibility I see here ATM (I saw something like for some time for hi-lo dependencies testing).
Comment #53
mondrakeReroll.
Comment #54
alexpottThis is a critical tasks because it blocks PHP 8 adoption.
Comment #55
alexpottRerolled... git took care of it with a 3 way merge.
Comment #56
mondrakeRerolled.
Comment #58
andypostComment #59
mondrakeComment #60
Suresh Prabhu Parkala CreditAttribution: Suresh Prabhu Parkala at Specbee commentedRe-rolled patch please review!
Comment #62
mondrakeAdded the above to silenced warnings.
Comment #64
mondrakePHPUnit 9.5.3 removes 'phpunit/php-token-stream' from its dependencies.
Comment #65
mondrakeComment #66
mondrakeSorry.
Comment #67
longwaveShould we look to fix this here?
Comment #68
mondrake#67 we can try, but we need to keep it compatible with PHPUnit 8...
Comment #69
longwaveAh yeah, it will still give the warning if the XML doesn't validate, and we need to keep the old elements for BC, so we might as well wait until we have a minimum of PHPUnit 9.
I tried this locally anyway and ran into https://github.com/sebastianbergmann/phpunit/issues/4419
Comment #70
longwaveIn which case back to RTBC on this, and core committers can decide whether we only require PHPUnit 9 in PHP 8 or allow it in 7.4.
Comment #71
xjm@catch brought this up to the committer team -- I'd like to have a think about it, so tagging for RM review.
Comment #72
alexpottThe test fail on #66 seems to show we have a problem on PHP 7.3?
Also I think we should block this on #3142267: Allow the full list of deprecations from PHPUnit8Warning to respect the --suppress-deprecations behavior on DrupalCI - that changes the PHPUnit8Warnings class to trigger deprecation messages so we then only have to maintain a single list of technical debt in \Drupal\Tests\Listeners\DeprecationListenerTrait::getSkippedDeprecations() - at the very least this patch should make the same change.
Comment #73
mondrakeWe would have to update the content-hash in the composer.lock file, to reflect the change in require-dev constraints, but I am refraining to do so since the patch would then require continuous rerolls. When you run the phpunit-update script (i.e. when testing on 7.4 ATM) this is not failing since the composer.lock file hash gets refreshed as part of the build.
Comment #74
ravi.shankar CreditAttribution: ravi.shankar at OpenSense Labs commentedPatch #66 didn't apply anyomore on Drupal 9.1.x, so here I have added reroll of patch #66.
Comment #75
mondrakeLet’s postpone per #72 then.
Comment #76
mondrakeComment #77
mondrakeComment #78
mondrakeNew patch, built on top of #3142267: Allow the full list of deprecations from PHPUnit8Warning to respect the --suppress-deprecations behavior on DrupalCI.
Comment #79
mondrakeHuh, #78 apparently fails since some test classes use
::prophesize
in data provider methods and the deprecation cannot be silenced in that case?(apart from the failures of
PhpUnitWarningsTest
that are expected given #3142267-58: Allow the full list of deprecations from PHPUnit8Warning to respect the --suppress-deprecations behavior on DrupalCI)Comment #80
Gábor HojtsyWow, this resolves half of the 29 dependency issues when attempting to make Drupal 9 core compatible with PHP 8. (#3109885: [meta] Ensure compatibility of Drupal 9 with PHP 8.0 (as it evolves))
Comment #81
andypostBlocker commited
Comment #82
mondrake#78 for review patch, renamed.
Comment #83
mondrakeLet's see if we can require
phpspec/prophecy-phpunit
in thedrupal-phpunit-upgrade
, and start using the trait.Comment #84
mondrakeI think we need to bring back our old friend
PhpunitCompatibilityTrait
from D8.9, to enable PHPUnit version dependent shims. See #3142267-62: Allow the full list of deprecations from PHPUnit8Warning to respect the --suppress-deprecations behavior on DrupalCI.Comment #85
mondrakeComment #86
mondrakeSkipping all tests in PhpUnitWarningsTest when executed under PHPUnit9. I suggest to leave adding back FC shims, where possible, to follow-ups. Added the
PhpUnitCompatibilityTrait
, which is imported in all base classes.Comment #87
mondrakeComment #88
mondrakeComment #89
longwaveTo update the hash you can run
composer update --lock
and it will update the hash but leave the packages alone.Comment #90
alexpottThis should be extending use Drupal\Tests\UnitTestCase; and not the Phpunit class. It's a test in a module and there's no reason to not extend the Drupal base class.
Comment #91
mondrake#90 is it in scope here or a follow-up?
Comment #92
alexpottI think it is in scope - the changes necessary to the test system show that that test is not inheriting from the correct class.
Comment #93
mondrakeAddressed #90.
Comment #94
alexpottI've reviewed all the component test changes are it looks like a few changes can be made.
This is not necessary here.
Should be
use PhpUnitCompatibilityTrait;
instead.Now we're using the trait I don't think we need this message here anymore.
Comment #95
alexpottFor #94
Comment #96
mondrakeAddresses #94, thanks.
#94.3 - we can remove from the deprecation silencers, but not from the PhpUnitWarnings trait unless we accept contrib to fail with PHPUnit warnings.
Comment #97
alexpottFirst thought was good point. But then I realised that our base test classes are all using the compatibility trait and therefore we should be able to remove it. We don't support contrib / custom not extending from our base classes.
Comment #98
mondrakeComment #99
mondrake#97 to be addressed
Comment #100
mondrakeFixed #97.
Comment #101
longwaveIt looks like all review points have been addressed.
Comment #102
mondrakeLet's be clear.
Comment #103
mondrakeFiled #3174200: Use PHPUnit-bridge polyfills for forward compatibility layer as a possible follow-up, for discussion.
Comment #104
alexpottRe #102 I don't think that is clear actually. PHPUnit 9 is not necessary for testing on PHP 7.4 - it is for PHP 8.0. We don't require PHPUnit 9 to run tests on PHP 7.4 - if you use the phpunit runner.
Comment #106
alexpottLooks like a random JS fail
Comment #107
catchWe probably could have done this in a spin-off issue to make the diff here smaller, but it doesn't really hurt. The method is already available to contrib modules to do the same thing so not much we can do about it ourselves.
Comment #108
mondrakeI think this needs reroll since #3064854: Allow Twig templates to use front matter for metadata support has just changed the content-hash in the composer.lock file.
Comment #109
alexpottThis is fine. That issue changed the path reference hash - it's not the same thing.
Comment #110
mondrakeAh, yes. Thanks @alexpott
Comment #111
alexpott#3110972: Update easyrdf library to 1.0.0 has now changed the content hash :)
Comment #112
mondrakeSee... I was obviously foreseeing that :)
Comment #113
catchWent over this one more time with a release manager eye, and decided we need a change record, which I've added here: https://www.drupal.org/node/3176567
I think this is in good shape and should not disrupt many contrib tests, if at all, as well as us having no choice due to PHPUnit and PHP's release cycle. So... committed 74fbb0a and pushed to 9.1.x. Thanks!
Comment #115
catchForgot to say there are a few changes for @expectedDeprecation vs. ::expectDeprecation() here, however I left them out of the change record because we're already addressing those changes in #3172438: Since symfony/phpunit-bridge 5.1: Using "@expectedDeprecation" annotations in tests is deprecated, use the "ExpectDeprecationTrait::expectDeprecation()" method instead..
Comment #116
mondrakeFrom the CR:
I do not think this is correct, actually. See https://www.drupal.org/node/3136304.
It's not about the order... it's about comparing array values being string to MarkupInterface objects or viceversa. Unfortunately the method is still undocumented upstream.
https://github.com/sebastianbergmann/phpunit-documentation-english/issue...
https://github.com/sebastianbergmann/phpunit/issues/3511
Comment #117
catchhmm I was going off #3127141-18: Use PHPUnit 9 for PHP 7.4+, while keeping support for PHPUnit 8.4 in PHP 7.3, maybe #3127141-19: Use PHPUnit 9 for PHP 7.4+, while keeping support for PHPUnit 8.4 in PHP 7.3 is the better one?
Comment #118
mondrakeI was wrong in #18; the relevant comments are #25 #26 #27
Comment #119
alexpottComment #120
catchComment #122
effulgentsia CreditAttribution: effulgentsia at Acquia commentedI'm not clear from reading this issue why we had to keep using PHPUnit 8 on PHP 7.3, but whatever the reason was, I wonder if it's been addressed since then in later releases of PHPUnit 9, so I opened #3217451: [TESTING ONLY; DO NOT COMMIT] Update to PHPUnit 9.