Problem/Motivation
Browser tests make HTTP requests to an virtual web browser, which can then make assertions about the HTML pages it receives from the test site.
Some of our browser tests use HTTP tests to perform setup tasks in the admin UI of the test site.
Making requests with the virtual browser is slow, so using HTTP requests for these is making the tests slower, and consume more resources. This costs drupal.org more money, and adds to Drupal's carbon footprint.
These setup HTTP requests could be done with API calls instead.
How to work on this issue
1. Look through Functional and FunctionalJavascript tests classes.
2. Read the description of the test to understand what the test is trying to cover. Look at the browser requests -- drupalGet() and submitForm() -- that it makes. Consider whether these browser requests are preparing the system for the test, or are they to do with what is being tested?
3. If you have found a candidate, create a child issue for it.
4. Replace each browser request with an API call:
-- Find the route controller or form class which the request uses. (Searching the code for some of the UI text is a good way to do this)
-- Find the API calls which the controller or form makes. For forms, these will typically be in submitForm().
5. Change the test to replace the browser requests with the direct API call
See also #3305413: Change entity creation tasks in RssTest to use API calls which has extensively documented examples of how it was fixed.
Comments
Comment #2
joachim commentedComment #3
joachim commentedComment #4
joachim commentedJust done #3355122: ContentTranslationContextualLinksTest should use API calls to set up translation and in the process of looking around language and translation tests, I found a LOT of tests that need this work!
Comment #6
berdirWe generally don't do per-file/module issue splits anymore unless there's a good reason to.
Comment #7
mstrelan commentedI would argue there is a good reason to here. Most of the tests are going to be unrelated to each other and the changes aren't just a matter of using a new coding style. Reviewing many different tests in a single issue will lead to review fatigue. Some tests may be harder to refactor than others and the sooner we can get some of these in the earlier we can reap the benefits. On the other hand, optimising all of them in one issue will make it easier to measure the impact.
Comment #8
berdirSee https://www.drupal.org/docs/develop/issues/issue-procedures-and-etiquett... and @longwave's comments on #3087434: [meta] Use FileUrlGenerator::generate() everywhere, then deprecate generateString() and generateAbsoluteString().
Comment #9
joachim commentedGiven it's probably going to be me who does most of these (I mean, if people beat me to it, great, but I'm not counting on it), I've filed issues in the way that makes sense to me. I'm not going to have the brainpower to work on multiple tests at the same time.
As @mstrelan points out, some issues are going to require discussion and some will be straightforward. It was tedious enough filing issues for all of these (that the 'clone issue' link doesn't work as expected made it harder) without having to think about how to group the simple ones together and leave the complex ones separate.
Comment #10
berdirI'm just pointing it out before you do the work, your issues might be closed by core maintainers or they might not, can't say.
Also, I can't help but point out that since you're going with the carbon footprint argument here, lets assume that this saves 0.1% of the total test execution(which I think is very generous) but at the same same time do it across 20 issues, it will require an extra 19'000 test runs to just break even on the actual carbon footprint of doing this change, assuming that each issue only needs a single test run. And that doesn't even consider the extra on-commit test runs, git commits, issues and comments ;)
Comment #11
catchFor this the issue scoping is a bit of a grey area because the changed might be quite different, or they might be nearly identical - a huge patch might be too much, but individual issues might be too repetitive. A possibly half-way would be to do A-F, G-N, O-Z sort of thing too.
Could we try this - maybe do two individual patches in the existing issues to see how it goes, and we can commit them one by one regardless of scoping for the other issues, and figure out the rest once we've done those.
Comment #12
catchI'm reviving #3040694: Use previous PHPUnit JUnit results to pack tests in bins when parallelizing which should help to identify priorities here - i.e. NodeTranslationUiTest has an individual test method that takes 55 seconds on my machine and the whole test class takes 4 minutes. That's not necessarily the worst one, just picked it from the @group #slow.
Comment #13
xjmCross-posting my review from #3384936: Use the API to set up languages in tests that are not specifically testing the language form:
@joachim pointed out that the container rebuild happens regardless, so maybe we need a separate issue to make the container multilingual much earlier in the test setup process. Possibly even a
MultilingualBrowserTestBaseor something. That could be separated from a more immediate improvement of converting these tests to use the API to set up their languages instead of the form.However, one child issue per test for tests that all have the exact same problem of using the translation form via the UI to set up languages is not okay scoping. At a minimum, a test trait for setting up languages via config should be created in one issue and the tests with the same form problem converted in bulk in a separate issue.
Please close all the children doing this exact same thing WRT the language form as duplicates. I have already rescoped #3384936: Use the API to set up languages in tests that are not specifically testing the language form to be the issue to address this. Thanks!
Comment #14
joachim commented> However, one child issue per test for tests that all have the exact same problem of using the translation form via the UI to set up languages is not okay scoping.
I chose to scope it like this because when I was working on this, I imagined that it would mostly be me working on the issues. I did not want to be running one branch for AGES while I work on one test after another, with the risk of the work done so far rotting, and then having to potentially discuss all the different changes in the different tests. It felt like a too large piece of work.
@Berdir brought the same thing up as you did @xjm and frankly the nitpickiness totally demoralised me. I'm glad at least that other people have stepped up and done some of the work.
Comment #15
catchAnother candidate, second longest test remaining in core: #3467853: Use API methods to create filter/editor in CKEditor5Test when not explicitly testing the UI
Comment #16
mgiffordAre there advantages here with the latest version of PHPUnit? I don't actually know but there have been improvements since the last comment https://phpunit.de/announcements/phpunit-12.html
Does that seem right?