We have a Functional test class derived from BrowserTestBase which is passing, but the output includes a deprecation notice.

Adding non-existent permissions to a role is deprecated in drupal:9.3.0 and triggers a runtime exception before drupal:10.0.0. The incorrect permissions are "edit any page content". Permissions should be defined in a permissions.yml file or a permission callback. See https://www.drupal.org/node/3193348

The class's $modules array includes the node module, as well as a custom module whose implementation of hook_install() assigns permissions to roles. One of those permissions is the "edit any page content" permission. When the module is installed on the site the permissions are assigned correctly. My understanding of the Node module is that it creates and enables the Article and Page content types by default, exposing the permissions appropriate to those content types, and that is indeed what happens on the site. But phpunit can't find those permissions, even though it knows that loading of the Node module is required. Including a call to $this->drupalCreateContentType() in setUp() doesn't eliminate the notice. Presumably if I don't figure this out the tests will start failing when we try to move to Drupal 10. We could work around the problem by backing out the code to assign the permission in the hook, and just assign it manually, but that's kind of ugly. I could also hack the hook implementation to detect when it's running under phpunit (assuming that's possible), and skip that assignment in that case, but that's also hackier than I would like.

  • Thanks for the edits, @apaderno. I looked at the documentation for the "9" tag which I thought said something like "don't use this just to indicate which version of Drupal you're running." I guess I didn't understand what they were trying to say.
    – Bob Kline
    Mar 23 at 20:47
  • It is trying to convey the concept that not every question needs to use a version tag. In this case, 9 is fine as Drupal 10 is the latest release and it is important to make clear you are not asking a question for Drupal 10. If I misunderstood the question, and it is a question for Drupal 10, I apologize.
    – apaderno
    Mar 24 at 8:59
  • OK, thanks for the clarification. For future questions, how would I convey that the question does not apply to versions of Drupal older than 8, but might apply to any version after 7 (bearing in mind that since I haven't upgraded to 10 yet I won't know for sure that the question would be appropriate for that version, hence the "might apply" above)?
    – Bob Kline
    Mar 24 at 17:19
  • It does not apply to any version after Drupal 8, but it may apply to any version after Drupal 7, means the question is about Drupal 8 and it should be tagged 8. Do not worry too much about version tags; if it is better not to use them in a question, they will just be removed. We cannot pretend users understand every time how to use them; we just ask not to use two or more version tags in the same question.
    – apaderno
    Mar 24 at 18:58
  • Sure. I was just trying to get with the program. I read the guidelines, which seemed to say I shouldn't use a version tag here, so that's what I did. Then I saw that you added the version tag, so I figured I must have misunderstood those guidelines. 😅
    – Bob Kline
    Mar 24 at 22:11

1 Answer 1


I believe I have figured out what we need to do, and it's a sort of a variation on the second of the two workarounds I identified in the original question above. As far as I can tell, my assumption that installing the node module automatically created and enabled the article and page content types was not valid. I now think that this magic is handled by the drush site:install command, probably in connection with the default profile it uses. Since phpunit can't take advantage of that magic, the install hook implementation really does have to figure out whether it's running as part of a test (by finding out if the content types have already been created) and if so, it must itself create the type whose permission it wants to install. After adding this to the top of that hook implementation:

  $types = \Drupal::entityTypeManager()
  if (!array_key_exists('page', $types)) {
    $type = NodeType::create(['type' => 'page', 'name' => 'Basic page']);

... the deprecation warning is gone. The permissions are brought into existence automatically when the content type is created, but the creation of the content type does not happen just by virtue of enabling the node module.

  • 2
    A content type would be made using either the standard install profile, or a custom install profile that includes content type(s). Enabling the node module alone does not create any.
    – Kevin
    Mar 23 at 16:59
  • 1
    Having said that, no, the need to set up configuration like this to provide the conditions for testing aren't bad or hacky. It can be done via install profile, test module configurations, or doing configuration inline in the test itself (which may be more manageble than piles of yaml files just for tests).
    – Kevin
    Mar 23 at 21:28
  • Yes, I don't think of the solution I hit on as a hack, as it ensures that the permissions during testing match those in effect for production use. What I would have been uncomfortable with was the workaround as I originally described it, as it would have had the opposite effect, avoiding setting a permission which would be set in normal operations in order to avoid the deprecation message (and eventual error). The approach I settled on gives us the the best of both worlds: consistent permissions without deprecated behavior.
    – Bob Kline
    Mar 24 at 1:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.