Problem/Motivation
Similarly to #3063887: Support PHPUnit 8 in Drupal 9, drop support for PHPUnit 7, this issue is about enabling testing with PHPUnit 9 in Drupal 9.
PHPUnit 7 support ended on February 7, 2020
PHPUnit 8 support ends on February 5, 2021
PHPUnit 9 support ends on February 4, 2022
PHPUnit 10 will be released in February, 2021.
In PHPUnit8 several assertions methods are deprecated for removal in PHPUnit9, for example:
- Using assertContains() with string haystacks is deprecated and will not be supported in PHPUnit 9. Refactor your test to use assertStringContainsString() or assertStringContainsStringIgnoringCase() instead.
- The @expectedException, @expectedExceptionCode, @expectedExceptionMessage, and @expectedExceptionMessageRegExp annotations are deprecated. They will be removed in PHPUnit 9. Refactor your test to use expectException(), expectExceptionCode(), expectExceptionMessage(), or expectExceptionMessageRegExp() instead.
- assertInternalType() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertIsArray(), assertIsBool(), assertIsFloat(), assertIsInt(), assertIsNumeric(), assertIsObject(), assertIsResource(), assertIsString(), assertIsScalar(), assertIsCallable(), or assertIsIterable() instead.
- assertArraySubset() is deprecated and will be removed in PHPUnit 9.
- getObjectAttribute() is deprecated and will be removed in PHPUnit 9.
- readAttribute() is deprecated and will be removed in PHPUnit 9.
Also, some deprecations are thrown since we are currently using functionalities that PHPUnit is in the process of deprecating (for example, TestListeners, deprecated in PHPUnit8 but not removed from PHPUnit9).
The PHPUnit-bridge deprecation handler and #3116856: Workaround PHPUnit 8 warnings are silencing the warnings, currently. Spinoffs shall address the gaps and remove the silencing.
Spin offs:
Done:
- #3127141: Use PHPUnit 9 for PHP 7.4+, while keeping support for PHPUnit 8.4 in PHP 7.3
- #3113509: Replace @expectedException* annotations with dedicated methods
- #3116856: Workaround PHPUnit 8 warnings
- #3122961: PHPUnit\Framework\TestCase::__construct() should not be extended
- #3126792: Replace usage of assertAttributeSame() that is deprecated
- #3126569: Replace usage of assertAttributeEmpty() that is deprecated
- #3126848: Replace usage of the $ignoreCase parameter of assertContains(), that is deprecated
- #3126564: Replace usage of assertArraySubset(), that is deprecated
- #3126969: Replace usage of assertAttributeInstanceOf() that is deprecated
- #3126695: [D8 only] Add forwards-compatibility shim for assertEqualsCanonicalizing() in phpunit 6&7
- #3126797: [D8 only] Add forwards-compatibility shim for assertString(Not)ContainsString()replacements in phpunit 6&7
- #3126563: Replace usage of assertAttributeEquals() that is deprecated
- #3126970: Replace usage of readAttribute() that is deprecated
- #3126971: Replace usage of getObjectAttribute() that is deprecated
- #3126787: [D8 only] Add forwards-compatibility shim for assertInternalType() replacements in phpunit 6&7
- #3108006: Replace assertInternalType() calls with dedicated methods
- #3126333: Replace usage of the optional $canonicalize parameter of assertEquals(), that is deprecated
- #3113077: Replace assertContains() on strings with assertStringContainsString() or assertStringContainsStringIgnoringCase()
Proposed resolution
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|
Comments
Comment #2
mondrakeComment #3
alexpottLet's see what breaks... interdiff to the patch in #3063887: Support PHPUnit 8 in Drupal 9, drop support for PHPUnit 7
Comment #5
mondrakeFiled #3113077: Replace assertContains() on strings with assertStringContainsString() or assertStringContainsStringIgnoringCase()
Comment #6
mondrakePatch in #3 combined with patches from the spun-off issues
Comment #7
mondrakeComment #8
mondrakeFiled #3113509: Replace @expectedException* annotations with dedicated methods.
Comment #9
mondrakeComment #11
longwaveRepurposing this as a meta as suggested by @alexpott in #3108006: Replace assertInternalType() calls with dedicated methods
Comment #12
alexpottWe should work out what we're doing for assertArraySubset - if you run
core/tests/Drupal/KernelTests/Core/Action/SaveActionTest.phpon D9 with -v you get warnings.Comment #13
volegerUpdated dates in IS
Comment #14
berdirassertArraySubset: In https://github.com/sebastianbergmann/phpunit/issues/3494, someone created a separate package, but that's PHPUnit 9 only and doesn't help to get rid of the deprecation messages :-/
Comment #15
berdirSo if I understand that correctly, per https://www.drupal.org/pift-ci-job/1587117, phpunit is currently writing out lots of warnings about its own deprecations and we ignore them unless these tests actually fail in a different way too.
I think the first step would be to improve run-tests.sh to fail on that and fix that? For BC, we could see if can do our own deprecation instead in overridden methods that we can control.
That's also what @mondrake meant in #3063887-93: Support PHPUnit 8 in Drupal 9, drop support for PHPUnit 7. It's not "travis stuff", it's core stuff, we're simply ignoring it right now.
Comment #16
berdirAs a quick hack, just letting all tests with warnings fail, to see how bad it is.
Comment #18
longwaveBoth #3108006: Replace assertInternalType() calls with dedicated methods and #3113077: Replace assertContains() on strings with assertStringContainsString() or assertStringContainsStringIgnoringCase() are disruptive to Drupal 8.8/8.9/9.0 test compatibility as the replacement methods aren't available in PHPUnit 6, which is the minimum version for Drupal 8.8. We either need to add forward compatibility shims to Drupal 8.8/8.9 so we can use the newer methods, or I think we have to bump this to 9.1?
Comment #19
berdirDrupal 8 doesn't support PHPUnit 8 I think, so isn't bothered by those deprecations in the first place?
I think it's fine to do these replacements only in 9.0.
Comment #20
longwaveBut we want to be able to easily port patches between 8.9 and 9.0, so changing this in 9.0 only makes that more difficult.
Comment #21
berdirThat's true, but removing deprecations does make that harder too for example :) I think 9.0 vs 9.1 is up to to framework/release managers at this point, I originally thought it's better to wait for 9.1 with these changes and also the return type, but I think these warnings are going to be very confusing when running tests manually and it might be worth the extra overhead of keeping patches in sync. The 9.1 branch might open as early as march from what I know, so we'll need 9.1 compatible patches from then on anyway.
Comment #22
alexpottHow about adding a forward compatibility layer for now - so we don't trigger the warnings and then we can fix later in D9. We could copy the PHPUnit 8 methods to our code and remove the warnings.
Here's a pragmatic approach - we can ignore the warnings. In the future we can change the warnings into our deprecations and remove usage from core but not when we're trying to make D8 and D9 cross compatibility easy.
Comment #24
alexpottSo this is a bit brittle because we'll get into a problem with test classes that contain the work WARNINGS :). Fortunately we can get PHPUnit to convert the warnings to errors for us and therefore be a bit more strict. Yay.
The approach I've followed for fixing the component unit tests is as follows - I've fixed the tests as these don't change much - but I've used the trait for the composer tests because this array is under active development and using the trait is likely to make things a bit simpler.
Comment #25
alexpottA little neater.
Comment #26
longwaveHow will we backport these to Drupal 8/PHPUnit 6, as these tests directly extend TestCase but these new methods don't exist in PHPUnit 6? Or will we just change these components in 9.x only?
Nitpick: PHPUNit -> PHPUnit
Comment #27
alexpott@longwave none of this is intended for backport. I think it is ok if this component test diverges a bit - it's not like it changes alot. And the people we really want to help is contrib - so they can maintain tests on both D8 and D9 without that much complexity. Apply this patch to D9 achieves that.
Comment #31
alexpottComment #33
alexpottHopefully green.
Comment #34
alexpottI've split #33 out into a critical sub-issue as it really is about PHPUnit8 and not PHPUnit9. See #3116856: Workaround PHPUnit 8 warnings
Comment #35
mondrakeAt least for #3108006: Replace assertInternalType() calls with dedicated methods and #3113077: Replace assertContains() on strings with assertStringContainsString() or assertStringContainsStringIgnoringCase(), we could add to Drupal 8 only a tiny FC shim to allow backporting easily test changes from D9.
For example, overridingassertInternalTypeand redirecting it to the more accurate assertion method if it is available. In D9 it will not be necessary.EDIT - sorry I meant the other way round:
For example, implementing
assertIsIntand redirecting it toassertInternalType('int', ...)in case the accurate assertion method is not available. In D9 it will not be necessary.Comment #36
mondrakeThis is a meta now, no patches expected.
Comment #37
mondrakeComment #38
mondrakeComment #39
mondrakeComment #40
mondrakeComment #41
mondrakeComment #42
mondrakeComment #43
mondrakeComment #44
mondrakeComment #45
mondrakeComment #46
mondrakeComment #47
mondrakeComment #48
mondrakeComment #49
daffie commentedComment #50
mondrakeComment #51
mondrakeComment #52
mondrakeComment #53
mondrakeComment #54
mondrakeFiled #3127141: Use PHPUnit 9 for PHP 7.4+, while keeping support for PHPUnit 8.4 in PHP 7.3. We're not that far from being able to support PHPUnit 9 now. 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 #55
mondrakeComment #56
mondrakeComment #57
mondrakeComment #58
mondrakeComment #59
mondrakeComment #60
mondrakeComment #61
mondrakeComment #62
mondrakeComment #63
Aki Tendo commentedOnce this is complete any tests working with the assert statement can be configured not to run if assertions are turned off using the requires setting annotation.
I'm puzzled as to why this hasn't been added to the documentation for PHP Unit. Mr. Bergmann did the pull over 2 years ago. This feature was written by me specifically for when we switched over to handle this circumstance. Anyway, I checked the codebase of PHPUnit, both 8.5 and 9.1 have the code necessary to honor setting annotations.
That will cause the test to skip if assertions are turned off, useful for the tests in place to make sure runtime assertions are thrown when they should be. Conversely -1 can be used to skip the test if assertions are turned on.
Assertions aren't the only ini directive this can test for - any ini directive is fair game.
Comment #64
mondrakeComment #65
mondrakeComment #66
mondrakeComment #67
mondrakeComment #68
tr commentedWhy are we failing and aborting tests on DrupalCI that use a method that's *deprecated* in PHPUnit 8? These are still valid methods, PHPUnit 8 is still in use on DrupalCI. These should not cause a test fail. Instead they should be handled like methods in Drupal that are deprecated - tests should pass.
That's not true, at least for contrib.
It is not acceptable to fail tests running with PHPUnit 8 on DrupalCI just because of one method that will be removed in PHPUnit 9. Give me a notice if you want, or let me run deprecation checks myself like we do for all other deprecations, but failing the tests and forcing me to immediately change my code is wrong - If PHPUnit 8 is still supported, then you must support it.
See https://www.drupal.org/node/2632588/qa for the failure.
Comment #69
mondrakeThis can be closed now, after commit of #3127141: Use PHPUnit 9 for PHP 7.4+, while keeping support for PHPUnit 8.4 in PHP 7.3. See you in #3174383: [meta] Support PHPUnit 10 in Drupal 9 :)