Problem/Motivation
The story of this issue:
#2863267: Convert web tests of views gave us Drupal\Tests\views\Functional\ViewTestBase and a deprecation of the WTB base class it replaces. Yay!
However, that led to some interesting results in #2870194-9: Ensure that process-isolated tests can use Symfony's PHPunit bridge to catch usages of deprecated code, where phpunit autoloading policy led to failed test runs based on the WTB version of ViewTestBase.
One chat between @Mile23 and @alexpott in IRC later: We originally agreed it's good deprecation policy to put @trigger_error() for test base classes in the setUp() method. So agreeable were we that the testing policy was changed: https://www.drupal.org/core/deprecation#how-test-base-class
Subsequent discussion on this issue and we've decided to put @trigger_error() in WTB base class constructors.
Now existing deprecated WebTestBase base classes need an update for the policy.
Since then, however, we realized that it's not a problem with the deprecation policy, but the existing deprecation policy actually told us the real problem: ConfigTranslationViewListUiTest is a WTB-based test incorrectly placed in the Functional\ namespace by #2770921: Feb 21st: Convert chunk of WTB to BTB by just moving classes, changing use statements adding traits
Steps to reproduce:
- Run
./vendor/bin/phpunit -c ./core --filter AccessManagerTest - See deprecation error
Proposed resolution
@Mile23 did some excellent research in #23. The problem described in this issue summary actually just matters for phpunit, so we don't have to adapt the WTB logic of putting it into the header of the file.
Move ConfigTranslationViewListUiTest back to WTB namespace.
Re-update deprecation policy document: https://www.drupal.org/core/deprecation#how-test-base-class
Remaining tasks
Eventually deprecate WebTestBase itself: #2847678: Deprecate WebTestBase and its required classes in favour of BrowserTestBase
User interface changes
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #23 | interdiff.txt | 7.17 KB | mile23 |
| #23 | 2876145_23.patch | 774 bytes | mile23 |
| #15 | 2876145-15.patch | 6.38 KB | michielnugter |
| #15 | interdiff-10-15.txt | 1.75 KB | michielnugter |
| #10 | 2876145-10.patch | 5.26 KB | michielnugter |
Comments
Comment #2
mile23And a patch...
Comment #3
alexpottComment #4
lendudeGood to know for any further conversions!
Should we update
\Drupal\datetime\Tests\DateTestBasein this issue too? That also has the trigger_error after the namespace.Comment #5
lendudeAnd \Drupal\views\Tests\Wizard\WizardTestBase
And what about base classes that don't implement setUp() like these
\Drupal\views\Tests\Plugin\PluginTestBase
\Drupal\views\Tests\Handler\HandlerTestBase
I guess implement setUp just to add the trigger_error?
Comment #6
alexpottyep let's do them all in this issue.
Comment #7
lendudeHere we go
Comment #8
dawehnerI would expect other classes to potentially do similar kind of stuff in the constructor, so I'm wondering whether we should do the same here.
Comment #9
dawehnerThe advantage of using the constructor would be to have it really explicit, unlike with the setup() method, which is basically in the middle of nowhere and potentially harder to see.
Comment #10
michielnugter commentedI agree with @dawehner. The constructor makes it hard to miss and very specific. Patch moves the messages to a constructor.
Comment #11
michielnugter commentedAdding tags to make sure we don't forget these. Not changing the title yet to wait for more opinions..
Comment #12
alexpott+1 to adding a constructor with the deprecation
Comment #13
mile23Constructor it is. :-) Hopefully the branch will pass soon and the test in #10 can run.
Eventually, we'll have to figure out how to
@trigger_error()inWebTestBaseitself: #2847678: Deprecate WebTestBase and its required classes in favour of BrowserTestBaseComment #14
lendude+1 for the constructor. Also, setUp() will get called multiple times so the trigger_error would get called multiple times too, which seems a little redundant.
would be nice to use the __NAMESPACE__ pattern consistently
other then that, this looks good to me.
Comment #15
michielnugter commentedFixed the namespace thing.
Seems we forgot this one: #2865992: Convert Datetime module Views tests to Kerneltest tough. I did another search and it's the only one missed I think.
Removing title and documentation tags. Title was updated and I just updated the documentation on this.
Comment #16
lendudePatch looks good, doc changes look good and I think we have a consensus on how to handle this. Nice!
Comment #17
dawehnerWhat about using
static::classhere?Comment #18
mpdonadiostatic::classwill be the late-static binding class name not the base class that we are deprecating; it's basically the same asget_called_class().Comment #19
catchWhat about __CLASS__ then?
Comment #20
dawehneroh well you could have also used
self::classComment #21
mile23Since this is about deprecation policy and not just this single change, let's not use
__construct().Because: If you use the constructor to throw a deprecation error in a phpunit-based test, and you use the phpunit tool with
--groupor--filter, you end up with a triggered error for every class that was initially discovered, not just the ones you ran.That takes us back to
setUp(), which is better, but which also is called for every test method and every case provided by a@dataProviderin phpunit. This is at least limited to test classes which ran, but gives a lot of thrown errors in your results.That leaves us with
setUpBeforeClass()in phpunit, which only happens once per class (obviously).We don't have that for
WebTestBase, however, so I propose as a policy we do the following:@throw_error()insetUp()forWebTestBasebase classes.@throw_error()insetUpBeforeClass()for phpunit base classes.If that's too complicated or inconsistent then just
setUp()is fine.So for this issue: move the
@throw_errorback tosetUp()for all the deprecated WebTestBase base classes.Comment #22
michielnugter commentedThat would mean that it would be no problem to trigger it in the constructor for simpletests as they're not run via phpunit right?
I for one would like the most ideal solution for the PHPUnit tests as that's the future and adapt to what's possible for Simpletest. If we're going to differ on solution for Simpletest: do we have a reason for not adding the trigger_error calls in the constructor?
Comment #23
mile23OK, so the ideal place for this kind of deprecation error in PHPUnit-based tests is
setUpBeforeClass(). This is a little out of scope for this issue, but we're going to update policy so we need to decide it.For simpletest based tests, we have two problems in this issue:
1) We don't like seeing simpletest-based tests doing
@trigger_error()during phpunit test runs. We want WTB tests to onlytrigger_error()when they're actually run and not when they're loaded because we don't like fails. This means eithersetUp()or__construct(). We seem to have decided on the constructor by consensus. However: Read on. :-)Note that the simpletest infrastructure has no idea what a
@trigger_error()is, so nothing happens with it now. The only problem we're solving here is that simpletest-based tests are throwing errors during phpunit test runs. Which brings us to:2) Why is a phpunit test run autoloading a simpletest-based test base, if it's not a test of that test base? We don't know. To answer it, adding a stacktrace output to the thrown error tells us that
Drupal\Tests\config_translation\Functional\ConfigTranslationViewListUiTestextendsDrupal\views_ui\Tests\UITestBase, which means it's a PHPUnit functional test using a WTB base class. Which is wrong. :-)This happened during the scripted mass-conversion of #2770921: Feb 21st: Convert chunk of WTB to BTB by just moving classes, changing use statements adding traits so it's reasonable that we didn't see it.
So re-evaluating all that has come before, we might reach the following conclusion:
We want to find errors like this, so WTB base classes should
@throw_error()as before: Right after the namespace declaration. Since simpletest won't catch those, it's all fine and dandy, but they'll scream in our face under phpunit when we have a test framework mismatch as withConfigTranslationViewListUiTest. We might find that we need to change this policy later, but for now it does the right thing: Tell us that we're using the wrong framework. It won't tell us that if we move it tosetUp()or the constructor.Also, we might well see more of these types of deprecation errors once we add the
@trigger_error()toWebTestBase.So here's a patch that turns
ConfigTranslationViewListUiTestback into a WTB test since that's the easiest move. It also throws errors after the namespace declaration as before for all the deprecated base classes.Needs a follow-up to re-convert
ConfigTranslationViewListUiTestto BTB, since this patch is a little bit like a regression.Comment #24
mile23Also, it really is a bug, and should be an 8.3.x issue, but I neglected to change that.
Comment #25
mile23Patch applies successfully to 8.3.x. Adding an 8.3.x test to the patch in #23.
Comment #26
michielnugter commentedThis alone makes the move back to right after the namespace worth it.
Good catch on the ConfigTranslationViewListUiTest, will try and find out if we have more of these. It's on my radar and I'll post this in the view_ui conversion issue and handle the conversion or follow-up there.
With the extensive research and history of the issue it's ready for RTBC I think.
Comment #27
dawehnerComment #28
mile23Updated the documentation to remove the special case for test base deprecations: https://www.drupal.org/core/deprecation
Comment #29
mile23Comment #30
alexpott@Mile23 was just about to ask for the title update - nice! But also the issue summary needs updating and the followup created.
Comment #31
mile23Updated IS with some more info.
@michielnugter mentions a follow-up so if he could link to it and remove the tag, that'd be great.
Comment #32
michielnugter commentedJust commented on #2747167: Convert first part of web tests of views_ui on the follow-up issue here, that should cover it right?
Comment #33
alexpottCommitted and pushed d284ae8 to 8.4.x and 9717b3a to 8.3.x. Thanks!