Use \Drupal consistently in tests

Created on 16 August 2013, over 11 years ago
Updated 25 July 2024, 9 months ago

Problem/Motivation

Kernel and functional tests should use the \Drupal discovery class even though $this->container is also available.

Proposed resolution

Replace all calls to $this->container->get() with \Drupal::service(), in core module kernel and functional test classes.

Use git grep '\Drupal::' core/modules/*/src/Tests/* to find these. Get a list of files this way: git grep --name-only '\Drupal::' core/modules/*/src/Tests/*

Note

Originally, this issue proposed the exact opposite. After a lot of discussion here and on 🌱 Use \Drupal consistently in tests Needs work , it was decided to use \Drupal::service() consistently.

Remaining tasks

file issue per module
fix issues

Related Issues

Initially from #1957142-64: Replace config() with Drupal::config() →
#2001206: Replace drupal_container() with Drupal::service() →

@todo list of issues
#2067007: Replace \Drupal:: with $this->container->get() in test classes of aggregator module →
#2066999: Replace \Drupal:: with $this->container->get() in test classes of system module →

Original report by @andypost

Problem/Motivation

SimpleTest TestBase-based tests should use the fixture container, rather than relying on the \Drupal discovery class.

Currently, TestBase assigns the fixture container to \Drupal, since a lot of existing code is still not properly injected.

As more of core is injected, it will be more important to use the fixture for tests, so that we can draw a line of isolation between the test runner and the system under test. This will allow for greater latitude in mocking services and filesystems for core.

Proposed resolution

Replace all calls to \Drupal:: with corresponding $this->container->get(), in core module test classes.
Use git grep '\Drupal::' core/modules/*/src/Tests/* to find these. Get a list of files this way: git grep --name-only '\Drupal::' core/modules/*/src/Tests/*

🌱 Plan
Status

Needs work

Version

11.0 🔥

Component
PHPUnit  →

Last updated 3 days ago

Created by

🇫🇷France andypost

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇩🇪Germany Anybody Porta Westfalica
  • First commit to issue fork.
  • Merge request !11707PHPStan rule to enforce \Drupal::service → (Open) created by mstrelan
  • Pipeline finished with Failed
    11 days ago
    Total: 158s
    #462987
  • 🇦🇺Australia mstrelan

    The IS mentions both Kernel and Functional tests should use \Drupal::service, but according to alexpott in #2699565-27: Replace \Drupal:: with $this->container->get() in test classes that allow dependency injection of Basic Auth module → this is only true for Functional tests.

    I've created an MR with a phpstan rule to identify functional tests that access $this->container. See https://git.drupalcode.org/issue/drupal-2066993/-/jobs/4841841 for results. We could land this and add the existing violations to the baseline. Then we can open follow up issues to cleanup the baseline. I suspect it should be simple enough to write a rector rule to replace $this->container->get() with \Drupal::service().

  • 🇦🇺Australia acbramley

    Removing the original report here as it's just confusing as it was originally the opposite.

  • IIRC, using \Drupal::service() instead of $this->container->get() addresses issues that surfaced while trying to fix 📌 Memory leak in DrupalKernel when installing modules Active in any test that has a container rebuild. Some of the relevant discussion might've been in Slack, though.

  • Pipeline finished with Failed
    11 days ago
    Total: 178s
    #463045
  • Pipeline finished with Failed
    11 days ago
    Total: 588s
    #463047
  • Pipeline finished with Success
    11 days ago
    Total: 766s
    #463059
  • 🇦🇺Australia mstrelan

    Managed to fix 405 files and only had one fail. Have added a @phpstan-ignore to NodeAccessGrantsCacheContextTest for now. Changing from a Plan to a Task and setting Needs Review.

  • 🇮🇹Italy mondrake 🇮🇹

    Some comments.

    1. General topic: adding new PHPStan rules to Drupal core. As already found in 📌 Introduce a @return-type-will-be-added annotation to indicate return type addition in next major; enforce with a PHPStan rule Active , new Drupal-defined rules added to Drupal phpstan.neon will not be visible to custom/contrib unless they also add the rule to their projects' neon files. mglaman/phpstan-drupal in that sense is different because in that case all the rules are added as part of the extension installation via composer. Unless we do something, there's high risk that Drupal core own rules will not be checked. The existing rule is different because it only checks Drupal component code that is not present in modules/themes/etc.
    2. As discussed in ✨ Add a trait for autowiring properties in tests Needs work , it seems to me that only preventing usage of $this->container->get() is not enough. I understand the problem is that any service should always be accessed from the singleton. Therefore we should also discourage contructs that store a service in a test property or a local variable like
        $cache = \Drupal::service('cache');
        ...
        $cache->get(...);
      

      no? That would be tricky.

    3. The new PHPStan rule needs tests. Actually see how test coverage instruments in PHPStan rules testing are adding the red line in the MR where the rule is introduced.
  • 🇦🇺Australia mstrelan

    Thanks @mondrake, some great points there. My initial thoughts on those:

    1. I think automatically applying this rule everywhere in contrib and custom code would be quite disruptive, so it's almost a nice side effect that it would be opt-in. Ultimately I don't really care where it lives. It could probably even be a phpcs sniff that can be auto-fixed with phpcbf.

    2. I think that could be handled separately in a follow up? Better to make progress than to get it perfect first go. Unless doing this makes things worse than the current state.

    3. Absolutely. Keen to get more feedback first though.

Production build 0.71.5 2024