diff --git a/entity_embed.module b/entity_embed.module
index 47c202c..0a3360c 100644
--- a/entity_embed.module
+++ b/entity_embed.module
@@ -5,44 +5,26 @@
  * Framework for allowing entities to be embedded in CKEditor.
  */
 
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\entity_embed\Hook\EntityEmbedHooks;
 use Drupal\Component\Serialization\Json;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Field\FieldItemListInterface;
-use Drupal\Core\Entity\ContentEntityInterface;
-use Drupal\embed\EmbedButtonInterface;
-use Drupal\embed\Entity\EmbedButton;
-use Drupal\entity_embed\Event\EmbedButtonEvent;
 
 /**
  * Implements hook_help().
  */
+#[LegacyHook]
 function entity_embed_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'help.page.entity_embed':
-      $output = '';
-      $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Entity Embed module allows entities to be embedded in formatted text.') . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('Embedding media') . '</dt>';
-      $output .= '<dd>' . t('This module, and the text filter that it provides along with the CKEditor integration, is especially suited to allow content authors to embed media in their textual content: images, video, and so on.') . '</dd>';
-      $output .= '<dt>' . t('Embedding arbitrary content') . '</dt>';
-      $output .= '<dd>' . t('As mentioned above, this module is especially helpful for embedding media in textual content, but it is not necessarily restricted to that; it allows <em>any</em> entity to be embedded. On an e-commerce site, you may want to embed products, on a company blog you may want to embed past projects, and so on.') . '</dd>';
-      $output .= '</dl>';
-      return $output;
-  }
+  return \Drupal::service(EntityEmbedHooks::class)->help($route_name, $route_match);
 }
 
 /**
  * Implements hook_theme().
  */
+#[LegacyHook]
 function entity_embed_theme() {
-  return [
-    'entity_embed_container' => [
-      'render element' => 'element',
-    ],
-  ];
+  return \Drupal::service(EntityEmbedHooks::class)->theme();
 }
 
 /**
@@ -71,9 +53,9 @@ function template_preprocess_entity_embed_container(array &$variables) {
  *
  * Implementation on behalf of the file module.
  */
+#[LegacyHook]
 function file_entity_embed_display_plugins_alter(array &$plugins) {
-  // The RSS enclosure field formatter is not usable for Entity Embed.
-  unset($plugins['file:file_rss_enclosure']);
+  \Drupal::service(EntityEmbedHooks::class)->fileEntityEmbedDisplayPluginsAlter($plugins);
 }
 
 /**
@@ -81,9 +63,9 @@ function file_entity_embed_display_plugins_alter(array &$plugins) {
  *
  * Implementation on behalf of the taxonomy module.
  */
+#[LegacyHook]
 function taxonomy_entity_embed_display_plugins_alter(array &$plugins) {
-  // The RSS category field formatter is not usable for Entity Embed.
-  unset($plugins['entity_reference:entity_reference_rss_category']);
+  \Drupal::service(EntityEmbedHooks::class)->taxonomyEntityEmbedDisplayPluginsAlter($plugins);
 }
 
 /**
@@ -96,28 +78,25 @@ function taxonomy_entity_embed_display_plugins_alter(array &$plugins) {
  *
  * @todo Remove when https://www.drupal.org/node/2567919 is fixed in core.
  */
+#[LegacyHook]
 function entity_embed_entity_embed_display_plugins_for_context_alter(array &$definitions, array $context) {
-  if ($context['entity_type'] === 'file' && !\Drupal::moduleHandler()->moduleExists('file_entity')) {
-    unset($definitions['entity_reference:entity_reference_entity_view']);
-  }
+  \Drupal::service(EntityEmbedHooks::class)->entityEmbedDisplayPluginsForContextAlter($definitions, $context);
 }
 
 /**
  * Implements hook_form_FORM_ID_alter().
  */
+#[LegacyHook]
 function entity_embed_form_filter_format_edit_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
-  // Add an additional validate callback so we can ensure the order of filters
-  // is correct.
-  $form['#validate'][] = 'entity_embed_filter_format_edit_form_validate';
+  \Drupal::service(EntityEmbedHooks::class)->formFilterFormatEditFormAlter($form, $form_state, $form_id);
 }
 
 /**
  * Implements hook_form_FORM_ID_alter().
  */
+#[LegacyHook]
 function entity_embed_form_filter_format_add_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
-  // Add an additional validate callback so we can ensure the order of filters
-  // is correct.
-  $form['#validate'][] = 'entity_embed_filter_format_edit_form_validate';
+  \Drupal::service(EntityEmbedHooks::class)->formFilterFormatAddFormAlter($form, $form_state, $form_id);
 }
 
 /**
@@ -291,52 +270,23 @@ function entity_embed_filter_format_edit_form_validate($form, FormStateInterface
 /**
  * Implements hook_field_widget_single_element_form_alter().
  */
+#[LegacyHook]
 function entity_embed_field_widget_single_element_form_alter(&$element, FormStateInterface $form_state, $context) {
-  // Add a `data-entity_embed-host-entity-langcode` attribute so that
-  // entity_embed's JavaScript can pass the host entity's language to
-  // EntityEmbedDialog, allowing it to present entities in the same language.
-  if (isset($element['#type']) && $element['#type'] === 'text_format') {
-    /** @var FieldItemListInterface $items */
-    $items = $context['items'];
-    $element['#attributes']['data-entity_embed-host-entity-langcode'] = $items->getEntity()->language()->getId();
-  }
+  \Drupal::service(EntityEmbedHooks::class)->fieldWidgetSingleElementFormAlter($element, $form_state, $context);
 }
 
 /**
  * Implements hook_library_info_alter().
  */
+#[LegacyHook]
 function entity_embed_library_info_alter(&$libraries, $extension) {
-  // Create the drupalSettings dynamically based on embed buttons for the
-  // admin library.
-  if ($extension === 'entity_embed' && isset($libraries['admin.entity_embed'])) {
-    $entity_embed_buttons = \Drupal::entityTypeManager()
-      ->getStorage('embed_button')
-      // @see \Drupal\entity_embed\Plugin\EmbedType\Entity
-      ->loadByProperties(['type_id' => 'entity']);
-    foreach ($entity_embed_buttons as $entity_embed_button) {
-      $libraries['admin.entity_embed']['drupalSettings']['embedButtons'][$entity_embed_button->id()] = [
-        'id' => $entity_embed_button->id(),
-        'icon' => $entity_embed_button->getIconUrl(),
-      ];
-
-    }
-    $libraries['admin.entity_embed']['drupalSettings']['modulePath'] = \Drupal::service('extension.list.module')->getPath('entity_embed');
-  }
+  \Drupal::service(EntityEmbedHooks::class)->libraryInfoAlter($libraries, $extension);
 }
 
 /**
  * Implements hook_ckeditor4to5upgrade_plugin_info_alter().
  */
+#[LegacyHook]
 function entity_embed_ckeditor4to5upgrade_plugin_info_alter(array &$plugin_definitions): void {
-  // Get the user set buttons and add them to the entity embed plugin definition
-  $buttons = [];
-  $embed_buttons = \Drupal::entityTypeManager()
-    ->getStorage('embed_button')
-    ->loadByProperties(['type_id' => 'entity']);
-
-  foreach ($embed_buttons as $embed_button) {
-    $buttons[] = $embed_button->id();
-  }
-
-  $plugin_definitions['entity_embed']['cke4_buttons'] = $buttons;
+  \Drupal::service(EntityEmbedHooks::class)->ckeditor4to5upgradePluginInfoAlter($plugin_definitions);
 }
diff --git a/entity_embed.services.yml b/entity_embed.services.yml
index 9202c46..76baf9c 100644
--- a/entity_embed.services.yml
+++ b/entity_embed.services.yml
@@ -10,3 +10,7 @@ services:
   entity_embed.builder:
     class: Drupal\entity_embed\EntityEmbedBuilder
     arguments: ['@module_handler', '@plugin.manager.entity_embed.display']
+
+  Drupal\entity_embed\Hook\EntityEmbedHooks:
+    class: Drupal\entity_embed\Hook\EntityEmbedHooks
+    autowire: true
diff --git a/src/EntityEmbedDisplay/FieldFormatterEntityEmbedDisplayBase.php b/src/EntityEmbedDisplay/FieldFormatterEntityEmbedDisplayBase.php
index aee67dc..0fcfedb 100644
--- a/src/EntityEmbedDisplay/FieldFormatterEntityEmbedDisplayBase.php
+++ b/src/EntityEmbedDisplay/FieldFormatterEntityEmbedDisplayBase.php
@@ -3,14 +3,10 @@
 namespace Drupal\entity_embed\EntityEmbedDisplay;
 
 use Drupal\Core\Access\AccessResult;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Field\BaseFieldDefinition;
-use Drupal\Core\Field\FormatterPluginManager;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Language\LanguageManagerInterface;
 use Drupal\Core\Plugin\PluginDependencyTrait;
 use Drupal\Core\Session\AccountInterface;
-use Drupal\Core\TypedData\TypedDataManager;
 use Drupal\entity_embed\Entity\EntityEmbedFakeEntity;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -124,7 +120,7 @@ abstract class FieldFormatterEntityEmbedDisplayBase extends EntityEmbedDisplayBa
 
     $definition = $this->getFieldDefinition();
 
-    /* @var \Drupal\Core\Field\FieldItemListInterface $items $items */
+    /** @var \Drupal\Core\Field\FieldItemListInterface $items $items */
     // Create a field item list object, 1 is the value, array('target_id' => 1)
     // would work too, or multiple values. 1 is passed down from the list to the
     // field item, which knows that an integer is the ID.
@@ -142,7 +138,7 @@ abstract class FieldFormatterEntityEmbedDisplayBase extends EntityEmbedDisplayBa
     // For some reason $build[0]['#printed'] is TRUE, which means it will fail
     // to render later. So for now we manually fix that.
     // @todo Investigate why this is needed.
-    show($build[0]);
+    $build[0]['#printed'] = FALSE;
 
     // Refresh the entity reference stored in the context. This is necessary in
     // Drupal 10.5+ and 11.2+ since the entity might have been cloned during the
diff --git a/src/Hook/EntityEmbedHooks.php b/src/Hook/EntityEmbedHooks.php
new file mode 100644
index 0000000..7950f12
--- /dev/null
+++ b/src/Hook/EntityEmbedHooks.php
@@ -0,0 +1,160 @@
+<?php
+
+namespace Drupal\entity_embed\Hook;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+
+/**
+ * Hook implementations for entity_embed.
+ */
+class EntityEmbedHooks {
+  use StringTranslationTrait;
+
+  /**
+   * Implements hook_help().
+   */
+  #[Hook('help')]
+  public function help($route_name, RouteMatchInterface $route_match) {
+    switch ($route_name) {
+      case 'help.page.entity_embed':
+        $output = '';
+        $output .= '<h3>' . $this->t('About') . '</h3>';
+        $output .= '<p>' . $this->t('The Entity Embed module allows entities to be embedded in formatted text.') . '</p>';
+        $output .= '<h3>' . $this->t('Uses') . '</h3>';
+        $output .= '<dl>';
+        $output .= '<dt>' . $this->t('Embedding media') . '</dt>';
+        $output .= '<dd>' . $this->t('This module, and the text filter that it provides along with the CKEditor integration, is especially suited to allow content authors to embed media in their textual content: images, video, and so on.') . '</dd>';
+        $output .= '<dt>' . $this->t('Embedding arbitrary content') . '</dt>';
+        $output .= '<dd>' . $this->t('As mentioned above, this module is especially helpful for embedding media in textual content, but it is not necessarily restricted to that; it allows <em>any</em> entity to be embedded. On an e-commerce site, you may want to embed products, on a company blog you may want to embed past projects, and so on.') . '</dd>';
+        $output .= '</dl>';
+        return $output;
+    }
+  }
+
+  /**
+   * Implements hook_theme().
+   */
+  #[Hook('theme')]
+  public function theme() {
+    return [
+      'entity_embed_container' => [
+        'render element' => 'element',
+      ],
+    ];
+  }
+
+  /**
+   * Implements hook_entity_embed_display_plugins_alter().
+   *
+   * Implementation on behalf of the file module.
+   */
+  #[Hook('entity_embed_display_plugins_alter', module: 'file')]
+  public function fileEntityEmbedDisplayPluginsAlter(array &$plugins) {
+    // The RSS enclosure field formatter is not usable for Entity Embed.
+    unset($plugins['file:file_rss_enclosure']);
+  }
+
+  /**
+   * Implements hook_entity_embed_display_plugins_alter().
+   *
+   * Implementation on behalf of the taxonomy module.
+   */
+  #[Hook('entity_embed_display_plugins_alter', module: 'taxonomy')]
+  public function taxonomyEntityEmbedDisplayPluginsAlter(array &$plugins) {
+    // The RSS category field formatter is not usable for Entity Embed.
+    unset($plugins['entity_reference:entity_reference_rss_category']);
+  }
+
+  /**
+   * Implements hook_entity_embed_display_plugins_for_context_alter().
+   *
+   * The 'Rendered entity' formatter can not be used for files unless the
+   * file_entity module is available.
+   *
+   * @see https://www.drupal.org/node/2468387
+   *
+   * @todo Remove when https://www.drupal.org/node/2567919 is fixed in core.
+   */
+  #[Hook('entity_embed_display_plugins_for_context_alter')]
+  public function entityEmbedDisplayPluginsForContextAlter(array &$definitions, array $context) {
+    if ($context['entity_type'] === 'file' && !\Drupal::moduleHandler()->moduleExists('file_entity')) {
+      unset($definitions['entity_reference:entity_reference_entity_view']);
+    }
+  }
+
+  /**
+   * Implements hook_form_FORM_ID_alter().
+   */
+  #[Hook('form_filter_format_edit_form_alter')]
+  public function formFilterFormatEditFormAlter(array &$form, FormStateInterface $form_state, $form_id) {
+    // Add an additional validate callback so we can ensure the order of filters
+    // is correct.
+    $form['#validate'][] = 'entity_embed_filter_format_edit_form_validate';
+  }
+
+  /**
+   * Implements hook_form_FORM_ID_alter().
+   */
+  #[Hook('form_filter_format_add_form_alter')]
+  public function formFilterFormatAddFormAlter(array &$form, FormStateInterface $form_state, $form_id) {
+    // Add an additional validate callback so we can ensure the order of filters
+    // is correct.
+    $form['#validate'][] = 'entity_embed_filter_format_edit_form_validate';
+  }
+
+  /**
+   * Implements hook_field_widget_single_element_form_alter().
+   */
+  #[Hook('field_widget_single_element_form_alter')]
+  public function fieldWidgetSingleElementFormAlter(&$element, FormStateInterface $form_state, $context) {
+    // Add a `data-entity_embed-host-entity-langcode` attribute so that
+    // entity_embed's JavaScript can pass the host entity's language to
+    // EntityEmbedDialog, allowing it to present entities in the same language.
+    if (isset($element['#type']) && $element['#type'] === 'text_format') {
+      /** @var FieldItemListInterface $items */
+      $items = $context['items'];
+      $element['#attributes']['data-entity_embed-host-entity-langcode'] = $items->getEntity()->language()->getId();
+    }
+  }
+
+  /**
+   * Implements hook_library_info_alter().
+   */
+  #[Hook('library_info_alter')]
+  public function libraryInfoAlter(&$libraries, $extension) {
+    // Create the drupalSettings dynamically based on embed buttons for the
+    // admin library.
+    if ($extension === 'entity_embed' && isset($libraries['admin.entity_embed'])) {
+      $entity_embed_buttons = \Drupal::entityTypeManager()->getStorage('embed_button')->loadByProperties([
+        'type_id' => 'entity',
+      ]);
+      foreach ($entity_embed_buttons as $entity_embed_button) {
+        $libraries['admin.entity_embed']['drupalSettings']['embedButtons'][$entity_embed_button->id()] = [
+          'id' => $entity_embed_button->id(),
+          'icon' => $entity_embed_button->getIconUrl(),
+        ];
+      }
+      $libraries['admin.entity_embed']['drupalSettings']['modulePath'] = \Drupal::service('extension.list.module')->getPath('entity_embed');
+    }
+  }
+
+  /**
+   * Implements hook_ckeditor4to5upgrade_plugin_info_alter().
+   */
+  #[Hook('ckeditor4to5upgrade_plugin_info_alter')]
+  public function ckeditor4to5upgradePluginInfoAlter(array &$plugin_definitions): void {
+    // Get the user set buttons and add them to the entity embed plugin definition.
+    $buttons = [];
+    $embed_buttons = \Drupal::entityTypeManager()->getStorage('embed_button')->loadByProperties([
+      'type_id' => 'entity',
+    ]);
+    foreach ($embed_buttons as $embed_button) {
+      $buttons[] = $embed_button->id();
+    }
+    $plugin_definitions['entity_embed']['cke4_buttons'] = $buttons;
+  }
+
+}
diff --git a/tests/modules/entity_embed_ckeditor_test/entity_embed_ckeditor_test.module b/tests/modules/entity_embed_ckeditor_test/entity_embed_ckeditor_test.module
index dea938c..09a4c8d 100644
--- a/tests/modules/entity_embed_ckeditor_test/entity_embed_ckeditor_test.module
+++ b/tests/modules/entity_embed_ckeditor_test/entity_embed_ckeditor_test.module
@@ -7,11 +7,13 @@
 
 declare(strict_types=1);
 
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\entity_embed_ckeditor_test\Hook\EntityEmbedCkeditorTestHooks;
+
 /**
  * Implements hook_editor_info_alter().
  */
+#[LegacyHook]
 function entity_embed_ckeditor_test_editor_info_alter(array &$editors) {
-  // Drupal 9 used to have an editor called ckeditor. Copy the Unicorn editor to
-  // it to be able to test upgrading to CKEditor 5.
-  $editors['ckeditor'] = $editors['unicorn'];
+  \Drupal::service(EntityEmbedCkeditorTestHooks::class)->editorInfoAlter($editors);
 }
diff --git a/tests/modules/entity_embed_ckeditor_test/entity_embed_ckeditor_test.services.yml b/tests/modules/entity_embed_ckeditor_test/entity_embed_ckeditor_test.services.yml
new file mode 100644
index 0000000..bce2e0a
--- /dev/null
+++ b/tests/modules/entity_embed_ckeditor_test/entity_embed_ckeditor_test.services.yml
@@ -0,0 +1,5 @@
+
+services:
+  Drupal\entity_embed_ckeditor_test\Hook\EntityEmbedCkeditorTestHooks:
+    class: Drupal\entity_embed_ckeditor_test\Hook\EntityEmbedCkeditorTestHooks
+    autowire: true
diff --git a/tests/modules/entity_embed_ckeditor_test/src/Hook/EntityEmbedCkeditorTestHooks.php b/tests/modules/entity_embed_ckeditor_test/src/Hook/EntityEmbedCkeditorTestHooks.php
new file mode 100644
index 0000000..95172e6
--- /dev/null
+++ b/tests/modules/entity_embed_ckeditor_test/src/Hook/EntityEmbedCkeditorTestHooks.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Drupal\entity_embed_ckeditor_test\Hook;
+
+use Drupal\Core\Hook\Attribute\Hook;
+
+/**
+ * Hook implementations for entity_embed_ckeditor_test.
+ */
+class EntityEmbedCkeditorTestHooks {
+
+  /**
+   * Implements hook_editor_info_alter().
+   */
+  #[Hook('editor_info_alter')]
+  public function editorInfoAlter(array &$editors) {
+    // Drupal 9 used to have an editor called ckeditor. Copy the Unicorn editor to
+    // it to be able to test upgrading to CKEditor 5.
+    $editors['ckeditor'] = $editors['unicorn'];
+  }
+
+}
diff --git a/tests/modules/entity_embed_test/entity_embed_test.module b/tests/modules/entity_embed_test/entity_embed_test.module
index e1cce52..e1020a2 100644
--- a/tests/modules/entity_embed_test/entity_embed_test.module
+++ b/tests/modules/entity_embed_test/entity_embed_test.module
@@ -5,7 +5,8 @@
  * Helper module for the Entity Embed tests.
  */
 
-use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\entity_embed_test\Hook\EntityEmbedTestHooks;
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Session\AccountInterface;
@@ -13,86 +14,47 @@ use Drupal\Core\Session\AccountInterface;
 /**
  * Implements hook_theme().
  */
+#[LegacyHook]
 function entity_embed_test_theme($existing, $type, $theme, $path) {
-  $items['entity_embed_twig_test'] = [
-    'template' => 'entity_embed_twig_test',
-    'variables' => [
-      'entity_type' => '',
-      'id' => '',
-      'display_plugin' => 'default',
-      'display_settings' => [],
-    ],
-  ];
-  return $items;
+  return \Drupal::service(EntityEmbedTestHooks::class)->theme($existing, $type, $theme, $path);
 }
 
 /**
  * Implements hook_entity_embed_display_plugins_alter().
  */
+#[LegacyHook]
 function entity_embed_test_entity_embed_display_plugins_alter(&$info) {
-  // Allow tests to enable or disable this hook.
-  if (!\Drupal::state()->get('entity_embed_test_entity_embed_display_plugins_alter', FALSE)) {
-    return;
-  }
-
-  // Prefix each plugin name with 'testing_hook:'.
-  $new_info = [];
-  foreach ($info as $key => $value) {
-    $new_key = "testing_hook:" . $key;
-    $new_info[$new_key] = $info[$key];
-    unset($info[$key]);
-  }
-  $info = $new_info;
+  \Drupal::service(EntityEmbedTestHooks::class)->entityEmbedDisplayPluginsAlter($info);
 }
 
 /**
  * Implements hook_entity_embed_context_alter().
  */
+#[LegacyHook]
 function entity_embed_test_entity_embed_context_alter(array &$context, EntityInterface $entity) {
-  // Allow tests to enable or disable this hook.
-  if (!\Drupal::state()->get('entity_embed_test_entity_embed_context_alter', FALSE)) {
-    return;
-  }
-
-  // Force to use 'Label' plugin.
-  $context['data-entity-embed-display'] = 'entity_reference:entity_reference_label';
-  $context['data-entity-embed-display-settings'] = ['link' => 1];
-
-  // Set title of the entity.
-  $entity->setTitle("Title set by hook_entity_embed_context_alter");
+  \Drupal::service(EntityEmbedTestHooks::class)->entityEmbedContextAlter($context, $entity);
 }
 
 /**
  * Implements hook_entity_embed_alter().
  */
+#[LegacyHook]
 function entity_embed_test_entity_embed_alter(array &$build, EntityInterface $entity, array $context) {
-  // Allow tests to enable or disable this hook.
-  if (!\Drupal::state()->get('entity_embed_test_entity_embed_alter', FALSE)) {
-    return;
-  }
-
-  // Adding classes is as simple as appending to an array.
-  $build['#attributes']['class'][] = 'test-class-added-in-alter-hook';
-
-  // Set title of the 'node' entity.
-  $entity->setTitle("Title set by hook_entity_embed_alter");
+  \Drupal::service(EntityEmbedTestHooks::class)->entityEmbedAlter($build, $entity, $context);
 }
 
 /**
  * Implements hook_entity_access().
  */
+#[LegacyHook]
 function entity_embed_test_entity_access(EntityInterface $entity, $operation, AccountInterface $account) {
-  if ($entity->label() == 'Embed Test Node') {
-    return AccessResult::neutral()->addCacheTags(['foo:' . $entity->id()]);
-  }
+  return \Drupal::service(EntityEmbedTestHooks::class)->entityAccess($entity, $operation, $account);
 }
 
 /**
  * Implements hook_entity_view_alter().
  */
+#[LegacyHook]
 function entity_embed_test_entity_view_alter(&$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
-  $build['#attributes']['data-entity-embed-test-uuid'] = $entity->uuid();
-  $build['#attributes']['data-entity-embed-test-view-mode'] = $build['#view_mode'];
-  // @see \Drupal\Tests\entity_embed\FunctionalJavascript\MediaImageTest::testPreviewUsesDefaultTheme()
-  $build['#attributes']['data-entity-embed-test-active-theme'] = \Drupal::theme()->getActiveTheme()->getName();
+  \Drupal::service(EntityEmbedTestHooks::class)->entityViewAlter($build, $entity, $display);
 }
diff --git a/tests/modules/entity_embed_test/entity_embed_test.services.yml b/tests/modules/entity_embed_test/entity_embed_test.services.yml
index 60c6f58..2f59cce 100644
--- a/tests/modules/entity_embed_test/entity_embed_test.services.yml
+++ b/tests/modules/entity_embed_test/entity_embed_test.services.yml
@@ -3,3 +3,7 @@ services:
     class: Drupal\entity_embed_test\Routing\RouteSubscriber
     tags:
       - { name: event_subscriber }
+
+  Drupal\entity_embed_test\Hook\EntityEmbedTestHooks:
+    class: Drupal\entity_embed_test\Hook\EntityEmbedTestHooks
+    autowire: true
diff --git a/tests/modules/entity_embed_test/src/Hook/EntityEmbedTestHooks.php b/tests/modules/entity_embed_test/src/Hook/EntityEmbedTestHooks.php
new file mode 100644
index 0000000..7108491
--- /dev/null
+++ b/tests/modules/entity_embed_test/src/Hook/EntityEmbedTestHooks.php
@@ -0,0 +1,108 @@
+<?php
+
+namespace Drupal\entity_embed_test\Hook;
+
+use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+
+/**
+ * Hook implementations for entity_embed_test.
+ */
+class EntityEmbedTestHooks {
+
+  /**
+   * Implements hook_theme().
+   */
+  #[Hook('theme')]
+  public function theme($existing, $type, $theme, $path) {
+    $items['entity_embed_twig_test'] = [
+      'template' => 'entity_embed_twig_test',
+      'variables' => [
+        'entity_type' => '',
+        'id' => '',
+        'display_plugin' => 'default',
+        'display_settings' => [],
+      ],
+    ];
+    return $items;
+  }
+
+  /**
+   * Implements hook_entity_embed_display_plugins_alter().
+   */
+  #[Hook('entity_embed_display_plugins_alter')]
+  public function entityEmbedDisplayPluginsAlter(&$info) {
+    // Allow tests to enable or disable this hook.
+    if (!\Drupal::state()->get('entity_embed_test_entity_embed_display_plugins_alter', FALSE)) {
+      return;
+    }
+    // Prefix each plugin name with 'testing_hook:'.
+    $new_info = [];
+    foreach ($info as $key => $value) {
+      $new_key = "testing_hook:" . $key;
+      $new_info[$new_key] = $info[$key];
+      unset($info[$key]);
+    }
+    $info = $new_info;
+  }
+
+  /**
+   * Implements hook_entity_embed_context_alter().
+   */
+  #[Hook('entity_embed_context_alter')]
+  public function entityEmbedContextAlter(array &$context, EntityInterface $entity) {
+    // Allow tests to enable or disable this hook.
+    if (!\Drupal::state()->get('entity_embed_test_entity_embed_context_alter', FALSE)) {
+      return;
+    }
+    // Force to use 'Label' plugin.
+    $context['data-entity-embed-display'] = 'entity_reference:entity_reference_label';
+    $context['data-entity-embed-display-settings'] = [
+      'link' => 1,
+    ];
+    // Set title of the entity.
+    $entity->setTitle("Title set by hook_entity_embed_context_alter");
+  }
+
+  /**
+   * Implements hook_entity_embed_alter().
+   */
+  #[Hook('entity_embed_alter')]
+  public function entityEmbedAlter(array &$build, EntityInterface $entity, array $context) {
+    // Allow tests to enable or disable this hook.
+    if (!\Drupal::state()->get('entity_embed_test_entity_embed_alter', FALSE)) {
+      return;
+    }
+    // Adding classes is as simple as appending to an array.
+    $build['#attributes']['class'][] = 'test-class-added-in-alter-hook';
+    // Set title of the 'node' entity.
+    $entity->setTitle("Title set by hook_entity_embed_alter");
+  }
+
+  /**
+   * Implements hook_entity_access().
+   */
+  #[Hook('entity_access')]
+  public function entityAccess(EntityInterface $entity, $operation, AccountInterface $account) {
+    if ($entity->label() == 'Embed Test Node') {
+      return AccessResult::neutral()->addCacheTags([
+        'foo:' . $entity->id(),
+      ]);
+    }
+  }
+
+  /**
+   * Implements hook_entity_view_alter().
+   */
+  #[Hook('entity_view_alter')]
+  public function entityViewAlter(&$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
+    $build['#attributes']['data-entity-embed-test-uuid'] = $entity->uuid();
+    $build['#attributes']['data-entity-embed-test-view-mode'] = $build['#view_mode'];
+    // @see \Drupal\Tests\entity_embed\FunctionalJavascript\MediaImageTest::testPreviewUsesDefaultTheme()
+    $build['#attributes']['data-entity-embed-test-active-theme'] = \Drupal::theme()->getActiveTheme()->getName();
+  }
+
+}
diff --git a/tests/src/Functional/EntityEmbedDialogTest.php b/tests/src/Functional/EntityEmbedDialogTest.php
index ddfe755..11fe5bb 100644
--- a/tests/src/Functional/EntityEmbedDialogTest.php
+++ b/tests/src/Functional/EntityEmbedDialogTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\entity_embed\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\editor\Entity\Editor;
 
 /**
@@ -9,6 +11,8 @@ use Drupal\editor\Entity\Editor;
  *
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class EntityEmbedDialogTest extends EntityEmbedTestBase {
 
   /**
diff --git a/tests/src/Functional/EntityEmbedDisplayManagerTest.php b/tests/src/Functional/EntityEmbedDisplayManagerTest.php
index 4d2354b..29f6569 100644
--- a/tests/src/Functional/EntityEmbedDisplayManagerTest.php
+++ b/tests/src/Functional/EntityEmbedDisplayManagerTest.php
@@ -2,12 +2,16 @@
 
 namespace Drupal\Tests\entity_embed\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Tests\BrowserTestBase;
 
 /**
  * @coversDefaultClass \Drupal\entity_embed\EntityEmbedDisplay\EntityEmbedDisplayManager
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class EntityEmbedDisplayManagerTest extends BrowserTestBase {
 
   /**
diff --git a/tests/src/Functional/EntityEmbedEntityBrowserTest.php b/tests/src/Functional/EntityEmbedEntityBrowserTest.php
index 0ea506d..ec9f477 100644
--- a/tests/src/Functional/EntityEmbedEntityBrowserTest.php
+++ b/tests/src/Functional/EntityEmbedEntityBrowserTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\entity_embed\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\entity_browser\Entity\EntityBrowser;
 use Drupal\embed\Entity\EmbedButton;
 
@@ -12,6 +14,8 @@ use Drupal\embed\Entity\EmbedButton;
  *
  * @dependencies entity_browser
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class EntityEmbedEntityBrowserTest extends EntityEmbedDialogTest {
 
   /**
diff --git a/tests/src/Functional/EntityEmbedHooksTest.php b/tests/src/Functional/EntityEmbedHooksTest.php
index 2737cae..ae45204 100644
--- a/tests/src/Functional/EntityEmbedHooksTest.php
+++ b/tests/src/Functional/EntityEmbedHooksTest.php
@@ -2,11 +2,16 @@
 
 namespace Drupal\Tests\entity_embed\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+
 /**
  * Tests the hooks provided by entity_embed module.
  *
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class EntityEmbedHooksTest extends EntityEmbedTestBase {
 
   /**
diff --git a/tests/src/Functional/EntityEmbedTwigTest.php b/tests/src/Functional/EntityEmbedTwigTest.php
index b5fa45d..561f1fd 100644
--- a/tests/src/Functional/EntityEmbedTwigTest.php
+++ b/tests/src/Functional/EntityEmbedTwigTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\entity_embed\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\entity_embed\Twig\EntityEmbedTwigExtension;
 
 /**
@@ -9,6 +11,8 @@ use Drupal\entity_embed\Twig\EntityEmbedTwigExtension;
  *
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class EntityEmbedTwigTest extends EntityEmbedTestBase {
 
   /**
diff --git a/tests/src/Functional/EntityReferenceFieldFormatterTest.php b/tests/src/Functional/EntityReferenceFieldFormatterTest.php
index fa4c977..6291116 100644
--- a/tests/src/Functional/EntityReferenceFieldFormatterTest.php
+++ b/tests/src/Functional/EntityReferenceFieldFormatterTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\entity_embed\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Core\Form\FormState;
 
 /**
@@ -9,6 +11,8 @@ use Drupal\Core\Form\FormState;
  *
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class EntityReferenceFieldFormatterTest extends EntityEmbedTestBase {
 
   /**
diff --git a/tests/src/Functional/FileFieldFormatterTest.php b/tests/src/Functional/FileFieldFormatterTest.php
index 228ba3b..a01c49f 100644
--- a/tests/src/Functional/FileFieldFormatterTest.php
+++ b/tests/src/Functional/FileFieldFormatterTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\entity_embed\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Component\Serialization\Json;
 use Drupal\Core\Form\FormState;
 
@@ -10,6 +12,8 @@ use Drupal\Core\Form\FormState;
  *
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class FileFieldFormatterTest extends EntityEmbedTestBase {
 
   /**
diff --git a/tests/src/Functional/ImageFieldFormatterTest.php b/tests/src/Functional/ImageFieldFormatterTest.php
index 2a0c977..55baa99 100644
--- a/tests/src/Functional/ImageFieldFormatterTest.php
+++ b/tests/src/Functional/ImageFieldFormatterTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\entity_embed\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Component\Serialization\Json;
 use Drupal\Core\Form\FormState;
 
@@ -10,6 +12,8 @@ use Drupal\Core\Form\FormState;
  *
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class ImageFieldFormatterTest extends EntityEmbedTestBase {
 
   /**
diff --git a/tests/src/Functional/RecursionProtectionTest.php b/tests/src/Functional/RecursionProtectionTest.php
index d722901..6048278 100644
--- a/tests/src/Functional/RecursionProtectionTest.php
+++ b/tests/src/Functional/RecursionProtectionTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\entity_embed\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\entity_embed\Plugin\Filter\EntityEmbedFilter;
 
 /**
@@ -11,6 +13,8 @@ use Drupal\entity_embed\Plugin\Filter\EntityEmbedFilter;
  *
  * @see \Drupal\Tests\entity_embed\Kernel\EntityEmbedFilterTest::testRecursionProtection
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class RecursionProtectionTest extends EntityEmbedTestBase {
 
   /**
diff --git a/tests/src/Functional/ViewModeFieldFormatterTest.php b/tests/src/Functional/ViewModeFieldFormatterTest.php
index a5fab13..bed58cd 100644
--- a/tests/src/Functional/ViewModeFieldFormatterTest.php
+++ b/tests/src/Functional/ViewModeFieldFormatterTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\entity_embed\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Core\Form\FormState;
 
 /**
@@ -9,6 +11,8 @@ use Drupal\Core\Form\FormState;
  *
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class ViewModeFieldFormatterTest extends EntityEmbedTestBase {
 
   private $plugins = [
diff --git a/tests/src/FunctionalJavascript/ButtonAdminTest.php b/tests/src/FunctionalJavascript/ButtonAdminTest.php
index 45e1e3e..d46cbde 100644
--- a/tests/src/FunctionalJavascript/ButtonAdminTest.php
+++ b/tests/src/FunctionalJavascript/ButtonAdminTest.php
@@ -2,6 +2,9 @@
 
 namespace Drupal\Tests\entity_embed\FunctionalJavascript;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+use PHPUnit\Framework\Attributes\DataProvider;
 use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
 use Drupal\Tests\media\Traits\MediaTypeCreationTrait;
 
@@ -10,6 +13,8 @@ use Drupal\Tests\media\Traits\MediaTypeCreationTrait;
  *
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class ButtonAdminTest extends WebDriverTestBase {
 
   use MediaTypeCreationTrait;
@@ -86,6 +91,7 @@ class ButtonAdminTest extends WebDriverTestBase {
    *
    * @dataProvider embedButtonAdminProvider
    */
+  #[DataProvider('embedButtonAdminProvider')]
   public function testEmbedButtonAdmin($entity_type_id, $bundle_id, $entity_embed_display_plugin_id) {
     $this->drupalLogin($this->adminUser);
 
diff --git a/tests/src/FunctionalJavascript/CKEditor5IntegrationTest.php b/tests/src/FunctionalJavascript/CKEditor5IntegrationTest.php
index 188b36e..bfc335b 100644
--- a/tests/src/FunctionalJavascript/CKEditor5IntegrationTest.php
+++ b/tests/src/FunctionalJavascript/CKEditor5IntegrationTest.php
@@ -2,6 +2,9 @@
 
 namespace Drupal\Tests\entity_embed\FunctionalJavascript;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+use PHPUnit\Framework\Attributes\DataProvider;
 use Drupal\ckeditor5\Plugin\Editor\CKEditor5;
 use Drupal\editor\Entity\Editor;
 use Drupal\filter\Entity\FilterFormat;
@@ -15,6 +18,8 @@ use Symfony\Component\Validator\ConstraintViolation;
  * @group ckeditor5
  * @internal
  */
+#[Group('ckeditor5')]
+#[RunTestsInSeparateProcesses]
 class CKEditor5IntegrationTest extends WebDriverTestBase {
 
   use CKEditor5TestTrait;
@@ -261,6 +266,7 @@ class CKEditor5IntegrationTest extends WebDriverTestBase {
    *
    * @dataProvider providerLinkability
    */
+  #[DataProvider('providerLinkability')]
   public function testLinkedEntityArbitraryHtml(bool $unrestricted): void {
     $assert_session = $this->assertSession();
 
@@ -420,6 +426,7 @@ class CKEditor5IntegrationTest extends WebDriverTestBase {
    *
    * @dataProvider providerLinkability
    */
+  #[DataProvider('providerLinkability')]
   public function testLinkability(bool $unrestricted) {
     // Disable filter_html.
     if ($unrestricted) {
@@ -554,6 +561,9 @@ class CKEditor5IntegrationTest extends WebDriverTestBase {
     $this->assertEmpty($xpath->query('//a'));
   }
 
+  /**
+   *
+   */
   public static function providerLinkability(): array {
     return [
       'restricted' => [FALSE],
@@ -566,6 +576,7 @@ class CKEditor5IntegrationTest extends WebDriverTestBase {
    *
    * @dataProvider providerLinkability
    */
+  #[DataProvider('providerLinkability')]
   public function testLinkManualDecorator(bool $unrestricted) {
     \Drupal::service('module_installer')->install(['ckeditor5_manual_decorator_test']);
     $this->resetAll();
@@ -637,6 +648,7 @@ class CKEditor5IntegrationTest extends WebDriverTestBase {
    *
    * @dataProvider previewAccessProvider
    */
+  #[DataProvider('previewAccessProvider')]
   public function testEmbedPreviewAccess(bool $entity_embed_enabled, bool $can_use_format): void {
     // Reconfigure the host entity's text format to suit our needs.
     /** @var \Drupal\filter\FilterFormatInterface $format */
diff --git a/tests/src/FunctionalJavascript/ConfigurationUiTest.php b/tests/src/FunctionalJavascript/ConfigurationUiTest.php
index 194ffc4..3ab8529 100644
--- a/tests/src/FunctionalJavascript/ConfigurationUiTest.php
+++ b/tests/src/FunctionalJavascript/ConfigurationUiTest.php
@@ -2,6 +2,9 @@
 
 namespace Drupal\Tests\entity_embed\FunctionalJavascript;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+use PHPUnit\Framework\Attributes\DataProvider;
 use Drupal\editor\Entity\Editor;
 use Drupal\filter\Entity\FilterFormat;
 
@@ -10,6 +13,8 @@ use Drupal\filter\Entity\FilterFormat;
  *
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class ConfigurationUiTest extends EntityEmbedTestBase {
 
   use SortableTestTrait;
@@ -94,6 +99,7 @@ class ConfigurationUiTest extends EntityEmbedTestBase {
    *
    * @dataProvider providerTestValidations
    */
+  #[DataProvider('providerTestValidations')]
   public function testValidationWhenAdding($filter_html_status, $entity_embed_status, $allowed_html, $expected_error_message) {
     $this->drupalGet('admin/config/content/formats/add');
 
@@ -160,6 +166,7 @@ class ConfigurationUiTest extends EntityEmbedTestBase {
    *
    * @dataProvider providerTestValidations
    */
+  #[DataProvider('providerTestValidations')]
   public function testValidationWhenEditing($filter_html_status, $entity_embed_status, $allowed_html, $expected_error_message) {
     $this->drupalGet('admin/config/content/formats/manage/embed_test');
 
diff --git a/tests/src/FunctionalJavascript/ContentTranslationTest.php b/tests/src/FunctionalJavascript/ContentTranslationTest.php
index 1d16792..7705e27 100644
--- a/tests/src/FunctionalJavascript/ContentTranslationTest.php
+++ b/tests/src/FunctionalJavascript/ContentTranslationTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\entity_embed\FunctionalJavascript;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Component\Utility\Html;
 use Drupal\file\Entity\File;
 use Drupal\media\Entity\Media;
@@ -11,6 +13,8 @@ use Drupal\media\Entity\Media;
  *
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class ContentTranslationTest extends EntityEmbedTestBase {
 
   /**
diff --git a/tests/src/FunctionalJavascript/EntityEmbedDialogTest.php b/tests/src/FunctionalJavascript/EntityEmbedDialogTest.php
index ac3173d..b35c894 100644
--- a/tests/src/FunctionalJavascript/EntityEmbedDialogTest.php
+++ b/tests/src/FunctionalJavascript/EntityEmbedDialogTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\entity_embed\FunctionalJavascript;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\editor\Entity\Editor;
 use Drupal\filter\Entity\FilterFormat;
 use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
@@ -12,6 +14,8 @@ use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
  * @group entity_embed
  * @requires function Drupal\FunctionalJavascriptTests\WebDriverTestBase::assertSession
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class EntityEmbedDialogTest extends WebDriverTestBase {
 
   /**
diff --git a/tests/src/FunctionalJavascript/ImageFieldFormatterTest.php b/tests/src/FunctionalJavascript/ImageFieldFormatterTest.php
index 3f310b7..7529db7 100644
--- a/tests/src/FunctionalJavascript/ImageFieldFormatterTest.php
+++ b/tests/src/FunctionalJavascript/ImageFieldFormatterTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\entity_embed\FunctionalJavascript;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
 use Drupal\editor\Entity\Editor;
 use Drupal\filter\Entity\FilterFormat;
@@ -11,6 +13,8 @@ use Drupal\filter\Entity\FilterFormat;
  *
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class ImageFieldFormatterTest extends WebDriverTestBase {
 
   use SortableTestTrait;
diff --git a/tests/src/FunctionalJavascript/MediaImageTest.php b/tests/src/FunctionalJavascript/MediaImageTest.php
index aae20b6..c6f6f1b 100644
--- a/tests/src/FunctionalJavascript/MediaImageTest.php
+++ b/tests/src/FunctionalJavascript/MediaImageTest.php
@@ -2,6 +2,9 @@
 
 namespace Drupal\Tests\entity_embed\FunctionalJavascript;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+use PHPUnit\Framework\Attributes\DataProvider;
 use Drupal\Component\Utility\Html;
 use Drupal\editor\Entity\Editor;
 use Drupal\entity_embed\Plugin\entity_embed\EntityEmbedDisplay\MediaImageDecorator;
@@ -16,6 +19,8 @@ use Drupal\Tests\TestFileCreationTrait;
  *
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class MediaImageTest extends EntityEmbedTestBase {
 
   use ContentTypeCreationTrait;
@@ -783,6 +788,7 @@ JS;
    *
    * @dataProvider providerCkeditorWidgetWorksForAllEmbeds
    */
+  #[DataProvider('providerCkeditorWidgetWorksForAllEmbeds')]
   public function testCkeditorWidgetWorksForAllEmbeds($data_embed_button_attribute) {
     $this->host->body->value = '<drupal-entity data-caption="baz" ' . $data_embed_button_attribute . ' data-entity-embed-display="entity_reference:media_thumbnail" data-entity-embed-display-settings="{&quot;image_style&quot;:&quot;&quot;,&quot;image_link&quot;:&quot;&quot;}" data-entity-type="media" data-entity-uuid="' . $this->media->uuid() . '"></drupal-entity>';
     $this->host->save();
diff --git a/tests/src/Kernel/EntityEmbedDialogTest.php b/tests/src/Kernel/EntityEmbedDialogTest.php
index 650ae82..29690cd 100644
--- a/tests/src/Kernel/EntityEmbedDialogTest.php
+++ b/tests/src/Kernel/EntityEmbedDialogTest.php
@@ -4,6 +4,9 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\entity_embed\Kernel;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+use PHPUnit\Framework\Attributes\DataProvider;
 use Drupal\Core\Form\FormState;
 use Drupal\entity_embed\Form\EntityEmbedDialog;
 use Drupal\file\Entity\File;
@@ -13,6 +16,8 @@ use Drupal\Tests\TestFileCreationTrait;
 /**
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class EntityEmbedDialogTest extends EntityEmbedFilterTestBase {
 
   use TestFileCreationTrait;
@@ -20,6 +25,7 @@ class EntityEmbedDialogTest extends EntityEmbedFilterTestBase {
   /**
    * @dataProvider removalOfEmptyAttributesData
    */
+  #[DataProvider('removalOfEmptyAttributesData')]
   public function testRemovalOfEmptyAttributes(array $attributes, array $expected): void {
     $this->container->get('module_installer')->install(['entity_embed_test']);
 
@@ -36,7 +42,7 @@ class EntityEmbedDialogTest extends EntityEmbedFilterTestBase {
       'name' => 'Screaming hairy armadillo',
       'field_media_image' => [
         [
-          'target_id' => 1
+          'target_id' => 1,
         ],
       ],
     ]);
@@ -78,7 +84,7 @@ class EntityEmbedDialogTest extends EntityEmbedFilterTestBase {
       ],
       'Test with non-empty alt and title and display settings.' => [
         'attributes' => $attributes +
-            ['data-entity-embed-display-settings' => ['alt' => 'ALT', 'title' => 'TITLE', 'setting' => 'SETTING']],
+          ['data-entity-embed-display-settings' => ['alt' => 'ALT', 'title' => 'TITLE', 'setting' => 'SETTING']],
         'expected' => $attributes +
           ['data-entity-embed-display-settings' => '{"setting":"SETTING"}'] +
           ['alt' => 'ALT', 'title' => 'TITLE'] ,
diff --git a/tests/src/Kernel/EntityEmbedFilterDisabledIntegrationsTest.php b/tests/src/Kernel/EntityEmbedFilterDisabledIntegrationsTest.php
index 463ff6e..17c7a6d 100644
--- a/tests/src/Kernel/EntityEmbedFilterDisabledIntegrationsTest.php
+++ b/tests/src/Kernel/EntityEmbedFilterDisabledIntegrationsTest.php
@@ -2,12 +2,18 @@
 
 namespace Drupal\Tests\entity_embed\Kernel;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+use PHPUnit\Framework\Attributes\DataProvider;
+
 /**
  * Tests that entity embed disables certain integrations.
  *
  * @coversDefaultClass \Drupal\entity_embed\Plugin\Filter\EntityEmbedFilter
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class EntityEmbedFilterDisabledIntegrationsTest extends EntityEmbedFilterTestBase {
 
   /**
@@ -36,6 +42,7 @@ class EntityEmbedFilterDisabledIntegrationsTest extends EntityEmbedFilterTestBas
    * @covers \Drupal\entity_embed\Plugin\entity_embed\EntityEmbedDisplay\EntityReferenceFieldFormatter::disableQuickEdit
    * @dataProvider providerDisabledIntegrations
    */
+  #[DataProvider('providerDisabledIntegrations')]
   public function testDisabledIntegrations($integration_detection_selector) {
     $text = $this->createEmbedCode([
       'data-entity-type' => 'node',
@@ -54,7 +61,7 @@ class EntityEmbedFilterDisabledIntegrationsTest extends EntityEmbedFilterTestBas
     return [
       'contextual' => [
         'div.embedded-entity > .contextual-region',
-      ]
+      ],
     ];
   }
 
diff --git a/tests/src/Kernel/EntityEmbedFilterLegacyTest.php b/tests/src/Kernel/EntityEmbedFilterLegacyTest.php
index 8b83bef..6fe80bf 100644
--- a/tests/src/Kernel/EntityEmbedFilterLegacyTest.php
+++ b/tests/src/Kernel/EntityEmbedFilterLegacyTest.php
@@ -2,11 +2,18 @@
 
 namespace Drupal\Tests\entity_embed\Kernel;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\IgnoreDeprecations;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+
 /**
  * @coversDefaultClass \Drupal\entity_embed\Plugin\Filter\EntityEmbedFilter
  * @group entity_embed
  * @group legacy
  */
+#[Group('entity_embed')]
+#[IgnoreDeprecations]
+#[RunTestsInSeparateProcesses]
 class EntityEmbedFilterLegacyTest extends EntityEmbedFilterTestBase {
 
   /**
diff --git a/tests/src/Kernel/EntityEmbedFilterOverridesTest.php b/tests/src/Kernel/EntityEmbedFilterOverridesTest.php
index 8fb38a7..d9e9100 100644
--- a/tests/src/Kernel/EntityEmbedFilterOverridesTest.php
+++ b/tests/src/Kernel/EntityEmbedFilterOverridesTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\entity_embed\Kernel;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\file\Entity\File;
 use Drupal\media\Entity\Media;
@@ -14,6 +16,8 @@ use Drupal\Tests\TestFileCreationTrait;
  * @coversDefaultClass \Drupal\entity_embed\Plugin\Filter\EntityEmbedFilter
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class EntityEmbedFilterOverridesTest extends EntityEmbedFilterTestBase {
 
   use MediaTypeCreationTrait;
diff --git a/tests/src/Kernel/EntityEmbedFilterTest.php b/tests/src/Kernel/EntityEmbedFilterTest.php
index f69a57d..67e48b7 100644
--- a/tests/src/Kernel/EntityEmbedFilterTest.php
+++ b/tests/src/Kernel/EntityEmbedFilterTest.php
@@ -2,6 +2,9 @@
 
 namespace Drupal\Tests\entity_embed\Kernel;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+use PHPUnit\Framework\Attributes\DataProvider;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\filter\FilterProcessResult;
@@ -10,6 +13,8 @@ use Drupal\filter\FilterProcessResult;
  * @coversDefaultClass \Drupal\entity_embed\Plugin\Filter\EntityEmbedFilter
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class EntityEmbedFilterTest extends EntityEmbedFilterTestBase {
 
   /**
@@ -35,6 +40,7 @@ class EntityEmbedFilterTest extends EntityEmbedFilterTestBase {
    *
    * @dataProvider providerTestBasics
    */
+  #[DataProvider('providerTestBasics')]
   public function testBasics(array $embed_attributes, $expected_view_mode, array $expected_attributes) {
     $content = $this->createEmbedCode($embed_attributes);
 
@@ -56,12 +62,18 @@ class EntityEmbedFilterTest extends EntityEmbedFilterTestBase {
     $this->assertSame(['entity_embed/caption'], $result->getAttachments()['library']);
   }
 
+  /**
+   *
+   */
   private function getCacheTags(FilterProcessResult $result): array {
     $cache_tags = $result->getCacheTags();
     sort($cache_tags);
     return $cache_tags;
   }
 
+  /**
+   *
+   */
   private function getCacheContexts(FilterProcessResult $result): array {
     $cache_contexts = $result->getCacheContexts();
     sort($cache_contexts);
@@ -183,6 +195,7 @@ class EntityEmbedFilterTest extends EntityEmbedFilterTestBase {
    *
    * @dataProvider providerAccessUnpublished
    */
+  #[DataProvider('providerAccessUnpublished')]
   public function testAccessUnpublished($allowed_to_view_unpublished, $expected_rendered, CacheableMetadata $expected_cacheability, array $expected_attachments) {
     // Unpublish the embedded entity so we can test variations in behavior.
     $this->embeddedEntity->setUnpublished()->save();
@@ -258,6 +271,7 @@ class EntityEmbedFilterTest extends EntityEmbedFilterTestBase {
    *
    * @dataProvider providerMissingEntityIndicator
    */
+  #[DataProvider('providerMissingEntityIndicator')]
   public function testMissingEntityIndicator($entity_type_id, $uuid, $expected_missing_text) {
     $content = $this->createEmbedCode([
       'data-entity-type' => $entity_type_id,
@@ -355,6 +369,7 @@ class EntityEmbedFilterTest extends EntityEmbedFilterTestBase {
    * @covers \Drupal\filter\Plugin\Filter\FilterCaption
    * @dataProvider providerFilterIntegration
    */
+  #[DataProvider('providerFilterIntegration')]
   public function testFilterIntegration(array $filter_ids, array $additional_attributes, $verification_selector, $expected_verification_success, array $expected_asset_libraries, $prefix = '', $suffix = '') {
     $content = $this->createEmbedCode([
       'data-entity-type' => 'node',
diff --git a/tests/src/Kernel/EntityEmbedFilterTranslationTest.php b/tests/src/Kernel/EntityEmbedFilterTranslationTest.php
index 3660684..d794ccd 100644
--- a/tests/src/Kernel/EntityEmbedFilterTranslationTest.php
+++ b/tests/src/Kernel/EntityEmbedFilterTranslationTest.php
@@ -2,6 +2,9 @@
 
 namespace Drupal\Tests\entity_embed\Kernel;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+use PHPUnit\Framework\Attributes\DataProvider;
 use Drupal\language\Entity\ConfigurableLanguage;
 
 /**
@@ -10,6 +13,8 @@ use Drupal\language\Entity\ConfigurableLanguage;
  * @coversDefaultClass \Drupal\entity_embed\Plugin\Filter\EntityEmbedFilter
  * @group entity_embed
  */
+#[Group('entity_embed')]
+#[RunTestsInSeparateProcesses]
 class EntityEmbedFilterTranslationTest extends EntityEmbedFilterTestBase {
 
   /**
@@ -41,6 +46,7 @@ class EntityEmbedFilterTranslationTest extends EntityEmbedFilterTestBase {
    *
    * @dataProvider providerTranslationSituations
    */
+  #[DataProvider('providerTranslationSituations')]
   public function testTranslationSelection($text_langcode, array $additional_attributes, $expected_title_langcode) {
     $text = $this->createEmbedCode([
       'data-entity-type' => 'node',
diff --git a/tests/src/Kernel/UpgradePathTest.php b/tests/src/Kernel/UpgradePathTest.php
index 3992b57..e4d902f 100644
--- a/tests/src/Kernel/UpgradePathTest.php
+++ b/tests/src/Kernel/UpgradePathTest.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\entity_embed\Kernel;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\editor\Entity\Editor;
 use Drupal\filter\Entity\FilterFormat;
 use Drupal\Tests\ckeditor5\Kernel\SmartDefaultSettingsTest;
@@ -15,6 +17,9 @@ use Drupal\Tests\ckeditor5\Kernel\SmartDefaultSettingsTest;
  * @requires module ckeditor5
  * @internal
  */
+#[Group('entity_embed')]
+#[Group('ckeditor5')]
+#[RunTestsInSeparateProcesses]
 class UpgradePathTest extends SmartDefaultSettingsTest {
 
   /**
