Problem/Motivation
Spin-off from #3063887: Support PHPUnit 8 in Drupal 9, drop support for PHPUnit 7.
PHPUnit 8 is changing the signature of the main test methods that test classes extend - above all setUp
and tearDown
, adding a void
return typehint.
As per #3063887-75: Support PHPUnit 8 in Drupal 9, drop support for PHPUnit 7, in this issue we change the signatures of the methods in concrete Drupal test code according to PHPUnit 8.
Proposed resolution
@catch and I agreed that this is a good approach for addressing this compatibility issue so that we're ready by Drupal 10. Thanks!
Change all the implementations of
setUp()
tearDown()
setUpBeforeClass()
assertPostConditions()
in concrete test classes to have a void
return typehint.
We will then add a deprecation to inform developers of this change in #3111044: Deprecate setUp/tearDown concrete test methods that do not specify void return type
We cannot change abstract base test classes without breaking backward compatibility, so that will be done in a follow-up.
Remaining tasks
Patch.
User interface changes
API changes
Data model changes
Release notes snippet
Overridden test methods should have void return type hints added, see the change record at https://www.drupal.org/node/3114724 for more details.
Comment | File | Size | Author |
---|---|---|---|
#104 | 3107732-104-D90x.patch | 1.12 MB | mondrake |
#104 | 3107732-104-D91x.patch | 1.12 MB | mondrake |
Comments
Comment #2
mondrakeComment #3
longwaveAttached patch created with this script, which adds the return type for everything that isn't related to legacy SimpleTests, plus one or two manual fixes on top.
Comment #5
mondrakeTagging. Looks promising, only 5 failures.
Comment #6
longwaveMissed one class that mentions simpletest and four that use "setup()" instead of "setUp()". Some method visibilities are also wrong but I think that is out of scope to fix here.
Comment #7
longwaveIf this isn't viable because of the BC break with contrib/custom tests then I think this is still worth doing on the subclasses. We could emit a deprecation warning by using ReflectionMethod::hasReturnType() to tell contrib/custom code that they need to add the return type.
Comment #8
mondrake#6:
core/modules/comment/src/Tests/Views/CommentTestBase.php
core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php
core/modules/views/src/Tests/Wizard/WizardTestBase.php
are Simpletest WebTestBase tests, should not be impacted by this change
Comment #9
longwaveThanks, fixed those. The ones further down the class hierarchy are always going to end up false positives when using basic tools like find/grep/sed.
Comment #10
mondrake#7: that's going to be a choice between a hard failure and a deprecation failure (as long as custom/contrib enabled deprecation failure in their drupalci.yml). IMHO, as a contrib developer, better fail hard in this case rather than implementing and maintaining a BC layer. Per se, the changes required to test cases are trivial once it's clear what needs to be done. My 2 cents.
Comment #11
mondrakeFor an example of a contrib module meant to support D8.8 as well as D9, and adding
void
return typehints to the test cases under the current core test codebase without the typehint yet, see #3106802: Add void return typehint to test setUp methods. Results are as expected - pass on D8.8, D8.9 and D9.0 with PHP 7.1+, fail for PHP 7.0.Comment #12
mondrakeBased on #10, I cannot see anything else to be done here... apart from deciding that we want to do this.
Comment #13
mondrakeRerolled.
Comment #14
mondrakeReroll - there'll be a few while BC layers get removed.
Comment #15
mondrakeReroll
Comment #16
mondrakeReroll
Comment #17
xjmThis needs a CR and a release note. Thanks!
Comment #18
alexpottI agree that this is a big issue to solve with PHPUnit 8.
The downside of this solution is that if you have a module where you want to support 8.8 and 9.0 with the same codebase you minimum PHP is then 7.1. I think this is pretty unavoidable. The only other solution is to move to Symfony's simple-phpunit and that was not at all simple and will be even more disruptive given we'd have to drop PHPUnit as dev dependency of core. Also PHP 7.0 is not longer supported so I think the trade-off here is okay given what we have to work with.
So I'm +1 to the idea but the issue summary needs a major update to spell out the impacts of this change on the ecosystem.
Leaving "needs framework manager review" on the issue for other framework managers to have their say.
Comment #19
mondrakePostponing due to latest developments in #3063887: Support PHPUnit 8 in Drupal 9, drop support for PHPUnit 7 that are making this less urgent.
Comment #20
catchI think we should still be doing this in 9.0.x so that we're not relying on our own bc layer. We could potentially delay any base test classes to 9.1.x though but the regular tests should be brought up to date.
Comment #21
BerdirEven when excluding the base classes that might be tricky and will break at least a few modules. redis for example re-uses a few tests from core (lock and queue) and with complex hierarchies like the rest/jsonapi test structure, what exactly is a base class, what do we change and what not?
Comment #22
BerdirI'm not saying that's a definitive blocker, redis for example has been broken a few times with those tricks as we don't really support that anyway, although also in good ways (extended coverage in core showing of bugs in the redis implementation). Just something to consider when doing it. and unless we add it to our base classes, we 100% rely on our BC layer to anyway, the final breaking patch would just be smaller.
Comment #23
catchI think something like redis should expect to update its test coverage every so often (although that's a reason not to mark tests final, since I think it's a valid use-case to piggyback off core tests like that and people know what they're doing when they do it).
This is true but it'd be a lot less bad examples in core for people to potentially copy/paste from.
Comment #24
mondrakeRerolled, and with return typehints removed from base classes as per #3063887-75: Support PHPUnit 8 in Drupal 9, drop support for PHPUnit 7.
Comment #26
longwaveComment #28
longwaveComment #30
mondrakeUpdated IS.
Comment #31
mondrakeFiled #3111044: Deprecate setUp/tearDown concrete test methods that do not specify void return type as a follow-up.
Comment #32
mondrakeComment #33
mondrakeComment #34
mondrakeComment #35
mondrakeWorking on adding a deprecation PoC as suggested in #3111044: Deprecate setUp/tearDown concrete test methods that do not specify void return type.
Comment #36
mondrakeHere's the PoC. We use reflection at the time of a
startTest
to detect whether a method is declared in the class or inherited, and if declared inline without avoid
return typehint, throw a deprecation message.For convenience, I reverted the change in a single method from #28 to ensure we have at least a failure (and if we have only 1, #28 would be great work... :))
Comment #37
mondrakeA deprecation test-only patch to see bigger picture.
Comment #40
mondrakeSo:
#36 demonstrates that #28 is indeed great 😀
#37 demonstrates that the deprecation PoC works
Comment #41
mondrakeReroll of patch in #36
Comment #43
mondrakeThe deprecation thingie works nicely, #41 captured a newly added test class and signalled that the void typehint is missing.
Comment #44
mondrakeComment #45
longwaveNice work on the deprecation test :)
I think as per @alexpott in #3063887-75: Support PHPUnit 8 in Drupal 9, drop support for PHPUnit 7 we need to only add the typehints here in 9.0.x. Do you want to spin off the deprecation into a new issue for 9.1.x?
Real tiny nitpick but you can say
->hasReturnType()
in the first half of the if statement here.Comment #46
mondrake#45 thanks @longwave.
1. See #3111044: Deprecate setUp/tearDown concrete test methods that do not specify void return type. The idea is to keep the deprecation PoC here until before commit, then remove and move it there for 9.1.
2. Done, thanks!
Rerolling after removal of simpletest module. This will fail with deprecations for any newly added test class.
Comment #47
longwaveNothing more to do here as far as I can see, marking RTBC to get core committers attention on this proof of concept and help figure out next steps to get this committed.
Comment #49
volegerNew tests introduced, they have to be updated appropriately.
Comment #50
longwaveComment #51
longwaveAdded draft change record: https://www.drupal.org/node/3114724
Updated issue summary and added a draft line for the release notes, but perhaps it could be worded better.
Comment #52
mondrakeComment #53
mondrakeComment #54
salah1I rerolled the patch on #50.
It didn't apply so i worked on the conflicts shown by git. After that, the [git rebase --continue] was successfull, but the following step failed.
[Testing my patch by applying it to the upstream branch]. See the attached txt for more info.
Comment #56
xjmComment #57
longwaveThanks @salah1!
Fixed up the patch to include new test methods and a merge error. Also updated the deprecation message to link to the CR.
Comment #59
swatichouhan012 CreditAttribution: swatichouhan012 at Valuebound for Valuebound commentedI am working on this
Comment #60
swatichouhan012 CreditAttribution: swatichouhan012 at Valuebound for Valuebound commentedFixed some test fail in comment #57. Kindly review new patch.
Comment #61
longwaveReroll of #60 due to conflict in core/modules/file/tests/src/Kernel/Migrate/d7/MigratePrivateFileTest.php
Comment #63
swatichouhan012 CreditAttribution: swatichouhan012 at Valuebound for Valuebound commentedRemoved deleted patch code from file and updated with some test fix,
Comment #64
longwaveAs this affects almost every test class and has needed repeated rerolls I wonder if this is going to need a fixed window to try and get this in, similar to #2822382: Make every $modules property protected on classes extending BrowserTestBase and KernelTestBase - it seems futile rerolling it when almost every core commit breaks it again.
Comment #65
mondrakeFWiW, totally agree on #64...
Comment #66
mondrake#65 + the deprecation PoC.
Comment #67
catchI am +1 on scheduling this, but I am not sure when for yet - agreed it's the sort of patch where a specific commit window would be beneficial.
@xjm was not sure about committing this to 9.x at all, I think it's worth it:
the current bc layer we added rewrites test classes, but this is forward compatible with tests that implement the return type hints.
Doing this patch is equivalent to removing deprecated usages for a 'normal' deprecation - then in 10.x we would only need to add the type hints for the base classes (a test API change for everything extending those classes) and remove the bc layer (same but for every conveivable test).
Applying this patch earlier makes it more likely that contrib modules will follow core's example and add the return type hints themselves, something they would ideally do before we remove the bc layer in 10.x.
Comment #68
mondrakeComment #71
mondrakeComment #72
mondrakeComment #74
mondrakeComment #75
mondrakeComment #77
swatichouhan012 CreditAttribution: swatichouhan012 at Valuebound for Valuebound commentedUpdated test class setup().
Comment #78
swatichouhan012 CreditAttribution: swatichouhan012 at Valuebound for Valuebound commentedRemove wrong file, kindly review new patch with interdiff
Comment #82
neelam_wadhwani CreditAttribution: neelam_wadhwani at Valuebound for Valuebound commentedComment #83
swatichouhan012 CreditAttribution: swatichouhan012 at Valuebound for Valuebound commentedupdated patch #78 for class NodeClassicTest
Comment #84
mondrakeCan we try to get this in before beta? It's green now, rerolls are complicated, I'm afraid after beta this will be a no go
Comment #85
mondrakePostponed, #64 pointed out well this needs purposeless rerolls practically every day. Let's build on #67 to have a potential window when to make the effort meaningful.
Comment #86
xjm@catch and I discussed doing this as a scheduled beta target late in the beta process. It should happen before RC (which begins the first week of May) because it could theoretically be disruptive for contrib that extends an individual core test (which some contrib does do). Since individual tests are internal, it's OK to make the change during beta, but we should not do it during RC to avoid disruption.
I'd suggest picking a target few days in late April to roll, review, and commit the change?
Comment #87
mondrake@xjm can you update the issue title with a date range, so that those watching can act in that timeframe?
Comment #88
xjm@mondranke It's up to the participants to pick the date range because they're the ones committing to do the patch during that timeframe.
We'll want to get the signoffs from the change before that. Waiting to discuss with @catch a little further to confirm RM signoff, and I'll also link it in committer Slack asking for FM signoff.
Comment #89
alexpottAs a framework manager I sign off on the approach of
Comment #90
xjm@catch and I agreed that this is a good approach for addressing this compatibility issue so that we're ready by Drupal 10, so long as we're also sure to do #3111044: Deprecate setUp/tearDown concrete test methods that do not specify void return type after 9.1.x is opened for development next week. Thanks!
Comment #91
mondrake#89, #90 - in this case I suggest to use this issue to get a patch in 9.1.x first with the deprecation thingie in (it will be open for development before the time window to get it into 9.0.x), and then port to 9.0.x without the thingie. That would make the other issue redundant, and also we could have here two patches, one with the thingie (for 9.1.x) and one without (for 9.0.x), for quicker commit.
Comment #92
catch@mondrake that makes sense, although we should still keep this issue against the lowest applicable version.
Comment #93
xjmI may be out of the loop but what "thingie"?
Comment #94
catch@xjm #3111044: Deprecate setUp/tearDown concrete test methods that do not specify void return type is proposing to add some way to trigger a deprecation notice when a test class doesn't have return type hints - as a new deprecation this could land in 9.1.x-only - this is the 'thingie'. The proposal is to merge that issue back into this one, but with separate 9.1.x and 9.0.x patches (the 9.0.x patch just would not have the hunk adding the deprecation detection/triggering logic).
Comment #95
mondrake😀
This is the 'thingie':
Comment #96
mondrakeComment #97
mondrakeBot, what's the outlook today?
Comment #98
mondrakeComment #99
mondrakeComment #100
mondrakeComment #101
longwaveAs this is currently green let's mark it RTBC and get it tested nightly to automatically catch any new tests in the next few days that will need fixing here.
Comment #102
mondrakeSwitching to 9.1.x to allow filing two patches.
Comment #103
mondrakeTwo patches, one (D91x) for D9.1 with the deprecation code, one (D90x) for D9.0 with the return typehints only.
Comment #104
mondrakeSame, rerolled.
Comment #105
jungleI would suggest adding a sniffer/phpcs rule for this. But to do it in a separate issue as it depends on a new patch and a new release of the coder module. It's good to have the patch(es) here committed first, then the next patch would be much smaller and easy to review, or the current window will be missed probably.
Comment #106
alexpott@jungle there does not need to be a PHPCS rule for this. We’re triggering a deprecated error and once we remove the BC layer tests will just break with a language level error.
Comment #107
jungle@alexpott, you are RIGHT! Thanks for your reply!
Comment #108
alexpottCommitted 0dc2853 and pushed to 9.1.x. Thanks!
Had to edit the diffs to fix
core/modules/ban/tests/src/Kernel/Migrate/d7/MigrateBlockedIPsTest.php
tocore/modules/ban/tests/src/Kernel/Migrate/d7/MigrateBlockedIpsTest.php
caused by #3126784: \Drupal\ban\Plugin\migrate\destination\BlockedIP is not identical with its filename BlockedIp.php. Definitely worth getting this done now to prevent re-re-re-re...rolling.Comment #111
alexpott:D lol at the commit message.
Comment #112
BerdirFIY, this also changed MigrateProcessTestCase, despite not having a Base suffix, this was a base class that also had subclasses in paragraphs and maybe other contrib modules :)
Comment #113
heddnYes, this is also effecting migrate_plus and other migrate contrib modules. See https://www.drupal.org/pift-ci-job/1662818
Comment #114
longwaveOpened #3131402: Remove return type hints from abstract test classes to deal with that specific case. Also crafted a regex which has discovered some others we may want to consider reverting - some of these are false positives as there are test implementations in the same file, but a few may warrant reverting still: