Closed (fixed)
Project:
Drupal core
Version:
9.3.x-dev
Component:
phpunit
Priority:
Major
Category:
Task
Assigned:
Unassigned
Reporter:
Created:
28 Apr 2020 at 21:13 UTC
Updated:
14 Oct 2022 at 05:52 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
longwaveThis patch was created by searching for regex
=.*>assertand then excluding the following methods which have valid return values:Comment #3
andrewsizz commentedReviewed patch and it looks good for me!
Comment #4
alexpottFun issue. I think we need to be careful of BC. I think if a method return FALSE when it passes then we have something that doesn't make sense and can be fixed. But if it returns TRUE for a pass then we need to maintain that because of BC implications for contrib and custom code.
So this is always going to be returning FALSE (ie. NULL && NULL) so the return value makes no sense so I think changing this without a CR is okay.
Yeah we'll never hit this code if we fail but this is a sort of API change for contrib. Imo we should change this to return TRUE so it's explicit that is always a pass at this point and then deprecate the return value - its possible contrib/custom has tests that depend on it. We need a CR for this.
This will always return TRUE so again I think we need a CR and to return TRUE. The other issue here is now the $message is completely ignored and useless.
This will always return FALSE afaics so removing this is fine.
This will always return FALSE too so removing is fine.
Comment #5
longwave#4.2 How do we deprecate a return value? Contrib calls it once but doesn't use the return value, and Search API implements its own version of the method itself: http://grep.xnddx.ru/search?text=assertCacheContexts&filename=
The second and third arguments to assertCacheContexts also seem useless, they can likely be deprecated in another issue.
#4.3 Removed the message argument from the signature and the callers. This one isn't called in contrib at all.
Comment #6
mondrakeThe only way I can think of for deprecating the return value is to deprecate the entire methods and write new ones that return
void. TBH it feels a bit overkill, though. Maybe just a CR can do; 'tests are not API', and these are not even in base classes. If some projects were extending these classes back when they were still in Simpletest, they would have been forced to adjust to PHPUnit already anyway.Don't we need to return TRUE for the same reasons, here? I read the original intention of this assertion to have TRUE returned when dimensions are as expected, so that further tests can continue. Here if one assertion fails OK, all stops, but if they still pass and downstream an extended class is expecting true to continue testing, this will not happen. But.. see my header comment.
I think here we can inline all the logic in the assert w/o assigning to variables first.
same as point 1
same as point 1
NW (IMO, just for point 2)
Comment #7
mondrakeon this
Comment #8
mondrakeAddressed #6.
Reverted this from #5 as IMHO it's out of scope
Comment #9
longwaveI was a bit overzealous in the original patch. I agree with all suggestions in #4 and #6, as far as I can see we don't need any change records now because we are just tightening up return values where they can never be false.
Comment #10
xjm"A @todo without a followup is just wishful thinking." -- @catch
Is there a reason not to refactor the callers here to account for no return value? We're already changing (edit: or already have changed) the return values, and we don't provide BC for individual tests.
Comment #11
xjmReading previous comments, I guess I am contradicting #4, in a rare case of release manager being more permissive about BC rather than less. But these methods aren't test API; they're internal helpers for individual tests. Edit: It'd be different if they were on traits or base classes.
Comment #12
xjmComment #13
longwave> But these methods aren't test API; they're internal helpers for individual tests.
Out of scope here, but this is a great argument for making these methods private instead of protected - if we did that we could be 100% sure there were no downstream callers that we might break.
Comment #14
xjmI mean, there are a couple cases where we deliberately extend non-abstract test classes in order to run the parent's test methods on all the child classes. So it's not unheard of. But individual tests being not subject to any BC is maybe the only part of our internal API policy we haven't had to walk back our "no BC guarantee" for during the D8 lifecycle.
Anywho, there's #2727011: [policy, no patch] Private vs protected, and the role of inheritance for a policy discussion about
private. (Technically, core policy dating to 2012 or so is that we never useprivate, although that's been enforced inconsistently.)Comment #15
mondrakeRemoved todos, I will file a separate issue to make all custom assert*ions to be typehinted to void, to have a single issue where to do that in a consistent manner. It's not a follow up really, rather an issue of its own. That would have to be D9 (or D10?) only though, since void return typehint cannot be used in PHP 7.0 that D8 still supports.
Also swapped arguments in a assertEquals to ensure $expected comes on the left hand side, and converted calls of (now formally) deprecated Simpletest assertions in favor of WebAssert ones.
Comment #16
mondrakeFiled #3138078: [D9.3 beta - w/c Nov 8, 2021] Add a 'void' return typehint to custom assert* methods
Comment #17
longwaveBack to RTBC on this. The return values are good now, and in the unlikely event someone is using them the docs are correct.
Comment #18
daffie commentedThe patch needs a reroll, because #3139218: Replace usages of AssertLegacyTrait::assertResponse(), which is deprecated landed.
Comment #19
mondrakeon this
Comment #20
mondrakeRerolled. Only
DisplayPageWebTestwas impacted by the change fromassertResponse()toassertSession()->statusCodeEquals().Comment #21
mondrakeComment #22
xjmSo in #3082859: The AssertMailTrait should cast the data type to boolean in assertMailPattern, a contributor is relying on the return value of
AssertMailTraitto be true. In that case it's a trait, and actual public API, so it makes sense for us to provide BC there. I'm still not sure that means we should here, as these are not public API but #3138078: [D9.3 beta - w/c Nov 8, 2021] Add a 'void' return typehint to custom assert* methods is on an interesting track there. I don't know though that it's helping callers that are doing$this->assertTrue($this->assertCustomThing($foo, $bar));Comment #23
xjmGiven the contrib example from #3082859: The AssertMailTrait should cast the data type to boolean in assertMailPattern and the fact that that trait is not included here, I think the scope is not complete. Callers can do other things with the return value than assign it to variables, like conditional logic or even
assertTrue()ing the conditional logic. So we should look atIf the full scope of "Refactor tests that rely on return values from assertions" is too unwieldy, we can make this part of a meta also, but we'd need the parent.
So NW to either file a meta or expand the scope here. Thanks!
Comment #26
longwaveRerolled this following #3222783: Result of method PHPUnit\Framework\Assert::assertEquals() (void) is used
Added AssertPageCacheContextsAndTagsTrait into the mix, left that one returning TRUE as it's a trait that others might use; otherwise I think we should consider custom assertions inside test classes to be internal, I don't think we should attempt to provide backward compatibility in the unlikely event someone is extending ToolbarCacheContextsTest or something like that.
Comment #27
longwaveAlso re #23 AssertMailTrait was already handled in #3204764: PHPUnit assertions do not return a value, worth someone double checking if there are any more custom assertions that return a value though I guess.
Comment #28
longwave@mondrake if you agree with #26 in that we "consider custom assertions inside test classes to be internal" should we declare all custom assertions in classes (but not traits) as void return now? That way, IDEs and static analysis can pick up use of the void return automatically...
Comment #29
mondrakeIMHO this is good sense cleanup. I'd defer #27 and #28 together to #3138078: [D9.3 beta - w/c Nov 8, 2021] Add a 'void' return typehint to custom assert* methods.
Comment #31
longwaveRandom fail in TrustedHostsTest?
2x: Passing an escaped locator to the named selector is deprecated as of 1.7 and will be removed in 2.0. Pass the raw value instead.
2x in TrustedHostsTest::testShortcut from Drupal\Tests\system\Functional\System
Comment #32
catchShould we have a follow-up to change this to null as well?
Comment #33
mondrake#32 it will be done in #3138087: openstory 8.x-2.23
Comment #35
catchOK I didn't realise that issue was trying to deal with traits too. Left a comment there, but seems OK to go ahead with this.
Committed bcfecbb and pushed to 9.3.x. Thanks!
Comment #37
quietone commentedThis is tagged for a followup, #23, to address this problem in a wider scope. After some searching I rediscovered #3043939: [Meta] Remove usages of void return, which is a suitable follow up. I have updated the IS over there. I am removing the tag.