From 55820a0de1dcf90e955e5f00ede1e5e01494ba18 Mon Sep 17 00:00:00 2001
From: Christian Kuhn <lolli@schwarzbu.ch>
Date: Fri, 23 Feb 2024 17:42:14 +0100
Subject: [PATCH] [TASK] Use phpunit attributes in functional tests

phpunit 11 deprecates annotations like `@test` and
`@dataProvider` in favor of their attribute counterparts.

We'll adapt core main & v12 to keep v12 backports
simple. The patch takes care of Tests/Functional and
Tests/FunctionalDeprecated.

Script `Build/Scripts/splitFunctionalTests.php` is
adapted to deal with annotations for CI to continue
splitting functional tests into chunks. This also
fixes detection in two test cases that had unexpected
`@test` annotation combinations which were not properly
detected before.

> composer req --dev rector/rector
> wget https://forge.typo3.org/attachments/download/38273/rector.php
> find typo3/ -name \*Test.php | grep Tests/Functional | xargs bin/rector process
> rm rector.php
> composer rem --dev rector/rector

Minor manual adaption in a few files plus cgl fixes.

Also deny `@test` annotion in annotationChecker.php now
to not introduce new occurences with other patches anymore.
The script will receive another cleanup to look at further
obsolete annotations. `@dataProvider` is currently still
used in acceptance tests.

Change-Id: I42705b57193a32db6fe17276d53476ecddcae835
Resolves: #103195
Related: #103180
Releases: main, 12.4
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/83129
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: core-ci <typo3@b13.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
---
 Build/Scripts/annotationChecker.php           |   2 +-
 Build/Scripts/splitFunctionalTests.php        |  49 ++-
 Build/phpstan/phpstan-baseline.neon           |   2 +-
 .../Authentication/PasswordResetTest.php      |  33 +-
 .../Shortcut/ShortcutRepositoryTest.php       |  15 +-
 .../Functional/Clipboard/ClipboardTest.php    |   8 +-
 .../Controller/BackendControllerTest.php      |   9 +-
 .../Controller/EditDocumentControllerTest.php |   9 +-
 .../FormInlineAjaxControllerTest.php          |  17 +-
 .../Controller/MfaAjaxControllerTest.php      |  18 +-
 .../MfaConfigurationControllerTest.php        |  45 +--
 .../Controller/MfaControllerTest.php          |  45 +--
 .../Controller/MfaSetupControllerTest.php     |  57 +---
 .../Page/LocalizationControllerTest.php       |  37 +--
 .../Controller/Page/TreeControllerTest.php    |  48 +--
 .../ResetPasswordControllerTest.php           |  25 +-
 .../Controller/ShortcutControllerTest.php     |   8 +-
 .../LocalizationRepositoryTest.php            |  21 +-
 .../Container/FilesControlContainerTest.php   |   5 +-
 .../Form/FormDataProvider/TcaCategoryTest.php |  44 +--
 .../Form/FormDataProvider/TcaGroupTest.php    |   7 +-
 .../FormDataProvider/TcaSelectItemsTest.php   | 187 +++--------
 .../TcaSelectTreeItemsTest.php                |  16 +-
 .../Functional/Form/MfaInfoElementTest.php    |  25 +-
 .../History/RecordHistoryStoreTest.php        |  24 +-
 .../Functional/History/RecordHistoryTest.php  |   8 +-
 .../Middleware/BackendModuleValidatorTest.php |  29 +-
 .../Middleware/SiteResolverTest.php           |   5 +-
 .../Functional/Module/ModuleDataTest.php      |  30 +-
 .../Functional/Module/ModuleProviderTest.php  |   5 +-
 .../RecordList/DownloadRecordListTest.php     |  13 +-
 .../Tests/Functional/Routing/RouterTest.php   |  37 +--
 .../Functional/Routing/UriBuilderTest.php     |   9 +-
 .../SiteConfigurationOverridesTest.php        |  13 +-
 .../Buttons/Action/ShortcutButtonTest.php     |  16 +-
 .../Repository/PageTreeRepositoryTest.php     |  14 +-
 .../Functional/Utility/BackendUtilityTest.php |  24 +-
 .../View/BackendViewFactoryTest.php           |  33 +-
 .../Drawing/BackendLayoutRendererTest.php     |  33 +-
 .../FlexFormValueFormatterTest.php            |  13 +-
 .../Link/EditRecordViewHelperTest.php         |  25 +-
 .../Link/NewRecordViewHelperTest.php          |  37 +--
 .../Mfa/IfHasStateViewHelperTest.php          |  13 +-
 .../Uri/EditRecordViewHelperTest.php          |  25 +-
 .../Uri/NewRecordViewHelperTest.php           |  37 +--
 .../ConditionMatcherTest.php                  |  87 ++---
 .../ViewHelpers/MfaStatusViewHelperTest.php   |  21 +-
 .../AbstractUserAuthenticationTest.php        |  20 +-
 .../AuthenticationServiceTest.php             |   5 +-
 .../BackendUserAuthenticationTest.php         |  45 +--
 .../Authentication/GroupResolverTest.php      |   6 +-
 .../Mfa/MfaProviderPropertyManagerTest.php    |  37 +--
 .../Mfa/MfaProviderRegistryTest.php           |  29 +-
 .../Provider/RecoveryCodesProviderTest.php    |  49 +--
 .../Mfa/Provider/TotpProviderTest.php         |  45 +--
 .../Cache/Backend/ApcuBackendTest.php         |  67 ++--
 .../Cache/Backend/FileBackendTest.php         | 178 +++-------
 .../Cache/Backend/MemcachedBackendTest.php    |  64 +---
 .../Cache/Backend/RedisBackendTest.php        | 237 ++++----------
 .../Backend/Typo3DatabaseBackendTest.php      | 101 ++----
 .../Cache/Core/ClassAliasLoaderTest.php       |   5 +-
 .../Cache/Frontend/VariableFrontendTest.php   |   9 +-
 .../Collection/CategoryCollectionTest.php     |  41 +--
 .../Command/CacheFlushCommandTest.php         |  17 +-
 .../Command/CacheWarmupCommandTest.php        |  17 +-
 .../Functional/Command/CliCommandTest.php     |   8 +-
 .../FlexForm/FlexFormToolsTest.php            | 204 +++---------
 .../Loader/YamlFileLoaderTest.php             |  31 +-
 .../Tests/Functional/Country/CountryTest.php  |   5 +-
 .../DataHandler/CheckboxValidationTest.php    |  25 +-
 .../DataHandler/DefaultValuesTest.php         |  17 +-
 .../DeleteTranslatedSubpagesTest.php          |   5 +-
 .../DataHandler/GetUniqueTest.php             |   8 +-
 .../DataHandler/GetUniqueTranslationTest.php  |  17 +-
 .../DataHandling/DataHandler/HookTest.php     |  21 +-
 .../DataHandling/DataHandler/SecurityTest.php |  14 +-
 .../DataHandler/SelectCheckBoxTest.php        |   9 +-
 .../DataHandler/SlugUniqueTest.php            |  20 +-
 .../DataHandler/TranslationDiffSourceTest.php |   9 +-
 .../DataResolving/PlainDataResolverTest.php   |   8 +-
 .../DataHandling/Flexform/ActionTest.php      |   9 +-
 .../DataHandling/FlexformIrre/ActionTest.php  |   9 +-
 .../DataHandling/Regular/CheckValueTest.php   |  13 +-
 .../CheckValueTestForCheckboxesTest.php       |   9 +-
 .../Regular/CheckValueTestForSelectTest.php   |   9 +-
 .../Regular/Hooks/PagesTsConfigGuardTest.php  |   9 +-
 .../DataHandling/Regular/MinValueTest.php     |  16 +-
 .../Regular/MultiSite/MultiSiteTest.php       |   6 +-
 .../Regular/PagePermissionTest.php            |  13 +-
 .../DataHandling/Slug/SlugHelperTest.php      |  12 +-
 .../Slug/SlugHelperUniqueTest.php             |  13 +-
 .../Slug/SlugHelperUniqueWithLanguageTest.php |   8 +-
 .../CategoryManyToMany/Modify/ActionTest.php  |  70 +---
 .../CategoryOneToMany/Modify/ActionTest.php   |  70 +---
 .../CategoryOneToOne/Modify/ActionTest.php    |  55 +---
 .../DataScenarios/FAL/Modify/ActionTest.php   |  94 ++----
 .../FAL/WorkspacesDiscard/ActionTest.php      |  61 +---
 .../FAL/WorkspacesModify/ActionTest.php       |  61 +---
 .../FAL/WorkspacesPublish/ActionTest.php      |  61 +---
 .../FAL/WorkspacesPublishAll/ActionTest.php   |  61 +---
 .../Modify/ActionTest.php                     |  13 +-
 .../WorkspacesDiscard/ActionTest.php          |  13 +-
 .../WorkspacesModify/ActionTest.php           |  13 +-
 .../WorkspacesPublish/ActionTest.php          |  13 +-
 .../WorkspacesPublishAll/ActionTest.php       |  13 +-
 .../DataScenarios/Group/Modify/ActionTest.php | 108 ++-----
 .../Group/WorkspacesDiscard/ActionTest.php    |  79 ++---
 .../Group/WorkspacesModify/ActionTest.php     |  73 ++---
 .../Group/WorkspacesPublish/ActionTest.php    |  73 ++---
 .../Group/WorkspacesPublishAll/ActionTest.php |  73 ++---
 .../IrreCsv/Modify/ActionTest.php             | 172 ++--------
 .../IrreCsv/WorkspacesDiscard/ActionTest.php  | 110 ++-----
 .../IrreCsv/WorkspacesModify/ActionTest.php   | 110 ++-----
 .../IrreCsv/WorkspacesPublish/ActionTest.php  | 105 ++----
 .../WorkspacesPublishAll/ActionTest.php       | 105 ++----
 .../IrreForeignField/Modify/ActionTest.php    | 200 +++---------
 .../WorkspacesDiscard/ActionTest.php          | 110 ++-----
 .../WorkspacesModify/ActionTest.php           | 115 ++-----
 .../WorkspacesPublish/ActionTest.php          | 105 ++----
 .../WorkspacesPublishAll/ActionTest.php       | 105 ++----
 .../Modify/ActionTest.php                     | 164 +++-------
 .../WorkspacesModify/ActionTest.php           |  70 +---
 .../ManyToMany/Modify/ActionTest.php          | 109 ++-----
 .../WorkspacesDiscard/ActionTest.php          | 111 ++-----
 .../WorkspacesModify/ActionTest.php           | 108 ++-----
 .../WorkspacesPublish/ActionTest.php          | 109 ++-----
 .../WorkspacesPublishAll/ActionTest.php       | 109 ++-----
 .../Regular/Modify/ActionTest.php             | 285 ++++------------
 .../Regular/WorkspacesDiscard/ActionTest.php  | 242 ++++----------
 .../Regular/WorkspacesModify/ActionTest.php   | 306 +++++-------------
 .../Regular/WorkspacesPublish/ActionTest.php  | 225 ++++---------
 .../WorkspacesPublishAll/ActionTest.php       | 240 ++++----------
 .../Select/Modify/ActionTest.php              |  99 ++----
 .../Select/WorkspacesDiscard/ActionTest.php   |  73 ++---
 .../Select/WorkspacesModify/ActionTest.php    |  73 ++---
 .../Select/WorkspacesPublish/ActionTest.php   |  73 ++---
 .../WorkspacesPublishAll/ActionTest.php       |  73 ++---
 .../SelectFlex/Modify/ActionTest.php          |   9 +-
 .../WorkspacesDiscard/ActionTest.php          |   9 +-
 .../WorkspacesModify/ActionTest.php           |   9 +-
 .../WorkspacesPublish/ActionTest.php          |   9 +-
 .../WorkspacesPublishAll/ActionTest.php       |   9 +-
 .../Functional/Database/ConnectionTest.php    |   9 +-
 .../Expression/ExpressionBuilderTest.php      | 103 ++----
 .../NamedPlaceholderPreparedStatementTest.php |   5 +-
 ...sitionPlaceholderPreparedStatementTest.php |  28 +-
 .../Database/ReferenceIndexTest.php           |   5 +-
 .../ReferenceIndexWorkspaceLoadedTest.php     |   9 +-
 .../Database/Schema/SchemaMigratorTest.php    |  89 ++---
 .../AsCommandAttributeTest.php                |  17 +-
 .../Domain/Access/RecordAccessVoterTest.php   |  22 +-
 .../Domain/Repository/PageRepositoryTest.php  | 119 ++-----
 .../Functional/Error/ErrorHandlerTest.php     |   8 +-
 .../ExpressionLanguage/ResolverTest.php       |   9 +-
 .../Html/DefaultSanitizerBuilderTest.php      |  16 +-
 .../Functional/Imaging/IconFactoryTest.php    | 118 +++----
 .../Imaging/ImageMagickFileTest.php           |  44 +--
 .../Localization/LanguageServiceTest.php      |  32 +-
 .../TcaSystemLanguageCollectorTest.php        |   9 +-
 .../Functional/Log/LoggerAwareChannelTest.php |   9 +-
 .../Log/Writer/DatabaseWriterTest.php         |   5 +-
 .../Tests/Functional/Mail/FluidEmailTest.php  |  61 +---
 .../core/Tests/Functional/Mail/MailerTest.php |   5 +-
 .../Messaging/FlashMessageQueueTest.php       |  33 +-
 .../MetaDataHandling/PluginsTest.php          |  13 +-
 .../Functional/Package/PackageStatesTest.php  |   4 +-
 .../Page/JavaScriptRendererTest.php           |   4 +-
 .../Functional/Page/PageRendererTest.php      |  28 +-
 .../PasswordPolicyValidatorTest.php           |  28 +-
 .../NotCurrentPasswordValidatorTest.php       |  13 +-
 .../RateLimiter/RateLimiterFactoryTest.php    |  12 +-
 .../core/Tests/Functional/RegistryTest.php    |  45 +--
 .../DefaultUploadFolderResolverTest.php       |  41 +--
 .../Resource/Driver/LocalDriverTest.php       | 305 +++++------------
 .../Functional/Resource/FileReferenceTest.php |   5 +-
 .../Processing/PreviewProcessingTest.php      |   5 +-
 .../Functional/Resource/ProcessedFileTest.php |   5 +-
 .../Resource/ResourceCompressorTest.php       |  29 +-
 .../Resource/ResourceStorageTest.php          |  56 +---
 .../Resource/Security/SvgSanitizerTest.php    |   8 +-
 .../Resource/StorageRepositoryTest.php        |  66 ++--
 .../SynchronizeFolderRelationsTest.php        |   9 +-
 .../Aspect/PersistedAliasMapperTest.php       |  28 +-
 .../Aspect/PersistedPatternMapperTest.php     |  28 +-
 .../ModelServiceTest.php                      |  30 +-
 .../PolicyProviderTest.php                    |   8 +-
 .../ContentSecurityPolicy/PolicyTest.php      |  79 ++---
 .../Reporting/ReportRepositoryTest.php        |   5 +-
 .../Service/Archive/ZipServiceTest.php        |  29 +-
 .../Backend/DatabaseSessionBackendTest.php    |  45 +--
 .../Backend/RedisSessionBackendTest.php       |  49 +--
 .../Functional/Session/SessionManagerTest.php |   9 +-
 .../Tca/BackendGroupsVisibleFieldsTest.php    |   5 +-
 .../Tca/BackendUsersVisibleFieldsTest.php     |   9 +-
 .../Tca/CategoryVisibleFieldsTest.php         |   5 +-
 .../Tca/FileCollectionVisibleFieldsTest.php   |   5 +-
 .../Tca/FileMetadataVisibleFieldsTest.php     |   5 +-
 .../Tca/FileStorageVisibleFieldsTest.php      |   5 +-
 .../Functional/Tca/NewsVisibleFieldsTest.php  |   5 +-
 .../Functional/Tca/PagesVisibleFieldsTest.php |   8 +-
 .../AST/AstBuilderInterfaceTest.php           |  25 +-
 ...poScriptFactoryPageLayoutConditionTest.php |  25 +-
 .../IncludeTree/SysTemplateRepositoryTest.php |  13 +-
 .../SysTemplateTreeBuilderTest.php            |  45 +--
 .../TreeFromLineStreamBuilderTest.php         |  46 +--
 ...nditionConstantSubstitutionVisitorTest.php |   8 +-
 .../IncludeTreeSyntaxScannerVisitorTest.php   |  12 +-
 ...TsConfigFactoryPageLayoutConditionTest.php |  25 +-
 .../TypoScript/PageTsConfigFactoryTest.php    |  49 +--
 .../TypoScriptStringFactoryTest.php           |   9 +-
 .../TypoScript/UserTsConfigFactoryTest.php    |  29 +-
 ...anagementUtilityTcaOverrideRequireTest.php |   6 +-
 ...tensionManagementUtilityTcaRequireTest.php |   6 +-
 .../Utility/File/ExtendedFileUtilityTest.php  |  13 +-
 .../Utility/RootlineUtilityTest.php           |  33 +-
 .../IconForRecordViewHelperTest.php           |   5 +-
 .../ViewHelpers/IconViewHelperTest.php        |  21 +-
 .../Domain/Repository/PageRepositoryTest.php  |   9 +-
 .../TypoScript/PageTsConfigFactoryTest.php    |  13 +-
 .../Parser/TypoScriptParserTest.php           |   4 +-
 .../TypoScript/UserTsConfigFactoryTest.php    |   9 +-
 .../Tests/Functional/WidgetRegistryTest.php   |  20 +-
 .../BackendConfigurationManagerTest.php       |  49 +--
 .../FrontendConfigurationManagerTest.php      |  12 +-
 .../ActionControllerArgumentTest.php          |   6 +-
 .../Mvc/Controller/ActionControllerTest.php   |  53 +--
 .../ControllerArgumentsMappingTest.php        |  10 +-
 .../ActionControllerValidationTest.php        |  16 +-
 .../Functional/Mvc/Web/RequestBuilderTest.php |  89 ++---
 .../Pagination/QueryResultPaginatorTest.php   |  32 +-
 .../Tests/Functional/Persistence/AddTest.php  |  17 +-
 .../Functional/Persistence/CountTest.php      |  42 +--
 .../Persistence/EnableFieldsTest.php          |  17 +-
 .../Generic/Mapper/ColumnMapFactoryTest.php   |  81 ++---
 .../Generic/Mapper/DataMapFactoryTest.php     |   9 +-
 .../Generic/Mapper/DataMapperTest.php         |  99 ++----
 .../Generic/Storage/Typo3DbBackendTest.php    |   9 +-
 .../Storage/Typo3DbQueryParserTest.php        | 116 ++-----
 .../Tests/Functional/Persistence/InTest.php   |  33 +-
 .../Functional/Persistence/IsDirtyTest.php    |  21 +-
 .../Persistence/LazyLoadingProxyTest.php      |   9 +-
 .../Persistence/LazyObjectStorageTest.php     |   5 +-
 .../Functional/Persistence/OperatorTest.php   |  13 +-
 .../ParentChildTranslationTest.php            |   9 +-
 .../Persistence/QueryLocalizedDataTest.php    |  35 +-
 .../Persistence/QueryParserTest.php           |  34 +-
 .../Functional/Persistence/RelationTest.php   |  78 ++---
 .../Functional/Persistence/RepositoryTest.php |  53 +--
 .../Persistence/TranslatedSiteContentTest.php |  20 +-
 .../Persistence/TranslationTest.php           |  68 ++--
 .../Functional/Persistence/WorkspaceTest.php  |  34 +-
 .../Property/PropertyMapperTest.php           |  73 ++---
 .../TypeConverter/ArrayConverterTest.php      |   5 +-
 .../TypeConverter/BooleanConverterTest.php    |   5 +-
 .../TypeConverter/DateTimeConverterTest.php   |  61 +---
 .../TypeConverter/EnumConverterTest.php       |   8 +-
 .../TypeConverter/FileConverterTest.php       |   5 +-
 .../TypeConverter/FloatConverterTest.php      |   5 +-
 .../TypeConverter/IntegerConverterTest.php    |   5 +-
 .../TypeConverter/ObjectConverterTest.php     |  65 +---
 .../ObjectStorageConverterTest.php            |   9 +-
 .../PersistentObjectConverterTest.php         |  45 +--
 .../TypeConverter/StringConverterTest.php     |   5 +-
 .../Service/ExtensionServiceTest.php          |  17 +-
 .../Utility/LocalizationUtilityTest.php       |  41 +--
 .../Validator/AlphanumericValidatorTest.php   |  17 +-
 .../Validator/BooleanValidatorTest.php        |  33 +-
 .../Validator/CollectionValidatorTest.php     |  21 +-
 .../Validator/ConjunctionValidatorTest.php    |  29 +-
 .../Validator/DateTimeValidatorTest.php       |  12 +-
 .../Validator/EmailAddressValidatorTest.php   |  17 +-
 .../Validator/FloatValidatorTest.php          |  14 +-
 .../Validator/IntegerValidatorTest.php        |  18 +-
 .../Validator/NotEmptyValidatorTest.php       |  33 +-
 .../Validator/NumberRangeValidatorTest.php    |  17 +-
 .../Validator/NumberValidatorTest.php         |   9 +-
 .../RegularExpressionValidatorTest.php        |  20 +-
 .../Validator/StringLengthValidatorTest.php   |  69 ++--
 .../Validator/StringValidatorTest.php         |  13 +-
 .../Validator/TextValidatorTest.php           |  12 +-
 .../Validation/Validator/UrlValidatorTest.php |   8 +-
 .../Validation/ValidatorResolverTest.php      |   9 +-
 .../Utility/LocalizationUtilityTest.php       |  14 +-
 .../FrontendUserGroupRepositoryTest.php       |   9 +-
 .../Repository/FrontendUserRepositoryTest.php |  29 +-
 .../Tca/ContentVisibleFieldsTest.php          |   5 +-
 .../Tca/FileMetadataVisibleFieldsTest.php     |   5 +-
 .../EscapeChildrenRenderingStandaloneTest.php |   8 +-
 .../EscapeChildrenRenderingTest.php           |   8 +-
 .../Functional/View/TemplatesPathsTest.php    |  26 +-
 .../ViewHelpers/Asset/CssViewHelperTest.php   |  18 +-
 .../Asset/ScriptViewHelperTest.php            |  12 +-
 .../ViewHelpers/Be/LinkViewHelperTest.php     |   9 +-
 .../Be/Menus/ActionMenuItemViewHelperTest.php |   8 +-
 .../IfAuthenticatedViewHelperTest.php         |   9 +-
 .../Be/Security/IfHasRoleViewHelperTest.php   |  13 +-
 .../ViewHelpers/Be/UriViewHelperTest.php      |   9 +-
 .../ViewHelpers/CObjectViewHelperTest.php     |  17 +-
 .../FlashMessagesViewHelperTest.php           |  13 +-
 .../ViewHelpers/Form/ButtonViewHelperTest.php |   9 +-
 .../Form/CheckboxViewHelperTest.php           |  48 +--
 .../Form/CountrySelectViewHelperTest.php      |  33 +-
 .../ViewHelpers/Form/HiddenViewHelperTest.php |   5 +-
 .../Form/PasswordViewHelperTest.php           |  13 +-
 .../ViewHelpers/Form/RadioViewHelperTest.php  |  40 +--
 .../Form/Select/OptionViewHelperTest.php      |  42 +--
 .../ViewHelpers/Form/SelectViewHelperTest.php |  93 ++----
 .../ViewHelpers/Form/SubmitViewHelperTest.php |   5 +-
 .../Form/TextareaViewHelperTest.php           |  12 +-
 .../Form/TextfieldViewHelperTest.php          |  12 +-
 .../ViewHelpers/Form/UploadViewHelperTest.php |  21 +-
 .../ViewHelpers/FormViewHelperTest.php        |  40 +--
 .../Format/BytesViewHelperTest.php            |   8 +-
 .../ViewHelpers/Format/CaseViewHelperTest.php |  12 +-
 .../ViewHelpers/Format/CropViewHelperTest.php |   8 +-
 .../Format/CurrencyViewHelperTest.php         |   8 +-
 .../ViewHelpers/Format/DateViewHelperTest.php |  74 ++---
 .../ViewHelpers/Format/HtmlViewHelperTest.php |  14 +-
 .../HtmlentitiesDecodeViewHelperTest.php      |  25 +-
 .../Format/HtmlentitiesViewHelperTest.php     |  37 +--
 .../Format/Nl2brViewHelperTest.php            |   8 +-
 .../Format/NumberViewHelperTest.php           |   8 +-
 .../Format/PaddingViewHelperTest.php          |  12 +-
 .../Format/StripTagsViewHelperTest.php        |  11 +-
 .../ViewHelpers/Format/TrimViewHelperTest.php |  12 +-
 .../Format/UrlencodeViewHelperTest.php        |  11 +-
 .../ViewHelpers/ImageViewHelperTest.php       |  24 +-
 .../ViewHelpers/Link/ActionViewHelperTest.php |  26 +-
 .../ViewHelpers/Link/EmailViewHelperTest.php  |  16 +-
 .../Link/ExternalViewHelperTest.php           |   8 +-
 .../ViewHelpers/Link/FileViewHelperTest.php   |  29 +-
 .../ViewHelpers/Link/PageViewHelperTest.php   |  50 +--
 .../Link/TypolinkViewHelperTest.php           |  14 +-
 .../ViewHelpers/MediaViewHelperTest.php       |   8 +-
 .../PageRendererViewHelperTest.php            |  12 +-
 .../Sanitize/HtmlViewHelperTest.php           |  18 +-
 .../IfAuthenticatedViewHelperTest.php         |   9 +-
 .../Security/IfHasRoleViewHelperTest.php      |   8 +-
 .../Transform/HtmlViewHelperTest.php          |  20 +-
 .../ViewHelpers/TranslateViewHelperTest.php   |  63 ++--
 .../ViewHelpers/Uri/ActionViewHelperTest.php  |  26 +-
 .../Uri/ExternalViewHelperTest.php            |   8 +-
 .../ViewHelpers/Uri/ImageViewHelperTest.php   |  20 +-
 .../ViewHelpers/Uri/PageViewHelperTest.php    |  50 +--
 .../Uri/ResourceViewHelperTest.php            |  22 +-
 .../Uri/TypolinkViewHelperTest.php            |   8 +-
 .../Functional/ViewhelperLibraryTest.php      |   4 +-
 .../Be/Labels/CshViewHelperTest.php           |   8 +-
 .../Rendering/SecureHtmlRenderingTest.php     |  19 +-
 .../Tca/ContentVisibleFieldsTest.php          |   5 +-
 .../Renderable/AbstractRenderableTest.php     |   5 +-
 .../Domain/Runtime/FormRuntimeTest.php        |   9 +-
 .../Mvc/Validation/CountValidatorTest.php     |  21 +-
 .../Mvc/Validation/DateRangeValidatorTest.php |  37 +--
 .../Mvc/Validation/EmptyValidatorTest.php     |  29 +-
 .../Mvc/Validation/FileSizeValidatorTest.php  |  25 +-
 .../Mvc/Validation/MimeTypeValidatorTest.php  |  32 +-
 .../RequestHandling/RequestHandlingTest.php   |  20 +-
 .../Service/TranslationServiceTest.php        | 153 +++------
 .../UploadedResourceViewHelperTest.php        |   5 +-
 .../FrontendUserAuthenticationTest.php        |   9 +-
 .../Cache/CacheLifetimeCalculatorTest.php     |   5 +-
 ...entObjectRendererGetDataPageLayoutTest.php |  25 +-
 .../ContentObjectRendererTest.php             |  67 ++--
 .../ContentObject/FilesContentObjectTest.php  |  32 +-
 .../FluidTemplateContentObjectTest.php        | 109 ++-----
 .../Controller/ShowImageControllerTest.php    |   6 +-
 .../TypoScriptFrontendControllerTest.php      |  38 +--
 .../Functional/Imaging/GifBuilderTest.php     |  20 +-
 .../BackendUserAuthenticatorTest.php          |   9 +-
 .../AbsoluteUriPrefixRenderingTest.php        |   8 +-
 .../LocalizedSiteContentRenderingTest.php     |  18 +-
 .../Rendering/TitleTagRenderingTest.php       |   8 +-
 .../Rendering/UriPrefixRenderingTest.php      |   8 +-
 .../InternalRequestDataMappingTest.php        |  36 ++-
 .../SiteHandling/EidRequestTest.php           |  14 +-
 .../DefaultExtbaseControllerTest.php          |  12 +-
 .../LocaleModifierTest.php                    |  14 +-
 .../PersistedAliasMapperTest.php              |  14 +-
 .../PersistedPatternMapperTest.php            |  14 +-
 .../EnhancerLinkGenerator/RouteTest.php       |  26 +-
 .../StaticRangeMapperTest.php                 |  14 +-
 .../StaticValueMapperTest.php                 |  14 +-
 .../LocaleModifierTest.php                    |  14 +-
 .../PageTypeDecoratorTest.php                 |  18 +-
 .../PersistedAliasMapperTest.php              |  20 +-
 .../PersistedPatternMapperTest.php            |  14 +-
 .../EnhancerSiteRequest/RouteTest.php         |  32 +-
 .../StaticRangeMapperTest.php                 |  14 +-
 .../StaticValueMapperTest.php                 |  14 +-
 .../LinkGeneratorFreeModeTest.php             |  14 +-
 .../LocalizedPageRendering/ScenarioATest.php  |  15 +-
 .../LocalizedPageRendering/ScenarioBTest.php  |  21 +-
 .../LocalizedPageRendering/ScenarioCTest.php  |  21 +-
 .../LocalizedPageRendering/ScenarioDTest.php  |  25 +-
 .../LocalizedPageRendering/ScenarioETest.php  |  21 +-
 .../LocalizedPageRendering/ScenarioFTest.php  |  21 +-
 .../LocalizedPageRendering/ScenarioGTest.php  |   9 +-
 .../SiteHandling/MountPointTest.php           |  19 +-
 .../SiteHandling/RequestHandlerTest.php       |   9 +-
 .../SiteHandling/SiteRequestTest.php          | 134 +++-----
 .../SiteHandling/SlugLinkGeneratorTest.php    |  95 ++----
 ...esolutionByQueryParametersDisabledTest.php |   8 +-
 ...ResolutionByQueryParametersEnabledTest.php |   8 +-
 .../SiteHandling/SlugSiteRequestTest.php      | 209 ++++--------
 ...lugSiteWithoutRequiredCHashRequestTest.php |  14 +-
 .../SiteHandling/TypoLinkGeneratorTest.php    |  38 +--
 .../Tca/BackendLayoutVisibleFieldsTest.php    |   5 +-
 .../Tca/ContentVisibleFieldsTest.php          |   5 +-
 .../Tca/FrontendGroupsVisibleFieldsTest.php   |   5 +-
 .../Tca/FrontendUsersVisibleFieldsTest.php    |   5 +-
 .../PagesLanguageOverlayVisibleFieldsTest.php |   8 +-
 .../Tca/TemplateVisibleFieldsTest.php         |   5 +-
 .../ConditionMatcherTest.php                  | 104 +++---
 .../Functional/Command/ExportCommandTest.php  |  13 +-
 .../Functional/Command/ImportCommandTest.php  |  23 +-
 .../Export/ExportPageTreeViewTest.php         |   8 +-
 .../Export/IrreTutorialRecordsTest.php        |   5 +-
 .../MultilingualPagesAndTtContentTest.php     |  13 +-
 .../Export/PagesAndTtContentTest.php          |   9 +-
 .../PagesAndTtContentWithImagesTest.php       |  17 +-
 ...dTtContentWithRelationsAndSoftrefsTest.php |  13 +-
 .../impexp/Tests/Functional/ExportTest.php    |  59 +---
 .../Import/ImagesWithStoragesTest.php         |   9 +-
 .../Import/IrreTutorialRecordsTest.php        |   5 +-
 .../Import/PagesAndTtContentTest.php          |   5 +-
 ...TtContentWithImagesInEmptyDatabaseTest.php |  37 +--
 ...tContentWithImagesInFilledDatabaseTest.php |  44 +--
 ...dTtContentWithRteImagesAndFileLinkTest.php |   5 +-
 .../Tests/Functional/ImportExportTest.php     |   5 +-
 .../impexp/Tests/Functional/ImportTest.php    |  59 ++--
 .../Utility/ImportExportUtilityTest.php       |  12 +-
 .../Functional/IndexSearchRepositoryTest.php  |  13 +-
 .../Tests/Functional/IndexerTest.php          |  13 +-
 .../Functional/Utility/LikeWildcardTest.php   |   8 +-
 .../Service/EnableFileServiceTest.php         |  21 +-
 .../SilentConfigurationUpgradeServiceTest.php |  78 ++---
 .../Service/Typo3tempFileServiceTest.php      |   9 +-
 .../WebServerConfigurationFileServiceTest.php |   7 +-
 ...ndGroupsExplicitAllowDenyMigrationTest.php |   5 +-
 .../BackendModulePermissionMigrationTest.php  |   5 +-
 .../FeLoginModeExtractionUpdateTest.php       |  12 +-
 .../MigrateSiteSettingsConfigUpdateTest.php   |   9 +-
 .../SysRedirectRootPageMoveMigrationTest.php  |  17 +-
 .../WorkspaceNewPlaceholderRemovalTest.php    |  13 +-
 .../Updates/ShortcutRecordsMigrationTest.php  |   5 +-
 ...sFileCollectionIdentifierMigrationTest.php |   5 +-
 .../SysFileMountIdentifierMigrationTest.php   |   5 +-
 .../Updates/SysLogSerializationUpdateTest.php |   5 +-
 .../UpgradeAnalysis/DocumentationFileTest.php |  26 +-
 .../Format/PhpErrorCodeViewHelperTest.php     |   8 +-
 .../CheckBrokenRteLinkEventListenerTest.php   |   8 +-
 .../Tests/Functional/LinkAnalyzerTest.php     |  32 +-
 .../Repository/BrokenLinkRepositoryTest.php   |  26 +-
 .../Repository/PagesRepositoryTest.php        |   9 +-
 .../Clean/CleanUpLocalProcessedFilesTest.php  |  21 +-
 .../GlobalVariableProviderTest.php            |   5 +-
 .../DatabaseIntegrityControllerTest.php       |  62 ++--
 .../Reaction/CreateRecordReactionTest.php     |  20 +-
 .../Tests/Functional/ReactionRegistryTest.php |   9 +-
 .../Repository/ReactionsRepositoryTest.php    |  16 +-
 .../Recycle/Pages/AdminRecycleTest.php        |   9 +-
 .../Recycle/Pages/UserRecycleTest.php         |  17 +-
 .../Task/CleanerFieldProviderTest.php         |  22 +-
 .../Tests/Functional/Task/CleanerTaskTest.php |  13 +-
 .../Controller/ManagementControllerTest.php   |   5 +-
 .../AddPageTypeZeroSourceTest.php             |  13 +-
 .../AddPlainSlugReplacementSourceTest.php     |   5 +-
 .../EventListener/IncrementHitCountTest.php   |   5 +-
 .../SlugRedirectChangeItemFactoryTest.php     |  21 +-
 .../Repository/RedirectRepositoryTest.php     |  14 +-
 .../Service/IntegrityServiceTest.php          |  16 +-
 .../Service/RedirectServiceTest.php           |  50 ++-
 .../Functional/Service/SlugServiceTest.php    |  31 +-
 .../Tests/Functional/WebhookExecutionTest.php |   5 +-
 .../Controller/BrowseLinksControllerTest.php  |   5 +-
 .../Tca/TaskGroupVisibleFieldsTest.php        |   5 +-
 .../Canonical/CanonicalGeneratorTest.php      |  12 +-
 .../HrefLang/HrefLangGeneratorTest.php        |   8 +-
 .../MetaTag/MetaTagGeneratorTest.php          |   6 +-
 .../Tests/Functional/MetaTag/MetaTagTest.php  |   8 +-
 .../XmlSitemap/XmlSitemapIndexTest.php        |   5 +-
 .../XmlSitemap/XmlSitemapPagesTest.php        |  37 +--
 ...itemapPagesWithHideIfNotTranslatedTest.php |  14 +-
 .../XmlSitemap/XmlSitemapRecordsTest.php      |  18 +-
 .../XmlSitemap/XmlSitemapXslTest.php          |   8 +-
 .../Functional/Tca/NoteVisibleFieldsTest.php  |   5 +-
 .../Tests/Functional/WebhookExecutionTest.php |  13 +-
 .../PageTreeItemsHighlighterTest.php          |   5 +-
 .../Functional/Hook/DataHandlerHookTest.php   |   9 +-
 .../Service/WorkspaceServiceTest.php          |  37 +--
 .../Tca/WorkspaceStageVisibleFieldsTest.php   |   5 +-
 .../Tca/WorkspaceVisibleFieldsTest.php        |   5 +-
 493 files changed, 4719 insertions(+), 11152 deletions(-)

diff --git a/Build/Scripts/annotationChecker.php b/Build/Scripts/annotationChecker.php
index e1c8d4810997..1cef01ac9ffe 100755
--- a/Build/Scripts/annotationChecker.php
+++ b/Build/Scripts/annotationChecker.php
@@ -54,7 +54,7 @@ class NodeVisitor extends NodeVisitorAbstract
                     // PHPDocumentor 2 tags
                     'api', 'author', 'category', 'copyright', 'deprecated', 'example', 'filesource', 'global', 'ignore', 'internal', 'license', 'link', 'method', 'package', 'param', 'property', 'property-read', 'property-write', 'return', 'see', 'since', 'source', 'subpackage', 'throws', 'todo', 'TODO', 'usedby', 'uses', 'var', 'version',
                     // PHPUnit tags
-                    'codeCoverageIgnore', 'codeCoverageIgnoreStart', 'codeCoverageIgnoreEnd', 'test', 'dataProvider', 'group', 'skip', 'depends', 'expectedException', 'before', 'requires',
+                    'codeCoverageIgnore', 'codeCoverageIgnoreStart', 'codeCoverageIgnoreEnd', 'dataProvider', 'group', 'skip', 'depends', 'expectedException', 'before', 'requires',
                     // codeception tags
                     'env',
                     // PHPCheckStyle
diff --git a/Build/Scripts/splitFunctionalTests.php b/Build/Scripts/splitFunctionalTests.php
index 4ff423785e95..cac63e15524e 100755
--- a/Build/Scripts/splitFunctionalTests.php
+++ b/Build/Scripts/splitFunctionalTests.php
@@ -15,7 +15,6 @@ declare(strict_types=1);
  * The TYPO3 project - inspiring people to share!
  */
 
-use PhpParser\Comment\Doc;
 use PhpParser\Node;
 use PhpParser\NodeTraverser;
 use PhpParser\NodeVisitor\NameResolver;
@@ -189,18 +188,16 @@ class FunctionalTestCaseVisitor extends NodeVisitorAbstract
     /**
      * @var array[] An array of arrays with test method names and optionally a data provider name
      */
-    private $tests = [];
+    private array $tests = [];
 
     /**
      * @var string Fully qualified test class name
      */
-    private $fqcn;
+    private string $fqcn;
 
     /**
      * Create a list of '@test' annotated methods in a test case
      * file and see if single tests use data providers.
-     *
-     * @param Node $node
      */
     public function enterNode(Node $node): void
     {
@@ -211,27 +208,27 @@ class FunctionalTestCaseVisitor extends NodeVisitorAbstract
             $this->fqcn = (string)$node->namespacedName;
         }
 
-        if ($node instanceof Node\Stmt\ClassMethod
-            && ($docComment = $node->getDocComment()) instanceof Doc
-        ) {
-            preg_match_all(
-                '/\s*\s@(?<annotations>[^\s.].*)\n/',
-                $docComment->getText(),
-                $matches
-            );
-            foreach ($matches['annotations'] as $possibleTest) {
-                if ($possibleTest === 'test') {
-                    // Found a test
-                    $test = [
-                        'methodName' => $node->name->name,
-                    ];
-                    foreach ($matches['annotations'] as $possibleDataProvider) {
-                        // See if this test has a data provider attached
-                        if (str_starts_with($possibleDataProvider, 'dataProvider')) {
-                            $test['dataProvider'] = trim(ltrim($possibleDataProvider, 'dataProvider'));
+        if ($node instanceof Node\Stmt\ClassMethod) {
+            foreach ($node->getAttrGroups() as $possibleTestAttributeGroup) {
+                foreach ($possibleTestAttributeGroup->attrs as $possibleTestAttribute) {
+                    // See if that method has the phpunit Test attribute attached.
+                    $name = $possibleTestAttribute->name->toCodeString();
+                    if ($name === '\\PHPUnit\\Framework\\Attributes\\Test') {
+                        $test = [
+                            'methodName' => $node->name->name,
+                        ];
+                        foreach ($node->getAttrGroups() as $possibleDataProviderAttributeGroup) {
+                            foreach ($possibleDataProviderAttributeGroup->attrs as $possibleDataProviderAttribute) {
+                                // See if that method has the phpunit DataProvider attribute attached, too.
+                                $name = $possibleDataProviderAttribute->name->toCodeString();
+                                if ($name === '\\PHPUnit\\Framework\\Attributes\\DataProvider') {
+                                    $dataProviderMethodName = $possibleDataProviderAttribute->args[0]->value->value;
+                                    $test['dataProvider'] = $dataProviderMethodName;
+                                }
+                            }
                         }
+                        $this->tests[] = $test;
                     }
-                    $this->tests[] = $test;
                 }
             }
         }
@@ -239,8 +236,6 @@ class FunctionalTestCaseVisitor extends NodeVisitorAbstract
 
     /**
      * Return array of found tests and their data providers
-     *
-     * @return array
      */
     public function getTests(): array
     {
@@ -249,8 +244,6 @@ class FunctionalTestCaseVisitor extends NodeVisitorAbstract
 
     /**
      * Return Fully qualified class test name
-     *
-     * @return string
      */
     public function getFqcn(): string
     {
diff --git a/Build/phpstan/phpstan-baseline.neon b/Build/phpstan/phpstan-baseline.neon
index 2a01820aa334..01e0c17f6576 100644
--- a/Build/phpstan/phpstan-baseline.neon
+++ b/Build/phpstan/phpstan-baseline.neon
@@ -1636,7 +1636,7 @@ parameters:
 			path: ../../typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/ObjectConverterTest.php
 
 		-
-			message: "#^Property class@anonymous/extbase/Tests/Functional/Property/TypeConverter/ObjectConverterTest\\.php\\:334\\:\\:\\$name is unused\\.$#"
+			message: "#^Property class@anonymous/extbase/Tests/Functional/Property/TypeConverter/ObjectConverterTest\\.php\\:313\\:\\:\\$name is unused\\.$#"
 			count: 1
 			path: ../../typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/ObjectConverterTest.php
 
diff --git a/typo3/sysext/backend/Tests/Functional/Authentication/PasswordResetTest.php b/typo3/sysext/backend/Tests/Functional/Authentication/PasswordResetTest.php
index 23fc0c251bd4..b77008be0fe7 100644
--- a/typo3/sysext/backend/Tests/Functional/Authentication/PasswordResetTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Authentication/PasswordResetTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Authentication;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Log\LoggerInterface;
 use Psr\Log\LoggerTrait;
 use TYPO3\CMS\Backend\Authentication\PasswordReset;
@@ -47,9 +48,7 @@ final class PasswordResetTest extends FunctionalTestCase
         };
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isNotEnabledWorks(): void
     {
         $subject = new PasswordReset();
@@ -60,9 +59,7 @@ final class PasswordResetTest extends FunctionalTestCase
         self::assertFalse($subject->isEnabled());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isNotEnabledWithNoUsers(): void
     {
         $subject = new PasswordReset();
@@ -74,9 +71,7 @@ final class PasswordResetTest extends FunctionalTestCase
         self::assertFalse($subject->isEnabled());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isEnabledExcludesAdministrators(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/be_users_only_admins.csv');
@@ -92,9 +87,7 @@ final class PasswordResetTest extends FunctionalTestCase
         self::assertTrue($subject->isEnabled());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isEnabledForUserTest(): void
     {
         $subject = new PasswordReset();
@@ -122,9 +115,7 @@ final class PasswordResetTest extends FunctionalTestCase
         self::assertTrue($subject->isEnabledForUser(1));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function noEmailIsFound(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/be_users.csv');
@@ -141,9 +132,7 @@ final class PasswordResetTest extends FunctionalTestCase
         $subject->initiateReset($request, $context, $emailAddress);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function ambiguousEmailIsTriggeredForMultipleValidUsers(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/be_users.csv');
@@ -160,9 +149,7 @@ final class PasswordResetTest extends FunctionalTestCase
         self::assertEquals($emailAddress, $this->logger->records[0]['context']['email']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function passwordResetEmailIsTriggeredForValidUser(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/be_users.csv');
@@ -184,9 +171,7 @@ final class PasswordResetTest extends FunctionalTestCase
         self::assertEquals($username, $this->logger->records[0]['context']['username']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function invalidTokenCannotResetPassword(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/be_users.csv');
diff --git a/typo3/sysext/backend/Tests/Functional/Backend/Shortcut/ShortcutRepositoryTest.php b/typo3/sysext/backend/Tests/Functional/Backend/Shortcut/ShortcutRepositoryTest.php
index caf18fb7a888..e0f9417552fb 100644
--- a/typo3/sysext/backend/Tests/Functional/Backend/Shortcut/ShortcutRepositoryTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Backend/Shortcut/ShortcutRepositoryTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Backend\Shortcut;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Backend\Shortcut\ShortcutRepository;
 use TYPO3\CMS\Backend\Module\ModuleProvider;
 use TYPO3\CMS\Backend\Routing\Router;
@@ -53,10 +55,8 @@ final class ShortcutRepositoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @dataProvider shortcutExistsTestDataProvider
-     * @test
-     */
+    #[DataProvider('shortcutExistsTestDataProvider')]
+    #[Test]
     public function shortcutExistsTest(string $routeIdentifier, array $arguments, int $userid, bool $exists): void
     {
         $GLOBALS['BE_USER']->user['uid'] = $userid;
@@ -91,9 +91,7 @@ final class ShortcutRepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addShortcutTest(): void
     {
         foreach ($this->getShortcutsToAdd() as $shortcut) {
@@ -130,9 +128,8 @@ final class ShortcutRepositoryTest extends FunctionalTestCase
 
     /**
      * This effectively also tests ShortcutRepository::initShortcuts()
-     *
-     * @test
      */
+    #[Test]
     public function getShortcutsByGroupTest(): void
     {
         $expected = [
diff --git a/typo3/sysext/backend/Tests/Functional/Clipboard/ClipboardTest.php b/typo3/sysext/backend/Tests/Functional/Clipboard/ClipboardTest.php
index 672ca79d9e17..7697818c6342 100644
--- a/typo3/sysext/backend/Tests/Functional/Clipboard/ClipboardTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Clipboard/ClipboardTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Clipboard;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Clipboard\Clipboard;
 use TYPO3\CMS\Backend\Routing\UriBuilder;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
@@ -142,10 +144,8 @@ final class ClipboardTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider localizationsAreResolvedDataProvider
-     * @test
-     */
+    #[DataProvider('localizationsAreResolvedDataProvider')]
+    #[Test]
     public function localizationsAreResolved(
         int $pageId,
         int $workspaceId,
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/BackendControllerTest.php b/typo3/sysext/backend/Tests/Functional/Controller/BackendControllerTest.php
index 9e3d0e5252b6..c762176c35f9 100644
--- a/typo3/sysext/backend/Tests/Functional/Controller/BackendControllerTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Controller/BackendControllerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Controller;
 
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Backend\Controller\BackendController;
 use TYPO3\CMS\Backend\Controller\Event\AfterBackendPageRenderEvent;
@@ -44,9 +45,7 @@ final class BackendControllerTest extends FunctionalTestCase
         Bootstrap::initializeLanguageObject();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function backendPageRenderEventIsTriggered(): void
     {
         /** @var Container $container */
@@ -78,9 +77,7 @@ final class BackendControllerTest extends FunctionalTestCase
         self::assertInstanceOf(AfterBackendPageRenderEvent::class, $state['after-backend-page-render-listener']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flashMessageIsDispatchedForForcedRedirect(): void
     {
         // Set workspace to disable the site configuration module
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/EditDocumentControllerTest.php b/typo3/sysext/backend/Tests/Functional/Controller/EditDocumentControllerTest.php
index 78566d5cb1ab..ab9eddc5eb27 100644
--- a/typo3/sysext/backend/Tests/Functional/Controller/EditDocumentControllerTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Controller/EditDocumentControllerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Controller;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Controller\EditDocumentController;
 use TYPO3\CMS\Backend\Routing\Route;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
@@ -50,9 +51,7 @@ final class EditDocumentControllerTest extends FunctionalTestCase
         $this->normalizedParams = new NormalizedParams([], [], '', '');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function processedDataTakesOverDefaultValues(): void
     {
         $request = (new ServerRequest('https://www.example.com/', 'POST'))
@@ -82,9 +81,7 @@ final class EditDocumentControllerTest extends FunctionalTestCase
         self::assertEquals(302, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function processedDataDoesNotOverridePostWithDefaultValues(): void
     {
         $request = (new ServerRequest('https://www.example.com/', 'POST'))
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/FormInlineAjaxControllerTest.php b/typo3/sysext/backend/Tests/Functional/Controller/FormInlineAjaxControllerTest.php
index bbc50e89f1b2..552718952be2 100644
--- a/typo3/sysext/backend/Tests/Functional/Controller/FormInlineAjaxControllerTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Controller/FormInlineAjaxControllerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Controller;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Controller\FormInlineAjaxController;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -67,9 +68,7 @@ final class FormInlineAjaxControllerTest extends FunctionalTestCase
         $this->subject = new FormInlineAjaxController();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createActionWithNewParentReturnsResponseForInlineChildData(): void
     {
         $parsedBody = [
@@ -89,9 +88,7 @@ final class FormInlineAjaxControllerTest extends FunctionalTestCase
         self::assertNotEmpty($jsonArray['data']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createActionWithExistingParentReturnsResponseForInlineChildData(): void
     {
         $parsedBody = [
@@ -111,9 +108,7 @@ final class FormInlineAjaxControllerTest extends FunctionalTestCase
         self::assertNotEmpty($jsonArray['data']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createActionWithExistingLocalizedParentReturnsResponseWithLocalizedChildData(): void
     {
         $parsedBody = [
@@ -133,9 +128,7 @@ final class FormInlineAjaxControllerTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/<option value="1"[^>]* selected="selected">Dansk<\/option>/', $jsonArray['data']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createActionWithExistingLocalizedParentAndNotLocalizableChildReturnsResponseWithChildData(): void
     {
         unset($GLOBALS['TCA']['tx_testirrecsv_offer']['ctrl']['languageField']);
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/MfaAjaxControllerTest.php b/typo3/sysext/backend/Tests/Functional/Controller/MfaAjaxControllerTest.php
index 38d51bb9e1fb..00795140e8ae 100644
--- a/typo3/sysext/backend/Tests/Functional/Controller/MfaAjaxControllerTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Controller/MfaAjaxControllerTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Controller;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\ResponseInterface;
 use TYPO3\CMS\Backend\Controller\MfaAjaxController;
 use TYPO3\CMS\Core\Authentication\Mfa\MfaProviderRegistry;
@@ -43,10 +45,8 @@ final class MfaAjaxControllerTest extends FunctionalTestCase
             ->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_BE);
     }
 
-    /**
-     * @test
-     * @dataProvider handleRequestHandlesInvalidRequestTestDataProvider
-     */
+    #[DataProvider('handleRequestHandlesInvalidRequestTestDataProvider')]
+    #[Test]
     public function handleRequestHandlesInvalidRequestTest(array $parsedBody): void
     {
         $response = $this->parseResponse($this->subject->handleRequest($this->request->withParsedBody($parsedBody)));
@@ -64,9 +64,7 @@ final class MfaAjaxControllerTest extends FunctionalTestCase
         yield 'Invalid table' => [['action' => 'deactivate', 'userId' => 5, 'tableName' => 'some_table']];
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestReturnsInvalidRequestOnInsufficientPermissionsTest(): void
     {
         // Make the target user a system maintainer. Since the current user (1)
@@ -87,10 +85,8 @@ final class MfaAjaxControllerTest extends FunctionalTestCase
         self::assertEquals('Your are not allowed to perform this action', $response['message']);
     }
 
-    /**
-     * @test
-     * @dataProvider handleRequestHandlesDeactivationRequestTestDataProvider
-     */
+    #[DataProvider('handleRequestHandlesDeactivationRequestTestDataProvider')]
+    #[Test]
     public function handleRequestHandlesDeactivationRequestTest(
         array $parsedBody,
         bool $success,
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/MfaConfigurationControllerTest.php b/typo3/sysext/backend/Tests/Functional/Controller/MfaConfigurationControllerTest.php
index ce38183d0f81..d56aa9465659 100644
--- a/typo3/sysext/backend/Tests/Functional/Controller/MfaConfigurationControllerTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Controller/MfaConfigurationControllerTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Controller;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Controller\MfaConfigurationController;
 use TYPO3\CMS\Backend\Routing\Route;
 use TYPO3\CMS\Backend\Routing\UriBuilder;
@@ -67,9 +69,7 @@ final class MfaConfigurationControllerTest extends FunctionalTestCase
         $this->normalizedParams = new NormalizedParams([], [], '', '');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestReturnsBadRequestForInvalidActionTest(): void
     {
         $queryParams = [
@@ -86,9 +86,7 @@ final class MfaConfigurationControllerTest extends FunctionalTestCase
         self::assertEquals('Action not allowed', $response->getBody()->getContents());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestFallsBackToOverviewActionIfNoActionGivenTest(): void
     {
         $request = $this->request->withAttribute('normalizedParams', $this->normalizedParams);
@@ -100,9 +98,7 @@ final class MfaConfigurationControllerTest extends FunctionalTestCase
         self::assertStringContainsString('Multi-factor Authentication Overview', $response->getBody()->getContents());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestShowsAllRegisteredProvidersTest(): void
     {
         $request = $this->request->withAttribute('normalizedParams', $this->normalizedParams);
@@ -118,9 +114,7 @@ final class MfaConfigurationControllerTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestAddsInformationAboutMfaBeingRequiredAndRecommendedTest(): void
     {
         $request = $this->request->withAttribute('normalizedParams', $this->normalizedParams);
@@ -134,9 +128,7 @@ final class MfaConfigurationControllerTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/<div.*class="card card-size-fixed-small card-success".*id="totp-provider"/s', $responseContent);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestIndicatesDefaultProviderTest(): void
     {
         $GLOBALS['BE_USER']->user['mfa'] = json_encode(['totp' => ['active' => true, 'secret' => 'KRMVATZTJFZUC53FONXW2ZJB']]);
@@ -151,9 +143,7 @@ final class MfaConfigurationControllerTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/<span.*title="Default provider">/s', $response->getBody()->getContents());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestRespectsReturnUrlTest(): void
     {
         $returnUrl = Environment::getPublicPath() . '/typo3/some/module?token=123';
@@ -174,10 +164,8 @@ final class MfaConfigurationControllerTest extends FunctionalTestCase
         self::assertStringContainsString('href="' . $returnUrl . '" class="btn btn-sm btn-default " title="Go back"', $response->getBody()->getContents());
     }
 
-    /**
-     * @test
-     * @dataProvider handleRequestRedirectsToOverviewOnActionProviderMismatchTestDataProvider
-     */
+    #[DataProvider('handleRequestRedirectsToOverviewOnActionProviderMismatchTestDataProvider')]
+    #[Test]
     public function handleRequestRedirectsToOverviewOnActionProviderMismatchTest(
         string $action,
         string $provider,
@@ -262,11 +250,8 @@ final class MfaConfigurationControllerTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider handleRequestForwardsToCorrectActionTestDataProvider
-     * @throws \TYPO3\CMS\Core\Context\Exception\AspectNotFoundException
-     */
+    #[DataProvider('handleRequestForwardsToCorrectActionTestDataProvider')]
+    #[Test]
     public function handleRequestForwardsToCorrectActionTest(
         string $action,
         string $provider,
@@ -364,10 +349,8 @@ final class MfaConfigurationControllerTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider handleRequestAddsFormOnInteractionViewsTestTestDataProvider
-     */
+    #[DataProvider('handleRequestAddsFormOnInteractionViewsTestTestDataProvider')]
+    #[Test]
     public function handleRequestAddsFormOnInteractionViewsTest(
         string $action,
         bool $providerActive,
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/MfaControllerTest.php b/typo3/sysext/backend/Tests/Functional/Controller/MfaControllerTest.php
index 6550e2e729f9..fad45f5ac88e 100644
--- a/typo3/sysext/backend/Tests/Functional/Controller/MfaControllerTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Controller/MfaControllerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Controller;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use TYPO3\CMS\Backend\Controller\MfaController;
 use TYPO3\CMS\Backend\Routing\Route;
@@ -77,9 +78,7 @@ final class MfaControllerTest extends FunctionalTestCase
             ->withAttribute('route', new Route('path', ['packageName' => 'typo3/cms-backend']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestThrowsExceptionOnInvalidActionTest(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -90,9 +89,7 @@ final class MfaControllerTest extends FunctionalTestCase
         $this->subject->handleRequest($request);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestThrowsExceptionOnMissingProviderTest(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -103,9 +100,7 @@ final class MfaControllerTest extends FunctionalTestCase
         $this->subject->handleRequest($request);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestThrowsExceptionOnInactiveProviderTest(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -121,9 +116,7 @@ final class MfaControllerTest extends FunctionalTestCase
         $this->subject->handleRequest($request);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestReturnsAuthViewTest(): void
     {
         $GLOBALS['BE_USER']->user['mfa'] = json_encode([
@@ -151,9 +144,7 @@ final class MfaControllerTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/<input.*id="totp"/s', $responseContent);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestReturnsLockedAuthViewTest(): void
     {
         $GLOBALS['BE_USER']->user['mfa'] = json_encode([
@@ -173,9 +164,7 @@ final class MfaControllerTest extends FunctionalTestCase
         self::assertStringContainsString('This provider is temporarily locked!', $response->getBody()->__toString());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestReturnsAlternativeProvidersInAuthViewTest(): void
     {
         $GLOBALS['BE_USER']->user['mfa'] = json_encode([
@@ -199,9 +188,7 @@ final class MfaControllerTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/<a.*title="Use Recovery codes"/s', $responseContent);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestRedirectsToLoginOnInvalidRequestTest(): void
     {
         $GLOBALS['BE_USER']->user['mfa'] = json_encode([
@@ -222,9 +209,7 @@ final class MfaControllerTest extends FunctionalTestCase
         self::assertEquals('/typo3/login', parse_url($response->getHeaderLine('location'))['path']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestRedirectsToLoginOnLockedProviderRequestTest(): void
     {
         $GLOBALS['BE_USER']->user['mfa'] = json_encode([
@@ -245,9 +230,7 @@ final class MfaControllerTest extends FunctionalTestCase
         self::assertEquals('/typo3/login', parse_url($response->getHeaderLine('location'))['path']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestRedirectsToAuthViewOnUnsuccessfulAuthenticationTest(): void
     {
         $GLOBALS['BE_USER']->user['mfa'] = json_encode([
@@ -268,9 +251,7 @@ final class MfaControllerTest extends FunctionalTestCase
         self::assertEquals('/typo3/auth/mfa', parse_url($response->getHeaderLine('location'))['path']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestSetsSessionKeyOnSuccessfulAuthenticationTest(): void
     {
         $GLOBALS['BE_USER']->user['mfa'] = json_encode([
@@ -304,9 +285,7 @@ final class MfaControllerTest extends FunctionalTestCase
         self::assertEquals('/typo3/login', parse_url($response->getHeaderLine('location'))['path']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestRedirectsToLoginOnCancelTest(): void
     {
         $request = $this->request->withQueryParams(['action' => 'cancel']);
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/MfaSetupControllerTest.php b/typo3/sysext/backend/Tests/Functional/Controller/MfaSetupControllerTest.php
index a56dbd8a78c7..b478b96af265 100644
--- a/typo3/sysext/backend/Tests/Functional/Controller/MfaSetupControllerTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Controller/MfaSetupControllerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Controller;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Log\NullLogger;
 use TYPO3\CMS\Backend\Controller\MfaSetupController;
 use TYPO3\CMS\Backend\Routing\Route;
@@ -77,9 +78,7 @@ final class MfaSetupControllerTest extends FunctionalTestCase
             ->withAttribute('route', new Route('path', ['packageName' => 'typo3/cms-backend']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestThrowsExceptionWhenMfaWasAlreadyPassed(): void
     {
         $GLOBALS['BE_USER']->setAndSaveSessionData('mfa', true);
@@ -92,9 +91,7 @@ final class MfaSetupControllerTest extends FunctionalTestCase
         $this->subject->handleRequest($request);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestThrowsExceptionWhenInSwitchUserMode(): void
     {
         $GLOBALS['BE_USER']->setAndSaveSessionData('backuserid', 123);
@@ -107,9 +104,7 @@ final class MfaSetupControllerTest extends FunctionalTestCase
         $this->subject->handleRequest($request);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestThrowsExceptionWhenMfaNotRequired(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['BE']['requireMfa'] = 0;
@@ -122,9 +117,7 @@ final class MfaSetupControllerTest extends FunctionalTestCase
         $this->subject->handleRequest($request);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestThrowsExceptionWhenMfaAlreadyActivated(): void
     {
         $GLOBALS['BE_USER']->user['mfa'] = json_encode(['totp' => ['active' => true, 'secret' => 'KRMVATZTJFZUC53FONXW2ZJB']]);
@@ -137,9 +130,7 @@ final class MfaSetupControllerTest extends FunctionalTestCase
         $this->subject->handleRequest($request);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestReturns404OnInvalidAction(): void
     {
         $request = $this->request->withQueryParams(['action' => 'unknown']);
@@ -149,9 +140,7 @@ final class MfaSetupControllerTest extends FunctionalTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestReturns404OnWrongHttpMethod(): void
     {
         $request = $this->request->withQueryParams(['action' => 'activate']);
@@ -161,9 +150,7 @@ final class MfaSetupControllerTest extends FunctionalTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestFallsBackToSelectionView(): void
     {
         $request = $this->request;
@@ -184,9 +171,7 @@ final class MfaSetupControllerTest extends FunctionalTestCase
         self::assertDoesNotMatchRegularExpression('/<a.*class="list-group-item.*title="Set up Recovery codes".*>/s', $responseContent);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestAddsRedirectParameters(): void
     {
         $queryParams = [
@@ -209,9 +194,7 @@ final class MfaSetupControllerTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/<a.*title="Cancel".*href="\/typo3\/setup\/mfa.*&amp;redirect=my_module&amp;redirectParams=some%3Dparam".*>/s', $responseContent);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestReturnsSetupView(): void
     {
         $queryParams = [
@@ -236,9 +219,7 @@ final class MfaSetupControllerTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/<input.*id="totp"/s', $responseContent);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestRedirectsToSetupOnMissingProvider(): void
     {
         $queryParams = [
@@ -259,9 +240,7 @@ final class MfaSetupControllerTest extends FunctionalTestCase
         self::assertStringContainsString('redirect=web_list&redirectParams=some%3Dparam', $redirectUrl['query']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestRedirectsToSetupOnInvalidProvider(): void
     {
         $queryParams = [
@@ -286,9 +265,7 @@ final class MfaSetupControllerTest extends FunctionalTestCase
         self::assertStringContainsString('redirect=web_list&redirectParams=some%3Dparam', $redirectUrl['query']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestActivatesRequestedProvider(): void
     {
         $queryParams = [
@@ -339,9 +316,7 @@ final class MfaSetupControllerTest extends FunctionalTestCase
         self::assertStringContainsString('redirect=web_list&redirectParams=some%3Dparam', $redirectUrl['query']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestRedirectsWithErrorOnActivationFailure(): void
     {
         $queryParams = [
@@ -373,9 +348,7 @@ final class MfaSetupControllerTest extends FunctionalTestCase
         self::assertStringContainsString('redirect=web_list&redirectParams=some%3Dparam', $redirectUrl['query']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleRequestCancelsSetup(): void
     {
         $queryParams = [
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/Page/LocalizationControllerTest.php b/typo3/sysext/backend/Tests/Functional/Controller/Page/LocalizationControllerTest.php
index 45c98cfe1c58..9ed57b4c238f 100644
--- a/typo3/sysext/backend/Tests/Functional/Controller/Page/LocalizationControllerTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Controller/Page/LocalizationControllerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Controller\Page;
 
+use PHPUnit\Framework\Attributes\Test;
 use PHPUnit\Framework\MockObject\MockObject;
 use TYPO3\CMS\Backend\Controller\Page\LocalizationController;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
@@ -48,10 +49,7 @@ final class LocalizationControllerTest extends AbstractDataHandlerActionTestCase
         $this->subject = $this->getAccessibleMock(LocalizationController::class, ['getPageColumns']);
     }
 
-    /**
-     * @test
-     * see DataSet/TranslatedFromDefault.csv
-     */
+    #[Test]
     public function recordsGetTranslatedFromDefaultLanguage(): void
     {
         $params = [
@@ -65,9 +63,7 @@ final class LocalizationControllerTest extends AbstractDataHandlerActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/Localization/CSV/DataSet/TranslatedFromDefault.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function recordsGetTranslatedFromDifferentTranslation(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/tt_content-danish-language.csv');
@@ -83,9 +79,7 @@ final class LocalizationControllerTest extends AbstractDataHandlerActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/Localization/CSV/DataSet/TranslatedFromTranslation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function recordsGetCopiedFromDefaultLanguage(): void
     {
         $params = [
@@ -99,9 +93,7 @@ final class LocalizationControllerTest extends AbstractDataHandlerActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/Localization/CSV/DataSet/CopiedFromDefault.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function recordsGetCopiedFromAnotherLanguage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/tt_content-danish-language.csv');
@@ -126,9 +118,8 @@ final class LocalizationControllerTest extends AbstractDataHandlerActionTestCase
      *   "[Translate to Dansk:] Test content 1", which is the previous record in the colpos.
      *
      * For detail about the sorting algorithm when translating records, see DataHandler->getPreviousLocalizedRecordUid
-     *
-     * @test
      */
+    #[Test]
     public function copyingNewContentFromLanguageIntoExistingLocalizationHasSameOrdering(): void
     {
         $params = [
@@ -169,9 +160,7 @@ final class LocalizationControllerTest extends AbstractDataHandlerActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/Localization/CSV/DataSet/CreatedElementOrdering.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function defaultLanguageIsFoundAsOriginLanguage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/tt_content-danish-language.csv');
@@ -200,9 +189,7 @@ final class LocalizationControllerTest extends AbstractDataHandlerActionTestCase
         $usedLanguages = (string)$this->subject->getUsedLanguagesInPage($request)->getBody();
         self::assertThat($usedLanguages, self::stringContains('"uid":0'));
     }
-    /**
-     * @test
-     */
+    #[Test]
     public function deletedDefaultLanguageItemIsHandledAsIfNoRecordsExistAndReturnsAllOriginLanguages(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/tt_content-default-language-deleted-element.csv');
@@ -217,9 +204,7 @@ final class LocalizationControllerTest extends AbstractDataHandlerActionTestCase
         self::assertThat($usedLanguages, self::stringContains('"uid":0'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function recordLocalizeSummaryRespectsWorkspaceEncapsulationForDeletedRecords(): void
     {
         // Delete record 2 within workspace 1
@@ -240,9 +225,7 @@ final class LocalizationControllerTest extends AbstractDataHandlerActionTestCase
         self::assertEquals($expectedRecords, $localizeSummary);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function recordLocalizeSummaryRespectsWorkspaceEncapsulationForMovedRecords(): void
     {
         // Move record 2 to page 2 within workspace 1
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/Page/TreeControllerTest.php b/typo3/sysext/backend/Tests/Functional/Controller/Page/TreeControllerTest.php
index 6505baab6165..64bafca25d34 100644
--- a/typo3/sysext/backend/Tests/Functional/Controller/Page/TreeControllerTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Controller/Page/TreeControllerTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Controller\Page;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use PHPUnit\Framework\MockObject\MockObject;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Backend\Controller\Event\AfterPageTreeItemsPreparedEvent;
@@ -84,9 +86,7 @@ final class TreeControllerTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getAllEntryPointPageTrees(): void
     {
         $actual = $this->subject->_call('getAllEntryPointPageTrees');
@@ -199,9 +199,7 @@ final class TreeControllerTest extends FunctionalTestCase
         self::assertEquals($expected, $actual);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getAllEntryPointPageTreesWithRootPageAsMountPoint(): void
     {
         $this->backendUser->setWebMounts([0, 7000]);
@@ -313,9 +311,7 @@ final class TreeControllerTest extends FunctionalTestCase
         self::assertEquals($expected, $actual);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getAllEntryPointPageTreesWithSearch(): void
     {
         $actual = $this->subject->_call('getAllEntryPointPageTrees', 0, 'Groups');
@@ -358,9 +354,7 @@ final class TreeControllerTest extends FunctionalTestCase
         self::assertEquals($expected, $actual);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getSubtreeForAccessiblePage(): void
     {
         $actual = $this->subject->_call('getAllEntryPointPageTrees', 1200);
@@ -391,9 +385,7 @@ final class TreeControllerTest extends FunctionalTestCase
         self::assertEquals($expected, $actual);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getSubtreeForNonAccessiblePage(): void
     {
         $actual = $this->subject->_call('getAllEntryPointPageTrees', 1510);
@@ -405,9 +397,7 @@ final class TreeControllerTest extends FunctionalTestCase
         self::assertEquals($expected, $actual);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getSubtreeForPageOutsideMountPoint(): void
     {
         $actual = $this->subject->_call('getAllEntryPointPageTrees', 7000);
@@ -419,9 +409,7 @@ final class TreeControllerTest extends FunctionalTestCase
         self::assertEquals($expected, $actual);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getAllEntryPointPageTreesWithMountPointPreservesOrdering(): void
     {
         $this->backendUser->setWebmounts([1210, 1100]);
@@ -453,9 +441,7 @@ final class TreeControllerTest extends FunctionalTestCase
         self::assertEquals($expected, $actual);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getAllEntryPointPageTreesInWorkspace(): void
     {
         $this->setWorkspace(1);
@@ -635,10 +621,8 @@ final class TreeControllerTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getAllEntryPointPageTreesInWorkspaceWithSearchDataProvider
-     */
+    #[DataProvider('getAllEntryPointPageTreesInWorkspaceWithSearchDataProvider')]
+    #[Test]
     public function getAllEntryPointPageTreesInWorkspaceWithSearch(string $search, array $expectedChildren): void
     {
         $this->setWorkspace(1);
@@ -670,9 +654,7 @@ final class TreeControllerTest extends FunctionalTestCase
         self::assertEquals($expected, $actual);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getSubtreeForAccessiblePageInWorkspace(): void
     {
         $this->setWorkspace(1);
@@ -709,9 +691,7 @@ final class TreeControllerTest extends FunctionalTestCase
         self::assertEquals($expected, $actual);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTreeItemsModificationEventIsTriggered(): void
     {
         Bootstrap::initializeLanguageObject();
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/ResetPasswordControllerTest.php b/typo3/sysext/backend/Tests/Functional/Controller/ResetPasswordControllerTest.php
index b982655ce3d9..30f302ad4829 100644
--- a/typo3/sysext/backend/Tests/Functional/Controller/ResetPasswordControllerTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Controller/ResetPasswordControllerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Controller;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\ServerRequestInterface;
 use TYPO3\CMS\Backend\Authentication\PasswordReset;
 use TYPO3\CMS\Backend\Controller\ResetPasswordController;
@@ -83,9 +84,7 @@ final class ResetPasswordControllerTest extends FunctionalTestCase
         $GLOBALS['LANG'] = GeneralUtility::makeInstance(LanguageServiceFactory::class)->create('default');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function throwsPropagateResponseExceptionOnLoggedInUser(): void
     {
         $backendUser = new BackendUserAuthentication();
@@ -98,9 +97,7 @@ final class ResetPasswordControllerTest extends FunctionalTestCase
         $this->subject->forgetPasswordFormAction($this->request);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function customStylingIsApplied(): void
     {
         $request = $this->request;
@@ -110,9 +107,7 @@ final class ResetPasswordControllerTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/\.btn-login { background-color: #abcdef; }.*\.card-login \.card-footer { border-color: #abcdef; }/s', $response);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function queryArgumentsAreKept(): void
     {
         $queryParams = [
@@ -131,9 +126,7 @@ final class ResetPasswordControllerTest extends FunctionalTestCase
         self::assertStringContainsString($expected, $this->subject->passwordResetAction($request)->getBody()->__toString());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function initiatePasswordResetPreventsTimeBasedInformationDisclosure(): void
     {
         $start = microtime(true);
@@ -143,9 +136,7 @@ final class ResetPasswordControllerTest extends FunctionalTestCase
         self::assertGreaterThan(0.2, microtime(true) - $start);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function initiatePasswordResetValidatesGivenEmailAddress(): void
     {
         $request = $this->request->withParsedBody(['email' => 'email..email@example.com']);
@@ -156,9 +147,7 @@ final class ResetPasswordControllerTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resetPasswordFormUrlContainsQueryParameters(): void
     {
         $queryParams = [
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/ShortcutControllerTest.php b/typo3/sysext/backend/Tests/Functional/Controller/ShortcutControllerTest.php
index 0eed175064a0..2a9f4da9b083 100644
--- a/typo3/sysext/backend/Tests/Functional/Controller/ShortcutControllerTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Controller/ShortcutControllerTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Controller;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Backend\Shortcut\ShortcutRepository;
 use TYPO3\CMS\Backend\Backend\ToolbarItems\ShortcutToolbarItem;
 use TYPO3\CMS\Backend\Controller\ShortcutController;
@@ -51,10 +53,8 @@ final class ShortcutControllerTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $this->request;
     }
 
-    /**
-     * @dataProvider addShortcutTestDataProvide
-     * @test
-     */
+    #[DataProvider('addShortcutTestDataProvide')]
+    #[Test]
     public function addShortcutTest(array $parsedBody, string $expectedResponseBody, int $expectedResponseStatus): void
     {
         $request = $this->request->withParsedBody($parsedBody);
diff --git a/typo3/sysext/backend/Tests/Functional/Domain/Repository/Localization/LocalizationRepositoryTest.php b/typo3/sysext/backend/Tests/Functional/Domain/Repository/Localization/LocalizationRepositoryTest.php
index ab5ebda26124..c0d112f9ef44 100644
--- a/typo3/sysext/backend/Tests/Functional/Domain/Repository/Localization/LocalizationRepositoryTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Domain/Repository/Localization/LocalizationRepositoryTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Domain\Repository\Localization;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Domain\Repository\Localization\LocalizationRepository;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -93,10 +95,8 @@ final class LocalizationRepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider fetchOriginLanguageDataProvider
-     * @test
-     */
+    #[DataProvider('fetchOriginLanguageDataProvider')]
+    #[Test]
     public function fetchOriginLanguage(int $pageId, int $localizedLanguage, array $expectedResult): void
     {
         $result = $this->subject->fetchOriginLanguage($pageId, $localizedLanguage);
@@ -144,10 +144,8 @@ final class LocalizationRepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider getLocalizedRecordCountDataProvider
-     * @test
-     */
+    #[DataProvider('getLocalizedRecordCountDataProvider')]
+    #[Test]
     public function getLocalizedRecordCount(int $pageId, int $localizedLanguage, int $expectedResult): void
     {
         $result = $this->subject->getLocalizedRecordCount($pageId, $localizedLanguage);
@@ -200,11 +198,8 @@ final class LocalizationRepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider getRecordsToCopyDatabaseResultDataProvider
-     * @test
-     * @throws \Doctrine\DBAL\Driver\Exception
-     */
+    #[DataProvider('getRecordsToCopyDatabaseResultDataProvider')]
+    #[Test]
     public function getRecordsToCopyDatabaseResult(int $pageId, int $destLanguageId, int $languageId, array $expectedResult): void
     {
         $result = $this->subject->getRecordsToCopyDatabaseResult($pageId, $destLanguageId, $languageId, 'uid');
diff --git a/typo3/sysext/backend/Tests/Functional/Form/Container/FilesControlContainerTest.php b/typo3/sysext/backend/Tests/Functional/Form/Container/FilesControlContainerTest.php
index 99e6ea36e5c2..1332d63648fe 100644
--- a/typo3/sysext/backend/Tests/Functional/Form/Container/FilesControlContainerTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Form/Container/FilesControlContainerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Form\Container;
 
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Backend\Form\Container\FilesControlContainer;
 use TYPO3\CMS\Backend\Form\Event\CustomFileControlsEvent;
@@ -39,9 +40,7 @@ final class FilesControlContainerTest extends FunctionalTestCase
         $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->create('default');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function customFileControlsEventIsCalled(): void
     {
         $customFileControlsEvent = null;
diff --git a/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaCategoryTest.php b/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaCategoryTest.php
index 34e786110c52..5213913eb4d0 100644
--- a/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaCategoryTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaCategoryTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Form\FormDataProvider\TcaCategory;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Site\Entity\Site;
@@ -33,9 +35,7 @@ final class TcaCategoryTest extends FunctionalTestCase
         Bootstrap::initializeLanguageObject();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataOnlyWorksForTypeCategory(): void
     {
         $input = [
@@ -63,9 +63,7 @@ final class TcaCategoryTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaCategory())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataChecksForTargetRenderType(): void
     {
         $input = [
@@ -94,9 +92,7 @@ final class TcaCategoryTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaCategory())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataInitializesDefaultFieldConfiguration(): void
     {
         $input = [
@@ -130,9 +126,7 @@ final class TcaCategoryTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaCategory())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataOverridesDefaultFieldConfigurationByTSconfig(): void
     {
         $input = [
@@ -220,10 +214,8 @@ final class TcaCategoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider addDataOverridesDefaultFieldConfigurationBySiteConfigDataProvider
-     * @test
-     */
+    #[DataProvider('addDataOverridesDefaultFieldConfigurationBySiteConfigDataProvider')]
+    #[Test]
     public function addDataOverridesDefaultFieldConfigurationBySiteConfig(string $inputStartingPoints, string $expectedStartingPoints, Site $site): void
     {
         $input = [
@@ -264,9 +256,7 @@ final class TcaCategoryTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaCategory())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataProcessesCategoryFieldValue(): void
     {
         $input = [
@@ -303,9 +293,7 @@ final class TcaCategoryTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaCategory())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataThorwsExceptionForStaticItems(): void
     {
         $input = [
@@ -341,9 +329,7 @@ final class TcaCategoryTest extends FunctionalTestCase
         (new TcaCategory())->addData($input);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataBuildsTreeForSingle(): void
     {
         $input = [
@@ -385,9 +371,7 @@ final class TcaCategoryTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaCategory())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataBuildsTreeForCsv(): void
     {
         $input = [
@@ -455,9 +439,7 @@ final class TcaCategoryTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaCategory())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataBuildsTreeForMM(): void
     {
         $input = [
diff --git a/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaGroupTest.php b/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaGroupTest.php
index bd4df2f78cb4..7a408fd1610c 100644
--- a/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaGroupTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaGroupTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Form\FormDataProvider\TcaGroup;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -37,9 +38,8 @@ final class TcaGroupTest extends FunctionalTestCase
 
     /**
      * This test checks if TcaGroup respects deleted elements
-     *
-     * @test
      */
+    #[Test]
     public function respectsDeletedElements()
     {
         $aFieldConfig = [
@@ -71,9 +71,8 @@ final class TcaGroupTest extends FunctionalTestCase
 
     /**
      * This test checks if TcaGroup respects deleted elements in a workspace
-     *
-     * @test
      */
+    #[Test]
     public function respectsDeletedElementsInWorkspace()
     {
         $aFieldConfig = [
diff --git a/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaSelectItemsTest.php b/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaSelectItemsTest.php
index f689176f75b5..77d1f63f247e 100644
--- a/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaSelectItemsTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaSelectItemsTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectItems;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Core\Environment;
@@ -50,9 +52,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataKeepExistingItems(): void
     {
         $input = [
@@ -89,9 +89,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertSame($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataThrowsExceptionIfAnItemIsNotAnArray(): void
     {
         $input = [
@@ -117,9 +115,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         (new TcaSelectItems())->addData($input);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataTranslatesItemLabels(): void
     {
         $input = [
@@ -157,9 +153,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertSame($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataAddsDividersIfItemGroupsAreDefined(): void
     {
         $input = [
@@ -231,9 +225,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertSame($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataKeepsIconFromItem(): void
     {
         $input = [
@@ -269,9 +261,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertSame($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataAddsFileItemsWithConfiguredFileFolder(): void
     {
         $directory = Environment::getVarPath() . '/' . StringUtility::getUniqueId('test-') . '/';
@@ -325,9 +315,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataAddsFileItemsWithOverwrittenFileFolder(): void
     {
         $directory = Environment::getVarPath() . '/' . StringUtility::getUniqueId('test-') . '/';
@@ -400,9 +388,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataThrowsExceptionForInvalidFileFolder(): void
     {
         $input = [
@@ -428,9 +414,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         (new TcaSelectItems())->addData($input);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataAddsItemsByAddItemsFromPageTsConfig(): void
     {
         $input = [
@@ -484,9 +468,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataAddsItemsByAddItemsWithGroupFromPageTsConfig(): void
     {
         $input = [
@@ -548,9 +530,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataAddsItemsByAddItemsWithDuplicateValuesFromPageTsConfig(): void
     {
         $input = [
@@ -1010,10 +990,8 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider addDataReplacesMarkersInForeignTableClauseDataProvider
-     */
+    #[DataProvider('addDataReplacesMarkersInForeignTableClauseDataProvider')]
+    #[Test]
     public function addDataReplacesMarkersInForeignTableClause(string $foreignTableWhere, array $expectedItems, array $inputOverride): void
     {
         $input = [
@@ -1063,9 +1041,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataThrowsExceptionIfForeignTableIsNotDefinedInTca(): void
     {
         $input = [
@@ -1089,9 +1065,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         (new TcaSelectItems())->addData($input);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataForeignTableSplitsGroupOrderAndLimit(): void
     {
         $input = [
@@ -1147,9 +1121,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataForeignTableQueuesFlashMessageOnDatabaseError(): void
     {
         $input = [
@@ -1195,9 +1167,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertCount(1, $flashMessageQueue->getAllMessages());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataForeignTableHandlesForeignTableRows(): void
     {
         $input = [
@@ -1241,9 +1211,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataRemovesItemsThatAreRestrictedByUserStorageAddedByForeignTable(): void
     {
         $input = [
@@ -1289,9 +1257,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataForeignTableResolvesIconFromSelicon(): void
     {
         $input = [
@@ -1343,9 +1309,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataRemovesItemsByKeepItemsPageTsConfig(): void
     {
         $input = [
@@ -1402,9 +1366,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataRemovesAllItemsByEmptyKeepItemsPageTsConfig(): void
     {
         $input = [
@@ -1453,9 +1415,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataEvaluatesKeepItemsBeforeAddItemsFromPageTsConfig(): void
     {
         $input = [
@@ -1530,9 +1490,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataRemovesItemsByRemoveItemsPageTsConfig(): void
     {
         $input = [
@@ -1589,9 +1547,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataRemovesItemsByZeroValueRemoveItemsPageTsConfig(): void
     {
         $input = [
@@ -1647,9 +1603,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataRemovesItemsAddedByAddItemsFromPageTsConfigByRemoveItemsPageTsConfig(): void
     {
         $input = [
@@ -1702,9 +1656,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataRemovesItemsByLanguageFieldUserRestriction(): void
     {
         $input = [
@@ -1790,9 +1742,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataKeepsAllPagesDoktypesForAdminUser(): void
     {
         $input = [
@@ -1832,9 +1782,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataKeepsAllowedPageTypesForNonAdminUser(): void
     {
         $input = [
@@ -1877,9 +1825,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataCallsItemsProcFunc(): void
     {
         $input = [
@@ -1945,9 +1891,8 @@ final class TcaSelectItemsTest extends FunctionalTestCase
      *
      * In the itemsProcFunc we will iterate over the items given from foreign_table and filter out every item that
      * does not have a uid of 2
-     *
-     * @test
      */
+    #[Test]
     public function addDataItemsProcFuncWillUseItemsFromForeignTable(): void
     {
         $input = [
@@ -2024,9 +1969,8 @@ final class TcaSelectItemsTest extends FunctionalTestCase
      * In the itemsProcFunc we will iterate over the items given from foreign_table and filter out every item that
      * does not have a uid lower than 3.
      * The pageTsConfig will remove the item with the uid=2 from the list so only one item with uid=1 will remain
-     *
-     * @test
      */
+    #[Test]
     public function addDataItemsProcFuncWillUseItemsFromForeignTableAndRemoveItemsByPageTsConfig(): void
     {
         $input = [
@@ -2112,9 +2056,8 @@ final class TcaSelectItemsTest extends FunctionalTestCase
      * In the itemsProcFunc we will iterate over the items given from foreign_table and filter out every item that
      * does not have the uid of 2.
      * The pageTsConfig will add an item with the uid=12 to the list so only one item with uid=1 will remain
-     *
-     * @test
      */
+    #[Test]
     public function addDataItemsProcFuncWillUseItemsFromForeignTableAndAddItemsByPageTsConfig(): void
     {
         $input = [
@@ -2203,9 +2146,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataItemsProcFuncReceivesParameters(): void
     {
         $input = [
@@ -2278,9 +2219,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertCount(0, $flashMessageQueue->getAllMessages());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataItemsProcFuncEnqueuesFlashMessageOnException(): void
     {
         $input = [
@@ -2337,9 +2276,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertCount(1, $flashMessageQueue->getAllMessages());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataTranslatesItemLabelsFromPageTsConfig(): void
     {
         $input = [
@@ -2387,9 +2324,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertSame($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataAddsIconsFromPageTsConfig(): void
     {
         $input = [
@@ -2437,9 +2372,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertSame($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function processSelectFieldValueSetsMmForeignRelationValues(): void
     {
         $input = [
@@ -2470,9 +2403,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertSame(['5', '6'], (new TcaSelectItems())->addData($input)['databaseRow']['mm_field']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function processSelectFieldValueSetsForeignRelationValues(): void
     {
         $input = [
@@ -2500,9 +2431,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertSame(['1', '2', '3', '4'], (new TcaSelectItems())->addData($input)['databaseRow']['foreign_field']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function processSelectFieldValueRemovesInvalidDynamicValues(): void
     {
         $input = [
@@ -2532,9 +2461,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertSame(['1', '2', 'foo'], (new TcaSelectItems())->addData($input)['databaseRow']['foreign_field']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function processSelectFieldValueKeepsValuesFromStaticItems(): void
     {
         $input = [
@@ -2568,9 +2495,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function processSelectFieldValueReturnsEmptyValueForSingleSelect(): void
     {
         $input = [
@@ -2598,9 +2523,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function processSelectFieldValueTrimsEmptyValueForMultiValueSelect(): void
     {
         $input = [
@@ -2635,9 +2558,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function processSelectFieldValueDoesNotCallRelationManagerForStaticOnlyItems(): void
     {
         $relationHandlerMock = $this->createMock(RelationHandler::class);
@@ -2672,9 +2593,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function processSelectFieldValueAddsInvalidValuesToItemsForSingleSelects(): void
     {
         $relationHandlerMock = $this->createMock(RelationHandler::class);
@@ -2714,9 +2633,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function processSelectFieldValueReturnsDuplicateValuesForMultipleSelect(): void
     {
         $input = [
@@ -2756,9 +2673,7 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function processSelectFieldValueReturnsUniqueValuesForMultipleSelect(): void
     {
         $input = [
@@ -2913,10 +2828,8 @@ final class TcaSelectItemsTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider processSelectFieldSetsCorrectValuesForMmRelationsDataProvider
-     */
+    #[DataProvider('processSelectFieldSetsCorrectValuesForMmRelationsDataProvider')]
+    #[Test]
     public function processSelectFieldSetsCorrectValuesForMmRelations(array $input, array $relationHandlerUids): void
     {
         self::assertEquals($relationHandlerUids, (new TcaSelectItems())->addData($input)['databaseRow']['mm_field']);
diff --git a/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaSelectTreeItemsTest.php b/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaSelectTreeItemsTest.php
index d891d7129cb2..441eddb0e245 100644
--- a/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaSelectTreeItemsTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Form/FormDataProvider/TcaSelectTreeItemsTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Form\FormDataProvider;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectTreeItems;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Site\Entity\Site;
@@ -40,9 +42,7 @@ final class TcaSelectTreeItemsTest extends FunctionalTestCase
         $GLOBALS['BE_USER'] = $this->setUpBackendUser(1);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataAddsTreeConfigurationForSelectTreeElement(): void
     {
         $input = [
@@ -130,9 +130,7 @@ final class TcaSelectTreeItemsTest extends FunctionalTestCase
         self::assertEquals($expected, (new TcaSelectTreeItems())->addData($input));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addDataHandsPageTsConfigSettingsOverToTableConfigurationTree(): void
     {
         $input = [
@@ -267,10 +265,8 @@ final class TcaSelectTreeItemsTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider addDataHandsSiteConfigurationOverToTableConfigurationTreeDataProvider
-     * @test
-     */
+    #[DataProvider('addDataHandsSiteConfigurationOverToTableConfigurationTreeDataProvider')]
+    #[Test]
     public function addDataHandsSiteConfigurationOverToTableConfigurationTree(string $inputStartingPoints, string $expectedStartingPoints, Site $site): void
     {
         $input = [
diff --git a/typo3/sysext/backend/Tests/Functional/Form/MfaInfoElementTest.php b/typo3/sysext/backend/Tests/Functional/Form/MfaInfoElementTest.php
index 9e3874e59935..ff335ff10920 100644
--- a/typo3/sysext/backend/Tests/Functional/Form/MfaInfoElementTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Form/MfaInfoElementTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Form;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Form\Element\MfaInfoElement;
 use TYPO3\CMS\Backend\Form\NodeFactory;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
@@ -42,9 +43,7 @@ final class MfaInfoElementTest extends FunctionalTestCase
         $GLOBALS['LANG'] = $languageServiceMock;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsEmptyResultOnInvalidTableTest(): void
     {
         $result = $this->getFormElementResult([
@@ -54,9 +53,7 @@ final class MfaInfoElementTest extends FunctionalTestCase
         self::assertEmpty($result['html']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsElementWithMfaDisabledTest(): void
     {
         $result = $this->getFormElementResult([
@@ -81,9 +78,7 @@ final class MfaInfoElementTest extends FunctionalTestCase
         self::assertEmpty($result['javaScriptModules']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsElementWithoutInvalidProviderTest(): void
     {
         $result = $this->getFormElementResult([
@@ -108,9 +103,7 @@ final class MfaInfoElementTest extends FunctionalTestCase
         self::assertEmpty($result['javaScriptModules']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsElementWithMfaActiveTest(): void
     {
         $result = $this->getFormElementResult([
@@ -144,9 +137,7 @@ final class MfaInfoElementTest extends FunctionalTestCase
         self::assertSame('@typo3/backend/form-engine/element/mfa-info-element.js', $result['javaScriptModules'][0]->getName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsElementWithMfaActiveAndLockedProvidersTest(): void
     {
         $result = $this->getFormElementResult([
@@ -180,9 +171,7 @@ final class MfaInfoElementTest extends FunctionalTestCase
         self::assertSame('@typo3/backend/form-engine/element/mfa-info-element.js', $result['javaScriptModules'][0]->getName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsElementWithoutDeactivationButtonsOnMissingPermissionsTest(): void
     {
         // Make the target user a system maintainer. Since the current user (1)
diff --git a/typo3/sysext/backend/Tests/Functional/History/RecordHistoryStoreTest.php b/typo3/sysext/backend/Tests/Functional/History/RecordHistoryStoreTest.php
index cb83a84c5665..83ecce6f83bf 100644
--- a/typo3/sysext/backend/Tests/Functional/History/RecordHistoryStoreTest.php
+++ b/typo3/sysext/backend/Tests/Functional/History/RecordHistoryStoreTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\History;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\DataHandling\History\RecordHistoryStore;
 use TYPO3\CMS\Core\DataHandling\Model\CorrelationId;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -34,9 +35,6 @@ final class RecordHistoryStoreTest extends FunctionalTestCase
         $this->subject = new RecordHistoryStore();
     }
 
-    /**
-     * @throws \Doctrine\DBAL\Driver\Exception
-     */
     protected function getRecordCountByCorrelationId(CorrelationId $correlationId): int
     {
         $queryBuilder = $this->getConnectionPool()->getQueryBuilderForTable('sys_history');
@@ -48,9 +46,7 @@ final class RecordHistoryStoreTest extends FunctionalTestCase
             ->fetchOne();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addRecordAddsARecordToTheDatabase(): void
     {
         $correlationId = CorrelationId::forSubject('092a640c-bd8c-490d-b993-ed4bcef1a1f2');
@@ -59,9 +55,7 @@ final class RecordHistoryStoreTest extends FunctionalTestCase
         self::assertSame(1, $this->getRecordCountByCorrelationId($correlationId));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyRecordAddsARecordToTheDatabase(): void
     {
         $correlationId = CorrelationId::forSubject('058f117c-5e21-4222-b308-085fc1113604');
@@ -70,9 +64,7 @@ final class RecordHistoryStoreTest extends FunctionalTestCase
         self::assertSame(1, $this->getRecordCountByCorrelationId($correlationId));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteRecordAddsARecordToTheDatabase(): void
     {
         $correlationId = CorrelationId::forSubject('e1a2ea91-fe2f-4a01-b50b-5c2924a27568');
@@ -81,9 +73,7 @@ final class RecordHistoryStoreTest extends FunctionalTestCase
         self::assertSame(1, $this->getRecordCountByCorrelationId($correlationId));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function undeleteRecordAddsARecordToTheDatabase(): void
     {
         $correlationId = CorrelationId::forSubject('ab902256-56f2-43bd-b857-f7a0b974e9db');
@@ -92,9 +82,7 @@ final class RecordHistoryStoreTest extends FunctionalTestCase
         self::assertSame(1, $this->getRecordCountByCorrelationId($correlationId));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveRecordAddsARecordToTheDatabase(): void
     {
         $correlationId = CorrelationId::forSubject('9d806d3a-1d7a-4e62-816f-9fa1a1b3fe5b');
diff --git a/typo3/sysext/backend/Tests/Functional/History/RecordHistoryTest.php b/typo3/sysext/backend/Tests/Functional/History/RecordHistoryTest.php
index 1b08c807d906..c07a1dcab94f 100644
--- a/typo3/sysext/backend/Tests/Functional/History/RecordHistoryTest.php
+++ b/typo3/sysext/backend/Tests/Functional/History/RecordHistoryTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\History;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\History\RecordHistory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -42,10 +44,8 @@ final class RecordHistoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider findEventsForCorrelationWorksAsExpectedDataProvider
-     */
+    #[DataProvider('findEventsForCorrelationWorksAsExpectedDataProvider')]
+    #[Test]
     public function findEventsForCorrelationWorksAsExpected(string $correlationId, int $amountOfEntries): void
     {
         self::assertCount($amountOfEntries, $this->subject->findEventsForCorrelation($correlationId));
diff --git a/typo3/sysext/backend/Tests/Functional/Middleware/BackendModuleValidatorTest.php b/typo3/sysext/backend/Tests/Functional/Middleware/BackendModuleValidatorTest.php
index 1ec5aa66da36..e567e8482b44 100644
--- a/typo3/sysext/backend/Tests/Functional/Middleware/BackendModuleValidatorTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Middleware/BackendModuleValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Middleware;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 use Psr\Http\Server\RequestHandlerInterface;
@@ -69,9 +70,7 @@ final class BackendModuleValidatorTest extends FunctionalTestCase
         };
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moduleIsAddedToRequest(): void
     {
         $module = $this->get(ModuleFactory::class)->createModule(
@@ -92,9 +91,7 @@ final class BackendModuleValidatorTest extends FunctionalTestCase
         self::assertEquals('web_layout', $response->getHeaderLine('X-Module-identifier'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moduleDataIsAddedToRequest(): void
     {
         $module = $this->get(ModuleFactory::class)->createModule(
@@ -125,9 +122,7 @@ final class BackendModuleValidatorTest extends FunctionalTestCase
         self::assertEquals('1', $response->getHeader('X-ModuleData-reverse')[0]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function invalidModuleIsHandledWithRedirect(): void
     {
         $module = $this->get(ModuleFactory::class)->createModule(
@@ -150,9 +145,7 @@ final class BackendModuleValidatorTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flashMessageIsDispatchedForForcedRedirect(): void
     {
         $module = $this->get(ModuleFactory::class)->createModule(
@@ -177,9 +170,7 @@ final class BackendModuleValidatorTest extends FunctionalTestCase
         self::assertEquals(ContextualFeedbackSeverity::INFO, $flashMessage->getSeverity());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function invalidModuleThrowsException(): void
     {
         $GLOBALS['BE_USER']->user['admin'] = 0;
@@ -202,9 +193,7 @@ final class BackendModuleValidatorTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function noPageAccessThrowsException(): void
     {
         $module = $this->get(ModuleFactory::class)->createModule(
@@ -226,9 +215,7 @@ final class BackendModuleValidatorTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function redirectsToMainForSecFetchDestHeader(): void
     {
         $module = $this->get(ModuleFactory::class)->createModule(
diff --git a/typo3/sysext/backend/Tests/Functional/Middleware/SiteResolverTest.php b/typo3/sysext/backend/Tests/Functional/Middleware/SiteResolverTest.php
index 9fb0d33228ab..c3474fa5b86d 100644
--- a/typo3/sysext/backend/Tests/Functional/Middleware/SiteResolverTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Middleware/SiteResolverTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Middleware;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 use Psr\Http\Server\RequestHandlerInterface;
@@ -28,9 +29,7 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class SiteResolverTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function requestHasNullSiteAttributeIfIdParameterIsNoInteger(): void
     {
         $this->expectException(\RuntimeException::class);
diff --git a/typo3/sysext/backend/Tests/Functional/Module/ModuleDataTest.php b/typo3/sysext/backend/Tests/Functional/Module/ModuleDataTest.php
index 9157dc997206..a3ce32bcbfec 100644
--- a/typo3/sysext/backend/Tests/Functional/Module/ModuleDataTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Module/ModuleDataTest.php
@@ -17,15 +17,15 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Module;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Module\ModuleData;
 use TYPO3\CMS\Backend\Module\ModuleFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class ModuleDataTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function defaultValuesAreOverwritten(): void
     {
         $defaultValues = [
@@ -53,9 +53,7 @@ final class ModuleDataTest extends FunctionalTestCase
         self::assertEquals('anotherPropertyValue', $moduleData->toArray()['anotherProperty']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moduleDataAreCreatedFromModule(): void
     {
         $defaultValues = [
@@ -86,9 +84,7 @@ final class ModuleDataTest extends FunctionalTestCase
         self::assertEquals('anotherPropertyValue', $moduleData->toArray()['anotherProperty']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function cleanModuleDataPropertyThrowsExceptionOnInvalidProperty(): void
     {
         $moduleData = new ModuleData(
@@ -107,9 +103,7 @@ final class ModuleDataTest extends FunctionalTestCase
         $moduleData->clean('invalidProperty', ['allowedValue']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function cleanModuleDataPropertyThrowsExceptionOnEmptyAllowedList(): void
     {
         $moduleData = new ModuleData(
@@ -147,10 +141,8 @@ final class ModuleDataTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider cleanModuleDataPropertyDataProvider
-     */
+    #[DataProvider('cleanModuleDataPropertyDataProvider')]
+    #[Test]
     public function cleanModuleDataProperty(array $allowedValues, bool $cleaned, string $cleanedValue): void
     {
         $moduleData = new ModuleData(
@@ -217,10 +209,8 @@ final class ModuleDataTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider cleanUpModuleDataPropertiesDataProvider
-     */
+    #[DataProvider('cleanUpModuleDataPropertiesDataProvider')]
+    #[Test]
     public function cleanUpModuleDataProperties(
         array $allowedData,
         bool $useKeys,
diff --git a/typo3/sysext/backend/Tests/Functional/Module/ModuleProviderTest.php b/typo3/sysext/backend/Tests/Functional/Module/ModuleProviderTest.php
index 7e0f9a6bbd51..6941d5e80150 100644
--- a/typo3/sysext/backend/Tests/Functional/Module/ModuleProviderTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Module/ModuleProviderTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Module;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Module\ModuleFactory;
 use TYPO3\CMS\Backend\Module\ModuleProvider;
 use TYPO3\CMS\Backend\Module\ModuleRegistry;
@@ -27,9 +28,7 @@ final class ModuleProviderTest extends FunctionalTestCase
 {
     protected array $coreExtensionsToLoad = ['workspaces'];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function workspaceAccessIsInherited(): void
     {
         $parentModule = $this->get(ModuleFactory::class)->createModule(
diff --git a/typo3/sysext/backend/Tests/Functional/RecordList/DownloadRecordListTest.php b/typo3/sysext/backend/Tests/Functional/RecordList/DownloadRecordListTest.php
index 0975e70027cd..a32ccb5cb960 100644
--- a/typo3/sysext/backend/Tests/Functional/RecordList/DownloadRecordListTest.php
+++ b/typo3/sysext/backend/Tests/Functional/RecordList/DownloadRecordListTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\RecordList;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider;
 use TYPO3\CMS\Backend\RecordList\DatabaseRecordList;
 use TYPO3\CMS\Backend\RecordList\DownloadRecordList;
@@ -37,9 +38,7 @@ final class DownloadRecordListTest extends FunctionalTestCase
         $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->createFromUserPreferences($this->user);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function downloadReturnsAListOfAllBackendUsers(): void
     {
         $recordList = $this->get(DatabaseRecordList::class);
@@ -74,9 +73,7 @@ final class DownloadRecordListTest extends FunctionalTestCase
         ], $this->prepareRecordsForDbCompatAssertions($result));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function downloadReturnsAListOfSubpages(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/pages_download_record_list.csv');
@@ -165,9 +162,7 @@ final class DownloadRecordListTest extends FunctionalTestCase
         ], $this->prepareRecordsForDbCompatAssertions($result));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function downloadReturnsRawValues(): void
     {
         $recordList = $this->get(DatabaseRecordList::class);
diff --git a/typo3/sysext/backend/Tests/Functional/Routing/RouterTest.php b/typo3/sysext/backend/Tests/Functional/Routing/RouterTest.php
index 189b562f646e..cb8ae0a6dc55 100644
--- a/typo3/sysext/backend/Tests/Functional/Routing/RouterTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Routing/RouterTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Routing;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Module\ModuleInterface;
 use TYPO3\CMS\Backend\Routing\Exception\MethodNotAllowedException;
 use TYPO3\CMS\Backend\Routing\Exception\ResourceNotFoundException;
@@ -31,9 +32,7 @@ final class RouterTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function routerReturnsRouteForAlias(): void
     {
         $subject = $this->get(Router::class);
@@ -46,9 +45,7 @@ final class RouterTest extends FunctionalTestCase
         self::assertTrue($subject->hasRoute('old_route_identifier'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function matchResultFindsProperRoute(): void
     {
         $subject = $this->get(Router::class);
@@ -58,9 +55,7 @@ final class RouterTest extends FunctionalTestCase
         self::assertEquals('/login', $result->getRoute()->getPath());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function matchResultThrowsExceptionOnInvalidRoute(): void
     {
         $subject = $this->get(Router::class);
@@ -70,9 +65,7 @@ final class RouterTest extends FunctionalTestCase
         $subject->matchResult($request);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function matchResultThrowsInvalidMethodForValidRoute(): void
     {
         $subject = $this->get(Router::class);
@@ -82,9 +75,7 @@ final class RouterTest extends FunctionalTestCase
         $subject->matchResult($request);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function matchResultReturnsRouteWithMethodLimitation(): void
     {
         $subject = $this->get(Router::class);
@@ -94,9 +85,7 @@ final class RouterTest extends FunctionalTestCase
         self::assertEquals('/login/password-reset/initiate-reset', $result->getRoute()->getPath());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function matchResultReturnsRouteForBackendModuleWithMethodLimitation(): void
     {
         $subject = $this->get(Router::class);
@@ -107,9 +96,7 @@ final class RouterTest extends FunctionalTestCase
         self::assertInstanceOf(ModuleInterface::class, $result->getRoute()->getOption('module'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function matchResultThrowsExceptionForWrongHttpMethod(): void
     {
         $this->expectException(MethodNotAllowedException::class);
@@ -121,9 +108,7 @@ final class RouterTest extends FunctionalTestCase
         $subject->matchResult($request);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function matchResultReturnsRouteWithPlaceholderAndMethodLimitation(): void
     {
         $subject = $this->get(Router::class);
@@ -135,9 +120,7 @@ final class RouterTest extends FunctionalTestCase
         self::assertEquals(['identifier' => 'my-identifier'], $result->getArguments());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function matchResultReturnsRouteForSubRoute(): void
     {
         $subject = $this->get(Router::class);
diff --git a/typo3/sysext/backend/Tests/Functional/Routing/UriBuilderTest.php b/typo3/sysext/backend/Tests/Functional/Routing/UriBuilderTest.php
index 30e77f118dca..b2516b6369a7 100644
--- a/typo3/sysext/backend/Tests/Functional/Routing/UriBuilderTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Routing/UriBuilderTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Routing;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Routing\UriBuilder;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -27,9 +28,7 @@ final class UriBuilderTest extends FunctionalTestCase
 
     protected array $coreExtensionsToLoad = ['workspaces'];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function buildUriFromRouteResolvesAliasWhenLinking(): void
     {
         $subject = GeneralUtility::makeInstance(UriBuilder::class);
@@ -38,9 +37,7 @@ final class UriBuilderTest extends FunctionalTestCase
         self::assertEquals($routeFromAlias->getPath(), $route->getPath());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function buildUriFromRouteResolvesSubModule(): void
     {
         $subject = GeneralUtility::makeInstance(UriBuilder::class);
diff --git a/typo3/sysext/backend/Tests/Functional/SiteConfiguration/SiteConfigurationOverridesTest.php b/typo3/sysext/backend/Tests/Functional/SiteConfiguration/SiteConfigurationOverridesTest.php
index 29e708e5824a..30344f2e45ed 100644
--- a/typo3/sysext/backend/Tests/Functional/SiteConfiguration/SiteConfigurationOverridesTest.php
+++ b/typo3/sysext/backend/Tests/Functional/SiteConfiguration/SiteConfigurationOverridesTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\SiteConfiguration;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Configuration\SiteTcaConfiguration;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -41,9 +42,7 @@ final class SiteConfigurationOverridesTest extends FunctionalTestCase
         $this->subject = (new SiteTcaConfiguration())->getTca();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function allOverridesLoaded(): void
     {
         $columnsConfiguration = $this->subject['site']['columns'];
@@ -52,9 +51,7 @@ final class SiteConfigurationOverridesTest extends FunctionalTestCase
         self::assertArrayHasKey('tx_b_a', $columnsConfiguration);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function overrideOnlyLoadedOnce(): void
     {
         $showitemConfiguration = $this->subject['site']['types']['0']['showitem'];
@@ -63,9 +60,7 @@ final class SiteConfigurationOverridesTest extends FunctionalTestCase
         self::assertSame(1, mb_substr_count($showitemConfiguration, 'tx_b_a'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function finderUsesCorrectOrder(): void
     {
         $columnsConfiguration = $this->subject['site']['columns'];
diff --git a/typo3/sysext/backend/Tests/Functional/Template/Components/Buttons/Action/ShortcutButtonTest.php b/typo3/sysext/backend/Tests/Functional/Template/Components/Buttons/Action/ShortcutButtonTest.php
index 8fad85d9af34..801307819d42 100644
--- a/typo3/sysext/backend/Tests/Functional/Template/Components/Buttons/Action/ShortcutButtonTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Template/Components/Buttons/Action/ShortcutButtonTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Template\Components\Buttons\Action;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Template\Components\Buttons\Action\ShortcutButton;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
@@ -28,9 +30,7 @@ final class ShortcutButtonTest extends FunctionalTestCase
 {
     private const FIXTURES_PATH_PATTERN = __DIR__ . '/../../../Fixtures/%s.html';
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isButtonValid(): void
     {
         self::assertFalse((new ShortcutButton())->isValid());
@@ -39,9 +39,7 @@ final class ShortcutButtonTest extends FunctionalTestCase
         self::assertTrue((new ShortcutButton())->setRouteIdentifier('web_list')->setDisplayName('Some module anme')->isValid());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function buttonIsNotRenderedForUserWithInsufficientPermissions(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] = 'options.enableBookmarks=0';
@@ -54,10 +52,8 @@ final class ShortcutButtonTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @dataProvider rendersCorrectMarkupDataProvider
-     * @test
-     */
+    #[DataProvider('rendersCorrectMarkupDataProvider')]
+    #[Test]
     public function rendersCorrectMarkup(ShortcutButton $button, string $expectedMarkupFile): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../../../Fixtures/be_users.csv');
diff --git a/typo3/sysext/backend/Tests/Functional/Tree/Repository/PageTreeRepositoryTest.php b/typo3/sysext/backend/Tests/Functional/Tree/Repository/PageTreeRepositoryTest.php
index 94705bec5ad6..8f8413262bf7 100644
--- a/typo3/sysext/backend/Tests/Functional/Tree/Repository/PageTreeRepositoryTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Tree/Repository/PageTreeRepositoryTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\Tree\Repository;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Tree\Repository\Fixtures\Tree\NormalizeTreeTrait;
 use TYPO3\CMS\Backend\Tree\Repository\PageTreeRepository;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -224,10 +226,8 @@ final class PageTreeRepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider getTreeLevelsReturnsGroupedAndSortedPageTreeArrayDataProvider
-     * @test
-     */
+    #[DataProvider('getTreeLevelsReturnsGroupedAndSortedPageTreeArrayDataProvider')]
+    #[Test]
     public function getTreeLevelsReturnsGroupedAndSortedPageTreeArray(array $pageTree, int $depth, array $entryPointIds, array $expected): void
     {
         $pageTreeRepository = new PageTreeRepository();
@@ -308,10 +308,8 @@ final class PageTreeRepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider fetchFilteredTreeDataProvider
-     */
+    #[DataProvider('fetchFilteredTreeDataProvider')]
+    #[Test]
     public function fetchFilteredTreeShowsResults(string $search, int $workspaceId, int $entryPoint, array $expectedResult): void
     {
         $pageTreeRepository = new PageTreeRepository($workspaceId);
diff --git a/typo3/sysext/backend/Tests/Functional/Utility/BackendUtilityTest.php b/typo3/sysext/backend/Tests/Functional/Utility/BackendUtilityTest.php
index 3c12abd42dbb..f64ccea36645 100644
--- a/typo3/sysext/backend/Tests/Functional/Utility/BackendUtilityTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Utility/BackendUtilityTest.php
@@ -19,6 +19,8 @@ namespace TYPO3\CMS\Backend\Tests\Functional\Utility;
 
 use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
 use Doctrine\DBAL\Platforms\SqlitePlatform;
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Core\Bootstrap;
@@ -49,9 +51,7 @@ final class BackendUtilityTest extends FunctionalTestCase
         Bootstrap::initializeLanguageObject();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function givenPageIdCanBeExpanded(): void
     {
         $this->backendUser->groupData['webmounts'] = '1';
@@ -67,9 +67,7 @@ final class BackendUtilityTest extends FunctionalTestCase
         self::assertSame($expectedSiteHash, $actualSiteHash);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function otherBranchesCanBeClosedWhenOpeningPage(): void
     {
         $this->backendUser->groupData['webmounts'] = '1';
@@ -89,9 +87,7 @@ final class BackendUtilityTest extends FunctionalTestCase
         self::assertSame($expectedSiteHash, $actualSiteHash);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getProcessedValueForLanguage(): void
     {
         $this->writeSiteConfiguration(
@@ -131,9 +127,7 @@ final class BackendUtilityTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getRecordTitleForUidLabel(): void
     {
         $GLOBALS['TCA']['tt_content']['ctrl']['label'] = 'uid';
@@ -213,10 +207,8 @@ final class BackendUtilityTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider enableFieldsStatementIsCorrectDataProvider
-     */
+    #[DataProvider('enableFieldsStatementIsCorrectDataProvider')]
+    #[Test]
     public function enableFieldsStatementIsCorrect(array $enableColumns, bool $inverted, string $expectation): void
     {
         $platform = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME)->getDatabasePlatform();
diff --git a/typo3/sysext/backend/Tests/Functional/View/BackendViewFactoryTest.php b/typo3/sysext/backend/Tests/Functional/View/BackendViewFactoryTest.php
index 5ed95837c38e..5a970c86182c 100644
--- a/typo3/sysext/backend/Tests/Functional/View/BackendViewFactoryTest.php
+++ b/typo3/sysext/backend/Tests/Functional/View/BackendViewFactoryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\View;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Routing\Route;
 use TYPO3\CMS\Backend\View\BackendViewFactory;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -30,9 +31,7 @@ final class BackendViewFactoryTest extends FunctionalTestCase
         'typo3/sysext/backend/Tests/Functional/View/Fixtures/Extensions/test_templates_c',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createUsesTemplatePathsWithPackageGivenAsRouteOption()
     {
         $request = (new ServerRequest())->withAttribute('route', new Route('testing', ['packageName' => 'typo3tests/cms-test-templates-a']));
@@ -44,9 +43,7 @@ final class BackendViewFactoryTest extends FunctionalTestCase
         self::assertStringContainsString('Foo partial from extension test_templates_a', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createUsesTemplatePathsWithPackageGivenAsArgument()
     {
         $request = (new ServerRequest())->withAttribute('route', new Route('testing', []));
@@ -58,9 +55,7 @@ final class BackendViewFactoryTest extends FunctionalTestCase
         self::assertStringContainsString('Foo partial from extension test_templates_a', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createUsesOverrideTemplatePathsWithBasePackageNameFromRoute()
     {
         $request = (new ServerRequest())->withAttribute('route', new Route('testing', ['packageName' => 'typo3tests/cms-test-templates-a']));
@@ -72,9 +67,7 @@ final class BackendViewFactoryTest extends FunctionalTestCase
         self::assertStringContainsString('Foo partial from extension test_templates_b', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createUsesOverrideTemplatePathsWithMultiplePackagesGivenAsArgument()
     {
         $request = (new ServerRequest())->withAttribute('route', new Route('testing', []));
@@ -92,9 +85,7 @@ final class BackendViewFactoryTest extends FunctionalTestCase
         self::assertStringContainsString('Foo partial from extension test_templates_b', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createUsesPrefersTemplateFromLastOverrideWithMultiplePackagesGivenAsArgument()
     {
         $request = (new ServerRequest())->withAttribute('route', new Route('testing', []));
@@ -112,9 +103,7 @@ final class BackendViewFactoryTest extends FunctionalTestCase
         self::assertStringContainsString('Foo partial from extension test_templates_a', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createUsesFirstExistingFilesInChainBeginningFromLastOverrideWithMultiplePackagesGivenAsArgument()
     {
         $request = (new ServerRequest())->withAttribute('route', new Route('testing', []));
@@ -133,9 +122,7 @@ final class BackendViewFactoryTest extends FunctionalTestCase
         self::assertStringContainsString('Foo partial from extension test_templates_a', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAllowsOverridesUsingTsConfig()
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/BackendViewFactoryTestPages.csv');
@@ -150,9 +137,7 @@ final class BackendViewFactoryTest extends FunctionalTestCase
         self::assertStringContainsString('Foo partial from extension test_templates_b', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAllowsOverridesUsingTsConfigUsesFirstExistingFilesInChain()
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/BackendViewFactoryTestPagesWithFallback.csv');
diff --git a/typo3/sysext/backend/Tests/Functional/View/Drawing/BackendLayoutRendererTest.php b/typo3/sysext/backend/Tests/Functional/View/Drawing/BackendLayoutRendererTest.php
index 411c0059761a..513e0ee341ba 100644
--- a/typo3/sysext/backend/Tests/Functional/View/Drawing/BackendLayoutRendererTest.php
+++ b/typo3/sysext/backend/Tests/Functional/View/Drawing/BackendLayoutRendererTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\View\Drawing;
 
+use PHPUnit\Framework\Attributes\Test;
 use PHPUnit\Framework\MockObject\MockObject;
 use TYPO3\CMS\Backend\View\BackendLayout\BackendLayout;
 use TYPO3\CMS\Backend\View\BackendViewFactory;
@@ -81,9 +82,7 @@ final class BackendLayoutRendererTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function emptyBackendLayoutIsRendered(): void
     {
         $configuration['__config']['backend_layout.'] = [
@@ -94,9 +93,7 @@ final class BackendLayoutRendererTest extends FunctionalTestCase
         self::assertCount(0, $subject->getGridForPageLayoutContext($pageLayoutContext)->getRows());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function oneRowBackendLayoutIsRendered(): void
     {
         $configuration['__config']['backend_layout.'] = [
@@ -112,9 +109,7 @@ final class BackendLayoutRendererTest extends FunctionalTestCase
         self::assertCount(0, $subject->getGridForPageLayoutContext($pageLayoutContext)->getColumns());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function multipleRowsBackendLayoutIsRendered(): void
     {
         $configuration['__config']['backend_layout.'] = [
@@ -133,9 +128,7 @@ final class BackendLayoutRendererTest extends FunctionalTestCase
         self::assertCount(0, $subject->getGridForPageLayoutContext($pageLayoutContext)->getColumns());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function oneRowOneColBackendLayoutIsRendered(): void
     {
         $configuration['__config']['backend_layout.'] = [
@@ -158,9 +151,7 @@ final class BackendLayoutRendererTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function oneRowMultipleColsBackendLayoutIsRendered(): void
     {
         $configuration['__config']['backend_layout.'] = [
@@ -186,9 +177,7 @@ final class BackendLayoutRendererTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function multipleRowsOneColBackendLayoutIsRendered(): void
     {
         $configuration['__config']['backend_layout.'] = [
@@ -218,9 +207,7 @@ final class BackendLayoutRendererTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function multipleRowsMultipleColsBackendLayoutIsRendered(): void
     {
         $configuration['__config']['backend_layout.'] = [
@@ -256,9 +243,7 @@ final class BackendLayoutRendererTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function noColPosBackendLayoutIsRendered(): void
     {
         $configuration['__config']['backend_layout.'] = [
diff --git a/typo3/sysext/backend/Tests/Functional/View/ValueFormatter/FlexFormValueFormatterTest.php b/typo3/sysext/backend/Tests/Functional/View/ValueFormatter/FlexFormValueFormatterTest.php
index ed4e4812510b..9604e5ac2d52 100644
--- a/typo3/sysext/backend/Tests/Functional/View/ValueFormatter/FlexFormValueFormatterTest.php
+++ b/typo3/sysext/backend/Tests/Functional/View/ValueFormatter/FlexFormValueFormatterTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\View\ValueFormatter;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\View\ValueFormatter\FlexFormValueFormatter;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -31,9 +32,7 @@ final class FlexFormValueFormatterTest extends FunctionalTestCase
         Bootstrap::initializeLanguageObject();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flexFormDataWillBeDisplayedHumanReadable(): void
     {
         $GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config'] = $this->getFieldTcaConfig();
@@ -52,9 +51,7 @@ final class FlexFormValueFormatterTest extends FunctionalTestCase
         self::assertSame($expectedOutput, $actualOutput);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function nullResultsInEmptyString(): void
     {
         $flexFormValueFormatter = new FlexFormValueFormatter();
@@ -69,9 +66,7 @@ final class FlexFormValueFormatterTest extends FunctionalTestCase
         self::assertSame('', $actualOutput);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function emptyStringResultsInEmptyString(): void
     {
         $flexFormValueFormatter = new FlexFormValueFormatter();
diff --git a/typo3/sysext/backend/Tests/Functional/ViewHelpers/Link/EditRecordViewHelperTest.php b/typo3/sysext/backend/Tests/Functional/ViewHelpers/Link/EditRecordViewHelperTest.php
index a32dbe2a22a4..604b888220dc 100644
--- a/typo3/sysext/backend/Tests/Functional/ViewHelpers/Link/EditRecordViewHelperTest.php
+++ b/typo3/sysext/backend/Tests/Functional/ViewHelpers/Link/EditRecordViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\ViewHelpers\Link;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\NormalizedParams;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -38,9 +39,7 @@ final class EditRecordViewHelperTest extends FunctionalTestCase
             ->withAttribute('normalizedParams', new NormalizedParams([], [], '', ''));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkInExplicitFormat(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -53,9 +52,7 @@ final class EditRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('edit[a_table][42]=edit', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkInInlineFormat(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -68,9 +65,7 @@ final class EditRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('edit[b_table][21]=edit', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkWithReturnUrl(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -83,9 +78,7 @@ final class EditRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('returnUrl=foo/bar', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkWithField(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -99,9 +92,7 @@ final class EditRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('columnsOnly=canonical_url', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkWithFields(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -115,9 +106,7 @@ final class EditRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('columnsOnly=canonical_url,title', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionForInvalidUidArgument(): void
     {
         $this->expectException(\InvalidArgumentException::class);
diff --git a/typo3/sysext/backend/Tests/Functional/ViewHelpers/Link/NewRecordViewHelperTest.php b/typo3/sysext/backend/Tests/Functional/ViewHelpers/Link/NewRecordViewHelperTest.php
index 986d8533d603..ab287cae4ac6 100644
--- a/typo3/sysext/backend/Tests/Functional/ViewHelpers/Link/NewRecordViewHelperTest.php
+++ b/typo3/sysext/backend/Tests/Functional/ViewHelpers/Link/NewRecordViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\ViewHelpers\Link;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\NormalizedParams;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -38,9 +39,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
             ->withAttribute('normalizedParams', new NormalizedParams([], [], '', ''));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkInExplicitFormat(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -53,9 +52,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('edit[a_table][17]=new', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkForRoot(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -68,9 +65,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('edit[a_table][0]=new', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkInInlineFormat(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -83,9 +78,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('edit[b_table][17]=new', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkWithReturnUrl(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -98,9 +91,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('returnUrl=foo/bar', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkWithPosition(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -113,9 +104,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('edit[c_table][-11]=new', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkWithDefaultValue(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -129,9 +118,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('defVals[c_table][c_field]=c_value', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkWithDefaultValues(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -145,9 +132,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('defVals[c_table][c_field]=c_value&amp;defVals[c_table][c_field2]=c_value2', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionForInvalidUidArgument(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -160,9 +145,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         (new TemplateView($context))->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionForUidAndPid()
     {
         $this->expectException(\InvalidArgumentException::class);
diff --git a/typo3/sysext/backend/Tests/Functional/ViewHelpers/Mfa/IfHasStateViewHelperTest.php b/typo3/sysext/backend/Tests/Functional/ViewHelpers/Mfa/IfHasStateViewHelperTest.php
index 085444ba80ef..24dd03b2e6fe 100644
--- a/typo3/sysext/backend/Tests/Functional/ViewHelpers/Mfa/IfHasStateViewHelperTest.php
+++ b/typo3/sysext/backend/Tests/Functional/ViewHelpers/Mfa/IfHasStateViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\ViewHelpers\Mfa;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Authentication\Mfa\MfaProviderRegistry;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
@@ -38,9 +39,7 @@ final class IfHasStateViewHelperTest extends FunctionalTestCase
         $this->view->assign('provider', $this->get(MfaProviderRegistry::class)->getProvider('totp'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsInactive(): void
     {
         $GLOBALS['BE_USER'] = $this->getBackendUser();
@@ -51,9 +50,7 @@ final class IfHasStateViewHelperTest extends FunctionalTestCase
         self::assertStringNotContainsString('isLocked', $result);
         self::assertStringNotContainsString('isUnlocked', $result);
     }
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsActive(): void
     {
         $GLOBALS['BE_USER'] = $this->getBackendUser(true);
@@ -64,9 +61,7 @@ final class IfHasStateViewHelperTest extends FunctionalTestCase
         self::assertStringNotContainsString('isLocked', $result);
         self::assertStringContainsString('isUnlocked', $result);
     }
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsLocked(): void
     {
         $GLOBALS['BE_USER'] = $this->getBackendUser(true, true);
diff --git a/typo3/sysext/backend/Tests/Functional/ViewHelpers/Uri/EditRecordViewHelperTest.php b/typo3/sysext/backend/Tests/Functional/ViewHelpers/Uri/EditRecordViewHelperTest.php
index 5816a86d7d86..4a8341942dbb 100644
--- a/typo3/sysext/backend/Tests/Functional/ViewHelpers/Uri/EditRecordViewHelperTest.php
+++ b/typo3/sysext/backend/Tests/Functional/ViewHelpers/Uri/EditRecordViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\ViewHelpers\Uri;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\NormalizedParams;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -38,9 +39,7 @@ final class EditRecordViewHelperTest extends FunctionalTestCase
             ->withAttribute('normalizedParams', new NormalizedParams([], [], '', ''));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkInExplicitFormat(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -53,9 +52,7 @@ final class EditRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('edit[a_table][42]=edit', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkInInlineFormat(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -68,9 +65,7 @@ final class EditRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('edit[b_table][21]=edit', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkWithReturnUrl(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -83,9 +78,7 @@ final class EditRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('returnUrl=foo/bar', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkWithField(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -99,9 +92,7 @@ final class EditRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('columnsOnly=canonical_url', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkWithFields(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -115,9 +106,7 @@ final class EditRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('columnsOnly=canonical_url,title', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionForInvalidUidArgument(): void
     {
         $this->expectException(\InvalidArgumentException::class);
diff --git a/typo3/sysext/backend/Tests/Functional/ViewHelpers/Uri/NewRecordViewHelperTest.php b/typo3/sysext/backend/Tests/Functional/ViewHelpers/Uri/NewRecordViewHelperTest.php
index 1a0b61eeab05..674c8132fe33 100644
--- a/typo3/sysext/backend/Tests/Functional/ViewHelpers/Uri/NewRecordViewHelperTest.php
+++ b/typo3/sysext/backend/Tests/Functional/ViewHelpers/Uri/NewRecordViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\Functional\ViewHelpers\Uri;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\NormalizedParams;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -38,9 +39,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
             ->withAttribute('normalizedParams', new NormalizedParams([], [], '', ''));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkInExplicitFormat(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -53,9 +52,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('edit[a_table][17]=new', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkForRoot(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -68,9 +65,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('edit[a_table][0]=new', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkInInlineFormat(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -83,9 +78,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('edit[b_table][17]=new', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkWithReturnUrl(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -98,9 +91,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('returnUrl=foo/bar', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkWitPosition(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -113,9 +104,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('edit[c_table][-11]=new', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkWithDefaultValue(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -129,9 +118,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('defVals[c_table][c_field]=c_value', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsValidLinkWithDefaultValues(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -145,9 +132,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('defVals[c_table][c_field]=c_value&defVals[c_table][c_field2]=c_value2', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionForUidAndPid(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -160,9 +145,7 @@ final class NewRecordViewHelperTest extends FunctionalTestCase
         (new TemplateView($context))->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionForInvalidUidArgument(): void
     {
         $this->expectException(\InvalidArgumentException::class);
diff --git a/typo3/sysext/backend/Tests/FunctionalDeprecated/Configuration/TypoScript/ConditionMatching/ConditionMatcherTest.php b/typo3/sysext/backend/Tests/FunctionalDeprecated/Configuration/TypoScript/ConditionMatching/ConditionMatcherTest.php
index 8f691fd11df9..bc8de4b85241 100644
--- a/typo3/sysext/backend/Tests/FunctionalDeprecated/Configuration/TypoScript/ConditionMatching/ConditionMatcherTest.php
+++ b/typo3/sysext/backend/Tests/FunctionalDeprecated/Configuration/TypoScript/ConditionMatching/ConditionMatcherTest.php
@@ -17,7 +17,10 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Backend\Tests\FunctionalDeprecated\Configuration\TypoScript\ConditionMatching;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Log\NullLogger;
+use Symfony\Component\ExpressionLanguage\Node\BinaryNode;
 use TYPO3\CMS\Backend\Configuration\TypoScript\ConditionMatching\ConditionMatcher;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Context\Context;
@@ -45,9 +48,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether usergroup comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function usergroupConditionMatchesSingleGroupId(): void
     {
         $subject = $this->getConditionMatcher();
@@ -58,9 +60,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether usergroup comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function usergroupConditionMatchesMultipleUserGroupId(): void
     {
         $subject = $this->getConditionMatcher();
@@ -70,9 +71,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether checking for a user group matches.
-     *
-     * @test
      */
+    #[Test]
     public function userGroupInOperatorConditionMatchesGroupId(): void
     {
         $subject = $this->getConditionMatcher();
@@ -81,9 +81,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether user comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function loginUserConditionMatchesAnyLoggedInUser(): void
     {
         $subject = $this->getConditionMatcher();
@@ -93,9 +92,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether user comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function loginUserConditionMatchesSingleLoggedInUser(): void
     {
         $subject = $this->getConditionMatcher();
@@ -106,9 +104,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether user comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function loginUserConditionDoesNotMatchSingleLoggedInUser(): void
     {
         $subject = $this->getConditionMatcher();
@@ -119,9 +116,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether user comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function loginUserConditionMatchesMultipleLoggedInUsers(): void
     {
         $subject = $this->getConditionMatcher();
@@ -131,9 +127,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether checking for an admin user matches
-     *
-     * @test
      */
+    #[Test]
     public function adminUserConditionMatchesAdminUser(): void
     {
         $subject = $this->getConditionMatcher();
@@ -144,9 +139,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether checking for workspace id matches current workspace id
-     *
-     * @test
      */
+    #[Test]
     public function workspaceIdConditionMatchesCurrentWorkspaceId(): void
     {
         $this->setUpWorkspaceAspect(0);
@@ -159,9 +153,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether checking if workspace is live matches
-     *
-     * @test
      */
+    #[Test]
     public function workspaceIsLiveMatchesCorrectWorkspaceState(): void
     {
         $this->setUpWorkspaceAspect(1);
@@ -175,9 +168,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether checking if workspace is offline matches
-     *
-     * @test
      */
+    #[Test]
     public function workspaceIsOfflineMatchesCorrectWorkspaceState(): void
     {
         $this->setUpWorkspaceAspect(1);
@@ -191,9 +183,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether treeLevel comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function treeLevelConditionMatchesSingleValue(): void
     {
         $subject = $this->getConditionMatcher(2);
@@ -202,9 +193,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether treeLevel comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function treeLevelConditionMatchesMultipleValues(): void
     {
         $subject = $this->getConditionMatcher(2);
@@ -213,9 +203,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether treeLevel comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function treeLevelConditionDoesNotMatchFaultyValue(): void
     {
         $subject = $this->getConditionMatcher();
@@ -224,9 +213,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether a page Id is found in the previous rootline entries.
-     *
-     * @test
      */
+    #[Test]
     public function PIDupinRootlineConditionMatchesSinglePageIdInRootline(): void
     {
         $subject = $this->getConditionMatcher(3);
@@ -249,9 +237,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether a page id is not found in the previous rootline entries.
-     *
-     * @test
      */
+    #[Test]
     public function PIDupinRootlineConditionDoesNotMatchLastPageIdInRootline(): void
     {
         $subject = $this->getConditionMatcher(3);
@@ -260,9 +247,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether a page Id is found in the previous rootline entries.
-     *
-     * @test
      */
+    #[Test]
     public function PIDupinRootlineConditionDoesNotMatchPageIdNotInRootline(): void
     {
         $subject = $this->getConditionMatcher(3);
@@ -271,9 +257,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether a page Id is found in all rootline entries.
-     *
-     * @test
      */
+    #[Test]
     public function PIDinRootlineConditionMatchesSinglePageIdInRootline(): void
     {
         $subject = $this->getConditionMatcher(3);
@@ -282,9 +267,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether a page Id is found in all rootline entries.
-     *
-     * @test
      */
+    #[Test]
     public function PIDinRootlineConditionMatchesLastPageIdInRootline(): void
     {
         $subject = $this->getConditionMatcher(3);
@@ -293,9 +277,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether a page Id is found in all rootline entries.
-     *
-     * @test
      */
+    #[Test]
     public function PIDinRootlineConditionDoesNotMatchPageIdNotInRootline(): void
     {
         $subject = $this->getConditionMatcher(3);
@@ -305,9 +288,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
     /**
      * Tests whether the compatibility version can be evaluated.
      * (e.g. 7.9 is compatible to 7.0 but not to 15.0)
-     *
-     * @test
      */
+    #[Test]
     public function compatVersionConditionMatchesOlderRelease(): void
     {
         $subject = $this->getConditionMatcher();
@@ -319,9 +301,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
     /**
      * Tests whether the compatibility version can be evaluated.
      * (e.g. 7.9 is compatible to 7.0 but not to 15.0)
-     *
-     * @test
      */
+    #[Test]
     public function compatVersionConditionMatchesSameRelease(): void
     {
         $typo3Version = new Typo3Version();
@@ -334,9 +315,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
     /**
      * Tests whether the compatibility version can be evaluated.
      * (e.g. 7.9 is compatible to 7.0 but not to 15.0)
-     *
-     * @test
      */
+    #[Test]
     public function compatVersionConditionDoesNotMatchNewerRelease(): void
     {
         $subject = $this->getConditionMatcher();
@@ -347,9 +327,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether the generic fetching of variables works with the namespace 'ENV'.
-     *
-     * @test
      */
+    #[Test]
     public function genericGetVariablesSucceedsWithNamespaceENV(): void
     {
         $testKey = StringUtility::getUniqueId('test');
@@ -358,9 +337,7 @@ final class ConditionMatcherTest extends FunctionalTestCase
         self::assertTrue($subject->match('[getenv("' . $testKey . '") == "testValue"]'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function usingTSFEInATestInBeContextIsAlwaysFalse(): void
     {
         $subject = $this->getConditionMatcher();
@@ -423,10 +400,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider determinePageIdFindIdFromQueryParametersDataProvider
-     */
+    #[DataProvider('determinePageIdFindIdFromQueryParametersDataProvider')]
+    #[Test]
     public function determinePageIdFindIdFromQueryParameters($queryParameters, $resultPageId): void
     {
         $_GET = $queryParameters;
@@ -458,7 +433,7 @@ final class ConditionMatcherTest extends FunctionalTestCase
         // Symfony 7 dropped the `inArray` method with 7.0.0 from the BinaryNode, so we can use it as a check here for
         // the version and avoid to deal with composer version information here.
         return method_exists(
-            \Symfony\Component\ExpressionLanguage\Node\BinaryNode::class,
+            BinaryNode::class,
             'inArray'
         ) === false;
     }
diff --git a/typo3/sysext/beuser/Tests/Functional/ViewHelpers/MfaStatusViewHelperTest.php b/typo3/sysext/beuser/Tests/Functional/ViewHelpers/MfaStatusViewHelperTest.php
index d74867e9b329..3afbc3fa7a8f 100644
--- a/typo3/sysext/beuser/Tests/Functional/ViewHelpers/MfaStatusViewHelperTest.php
+++ b/typo3/sysext/beuser/Tests/Functional/ViewHelpers/MfaStatusViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Beuser\Tests\Functional\ViewHelpers;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Localization\LanguageService;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -46,25 +47,19 @@ final class MfaStatusViewHelperTest extends FunctionalTestCase
         $this->view = new TemplateView($context);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsEmptyResultForInvalidUserUid(): void
     {
         self::assertEmpty($this->view->assign('userUid', 0)->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsEmptyResultForUnknownUserUid(): void
     {
         self::assertEmpty($this->view->assign('userUid', 123)->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsMfaEnabledLabel(): void
     {
         self::assertEquals(
@@ -73,9 +68,7 @@ final class MfaStatusViewHelperTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsMfaLockedLabel(): void
     {
         self::assertEquals(
@@ -84,9 +77,7 @@ final class MfaStatusViewHelperTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsMfaLockedLabelOnMixedProviders(): void
     {
         self::assertEquals(
diff --git a/typo3/sysext/core/Tests/Functional/Authentication/AbstractUserAuthenticationTest.php b/typo3/sysext/core/Tests/Functional/Authentication/AbstractUserAuthenticationTest.php
index 6cf63da49139..65f13a7ac6a7 100644
--- a/typo3/sysext/core/Tests/Functional/Authentication/AbstractUserAuthenticationTest.php
+++ b/typo3/sysext/core/Tests/Functional/Authentication/AbstractUserAuthenticationTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Authentication;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -47,27 +49,21 @@ final class AbstractUserAuthenticationTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pushModuleDataDoesNotRevealPlainSessionId(): void
     {
         $this->subject->pushModuleData(self::class, true);
         self::assertNotContains($this->sessionId, $this->subject->uc['moduleSessionID']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getModuleDataResolvesHashedSessionId(): void
     {
         $this->subject->pushModuleData(self::class, true);
         self::assertTrue($this->subject->getModuleData(self::class));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getModuleDataFallsBackToPlainSessionId(): void
     {
         $this->subject->uc['moduleData'][self::class] = true;
@@ -86,10 +82,8 @@ final class AbstractUserAuthenticationTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getAuthInfoArrayReturnsEmptyPidListIfNoCheckPidValueIsGivenDataProvider
-     */
+    #[DataProvider('getAuthInfoArrayReturnsEmptyPidListIfNoCheckPidValueIsGivenDataProvider')]
+    #[Test]
     public function getAuthInfoArrayReturnsCorrectPidConstraintForGivenCheckPidValue(
         int|null|string $checkPid_value,
         string $expectedPids
diff --git a/typo3/sysext/core/Tests/Functional/Authentication/AuthenticationServiceTest.php b/typo3/sysext/core/Tests/Functional/Authentication/AuthenticationServiceTest.php
index d48327be961e..c83521103478 100644
--- a/typo3/sysext/core/Tests/Functional/Authentication/AuthenticationServiceTest.php
+++ b/typo3/sysext/core/Tests/Functional/Authentication/AuthenticationServiceTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Authentication;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Log\NullLogger;
 use TYPO3\CMS\Core\Authentication\AuthenticationService;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
@@ -40,9 +41,7 @@ final class AuthenticationServiceTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/../../../../core/Tests/Functional/Fixtures/be_users.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getUserReturnsOnlyNotDeletedRecords(): void
     {
         $this->subject->pObj = new BackendUserAuthentication();
diff --git a/typo3/sysext/core/Tests/Functional/Authentication/BackendUserAuthenticationTest.php b/typo3/sysext/core/Tests/Functional/Authentication/BackendUserAuthenticationTest.php
index 119b60e8f6bc..26ec3f3b6ba6 100644
--- a/typo3/sysext/core/Tests/Functional/Authentication/BackendUserAuthenticationTest.php
+++ b/typo3/sysext/core/Tests/Functional/Authentication/BackendUserAuthenticationTest.php
@@ -17,6 +17,9 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Authentication;
 
+use Doctrine\DBAL\Exception;
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\AuthenticationService;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Authentication\Mfa\MfaRequiredException;
@@ -37,7 +40,7 @@ final class BackendUserAuthenticationTest extends FunctionalTestCase
     protected $subject;
 
     /**
-     * @throws \Doctrine\DBAL\Exception
+     * @throws Exception
      * @throws \TYPO3\TestingFramework\Core\Exception
      */
     protected function setUp(): void
@@ -60,9 +63,7 @@ final class BackendUserAuthenticationTest extends FunctionalTestCase
         $this->subject = $backendUser;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFileMountRecordsReturnsFilemounts(): void
     {
         $backendUser = $this->setUpBackendUser(3);
@@ -70,18 +71,14 @@ final class BackendUserAuthenticationTest extends FunctionalTestCase
         self::assertCount(3, $records);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTranslatedPageOnWebMountIsInWebMountForNonAdminUser(): void
     {
         $result = $this->subject->isInWebMount(2);
         self::assertNotNull($result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function userTsConfigIsResolvedProperlyWithPrioritization(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] = "custom.generic = installation-wide-configuration\ncustom.property = from configuration";
@@ -95,9 +92,7 @@ final class BackendUserAuthenticationTest extends FunctionalTestCase
         self::assertEquals('installation-wide-configuration', $result['custom.']['generic']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function returnWebmountsFilterOutInaccessiblePages(): void
     {
         $result = $this->subject->returnWebmounts();
@@ -109,9 +104,7 @@ final class BackendUserAuthenticationTest extends FunctionalTestCase
         self::assertEquals(['1', '40'], $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDefaultUploadFolderFallsBackToDefaultStorage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_file_storage.csv');
@@ -130,9 +123,7 @@ final class BackendUserAuthenticationTest extends FunctionalTestCase
         self::assertEquals('/' . $path . '/', $folder->getIdentifier());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function loadGroupsWithProperSettingsAndOrder(): void
     {
         $subject = $this->setUpBackendUser(3);
@@ -142,9 +133,7 @@ final class BackendUserAuthenticationTest extends FunctionalTestCase
         self::assertEquals(['groupValue' => 'from_group_6', 'userValue' => 'from_user_3'], $subject->getTSConfig()['test.']['default.']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function mfaRequiredExceptionIsThrown(): void
     {
         $this->expectException(MfaRequiredException::class);
@@ -174,10 +163,8 @@ final class BackendUserAuthenticationTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider isImportEnabledDataProvider
-     */
+    #[DataProvider('isImportEnabledDataProvider')]
+    #[Test]
     public function isImportEnabledReturnsExpectedValues(int $userId, string $tsConfig, bool $expected): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] = $tsConfig;
@@ -207,10 +194,8 @@ final class BackendUserAuthenticationTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider isExportEnabledDataProvider
-     */
+    #[DataProvider('isExportEnabledDataProvider')]
+    #[Test]
     public function isExportEnabledReturnsExpectedValues(int $userId, string $tsConfig, bool $expected): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] = $tsConfig;
diff --git a/typo3/sysext/core/Tests/Functional/Authentication/GroupResolverTest.php b/typo3/sysext/core/Tests/Functional/Authentication/GroupResolverTest.php
index 41bfc916e850..c55d1bebf87d 100644
--- a/typo3/sysext/core/Tests/Functional/Authentication/GroupResolverTest.php
+++ b/typo3/sysext/core/Tests/Functional/Authentication/GroupResolverTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Authentication;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\GroupResolver;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -65,10 +67,10 @@ final class GroupResolverTest extends FunctionalTestCase
     }
 
     /**
-     * @test
-     * @dataProvider findAllUsersOfGroupsHandlesRecursiveCallsDataProvider
      * @param int[] $groupIds
      */
+    #[DataProvider('findAllUsersOfGroupsHandlesRecursiveCallsDataProvider')]
+    #[Test]
     public function findAllUsersOfGroupsHandlesRecursiveCalls(array $groupIds, array $expectedUsers): void
     {
         $subject = GeneralUtility::makeInstance(GroupResolver::class);
diff --git a/typo3/sysext/core/Tests/Functional/Authentication/Mfa/MfaProviderPropertyManagerTest.php b/typo3/sysext/core/Tests/Functional/Authentication/Mfa/MfaProviderPropertyManagerTest.php
index 9411201768b2..5fa1d695feda 100644
--- a/typo3/sysext/core/Tests/Functional/Authentication/Mfa/MfaProviderPropertyManagerTest.php
+++ b/typo3/sysext/core/Tests/Functional/Authentication/Mfa/MfaProviderPropertyManagerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Authentication\Mfa;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Authentication\AbstractUserAuthentication;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
@@ -41,9 +42,7 @@ final class MfaProviderPropertyManagerTest extends FunctionalTestCase
         $this->user->setBeUserByUid(4);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createTest(): void
     {
         $propertyManager = $this->createPropertyManager('totp');
@@ -52,18 +51,14 @@ final class MfaProviderPropertyManagerTest extends FunctionalTestCase
         self::assertEquals($this->user, $propertyManager->getUser());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasProviderEntryTest(): void
     {
         self::assertFalse($this->createPropertyManager('recovery-codes')->hasProviderEntry());
         self::assertTrue($this->createPropertyManager('totp')->hasProviderEntry());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasPropertyTest(): void
     {
         $propertyManager = $this->createPropertyManager('totp');
@@ -71,9 +66,7 @@ final class MfaProviderPropertyManagerTest extends FunctionalTestCase
         self::assertTrue($propertyManager->hasProperty('active'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPropertyTest(): void
     {
         $propertyManager = $this->createPropertyManager('totp');
@@ -83,9 +76,7 @@ final class MfaProviderPropertyManagerTest extends FunctionalTestCase
         self::assertEquals('KRMVATZTJFZUC53FONXW2ZJB', $propertyManager->getProperty('secret'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPropertiesTest(): void
     {
         $propertyManager = $this->createPropertyManager('recovery-codes');
@@ -102,9 +93,7 @@ final class MfaProviderPropertyManagerTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function updatePropertiesTest(): void
     {
         $propertyManager = $this->createPropertyManager('totp');
@@ -141,9 +130,7 @@ final class MfaProviderPropertyManagerTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createProviderEntryThrowsExceptionOnAlreadyExistingEntryTest(): void
     {
         $this->expectExceptionCode(1612781782);
@@ -151,9 +138,7 @@ final class MfaProviderPropertyManagerTest extends FunctionalTestCase
         $this->createPropertyManager('totp')->createProviderEntry(['key' => 'value']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createProviderEntryTest(): void
     {
         $timestamp = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('date', 'timestamp');
@@ -193,9 +178,7 @@ final class MfaProviderPropertyManagerTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteProviderEntryTest(): void
     {
         $propertyManager = $this->createPropertyManager('totp');
diff --git a/typo3/sysext/core/Tests/Functional/Authentication/Mfa/MfaProviderRegistryTest.php b/typo3/sysext/core/Tests/Functional/Authentication/Mfa/MfaProviderRegistryTest.php
index 85e5aa5c5892..885e93c2d2dd 100644
--- a/typo3/sysext/core/Tests/Functional/Authentication/Mfa/MfaProviderRegistryTest.php
+++ b/typo3/sysext/core/Tests/Functional/Authentication/Mfa/MfaProviderRegistryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Authentication\Mfa;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\AbstractUserAuthentication;
 use TYPO3\CMS\Core\Authentication\Mfa\MfaProviderManifest;
 use TYPO3\CMS\Core\Authentication\Mfa\MfaProviderRegistry;
@@ -71,9 +72,7 @@ final class MfaProviderRegistryTest extends FunctionalTestCase
         self::assertInstanceOf(MfaProviderManifest::class, $this->subject->getProvider('some-provider'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getProviderThrowsExceptionOnInvalidIdentifierTest(): void
     {
         $this->expectExceptionCode(1610994735);
@@ -81,9 +80,7 @@ final class MfaProviderRegistryTest extends FunctionalTestCase
         $this->subject->getProvider('unknown-provider');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasActiveProvidersTest(): void
     {
         self::assertFalse($this->subject->hasActiveProviders($this->user));
@@ -91,9 +88,7 @@ final class MfaProviderRegistryTest extends FunctionalTestCase
         self::assertTrue($this->subject->hasActiveProviders($this->user));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getActiveProvidersTest(): void
     {
         self::assertCount(0, $this->subject->getActiveProviders($this->user));
@@ -111,9 +106,7 @@ final class MfaProviderRegistryTest extends FunctionalTestCase
         self::assertEquals('recovery-codes', array_key_last($result));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFirstAuthenticationAwareProviderTest(): void
     {
         self::assertNull($this->subject->getFirstAuthenticationAwareProvider($this->user));
@@ -136,9 +129,7 @@ final class MfaProviderRegistryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasLockedProvidersTest(): void
     {
         self::assertFalse($this->subject->hasLockedProviders($this->user));
@@ -146,9 +137,7 @@ final class MfaProviderRegistryTest extends FunctionalTestCase
         self::assertTrue($this->subject->hasLockedProviders($this->user));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getLockedProvidersTest(): void
     {
         self::assertCount(0, $this->subject->getLockedProviders($this->user));
@@ -166,9 +155,7 @@ final class MfaProviderRegistryTest extends FunctionalTestCase
         self::assertEquals('recovery-codes', array_key_last($result));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function allowedProvidersItemsProcFuncTest(): void
     {
         $parameters = [];
diff --git a/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/RecoveryCodesProviderTest.php b/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/RecoveryCodesProviderTest.php
index 063a6956fa6e..0d3549e185a9 100644
--- a/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/RecoveryCodesProviderTest.php
+++ b/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/RecoveryCodesProviderTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Authentication\Mfa\Provider;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Authentication\Mfa\MfaProviderManifestInterface;
 use TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager;
@@ -60,9 +61,7 @@ final class RecoveryCodesProviderTest extends FunctionalTestCase
         $this->subject = $this->get(MfaProviderRegistry::class)->getProvider('recovery-codes');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canProcessTest(): void
     {
         self::assertFalse($this->subject->canProcess(new ServerRequest('https://example.com', 'POST')));
@@ -74,9 +73,7 @@ final class RecoveryCodesProviderTest extends FunctionalTestCase
         ));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isActiveTest(): void
     {
         self::assertFalse($this->subject->isActive(MfaProviderPropertyManager::create($this->subject, $this->user)));
@@ -86,9 +83,7 @@ final class RecoveryCodesProviderTest extends FunctionalTestCase
         self::assertTrue($this->subject->isActive(MfaProviderPropertyManager::create($this->subject, $this->user)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isLockedTest(): void
     {
         self::assertFalse($this->subject->isLocked(MfaProviderPropertyManager::create($this->subject, $this->user)));
@@ -102,9 +97,7 @@ final class RecoveryCodesProviderTest extends FunctionalTestCase
         self::assertTrue($this->subject->isLocked(MfaProviderPropertyManager::create($this->subject, $this->user)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyTest(): void
     {
         $code = '12345678';
@@ -132,9 +125,7 @@ final class RecoveryCodesProviderTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function activateTest(): void
     {
         $request = (new ServerRequest('https://example.com', 'POST'));
@@ -152,9 +143,7 @@ final class RecoveryCodesProviderTest extends FunctionalTestCase
         self::assertTrue($this->subject->activate($request->withParsedBody($parsedBody), $propertyManager));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deactivateTest(): void
     {
         $request = (new ServerRequest('https://example.com', 'POST'));
@@ -168,9 +157,7 @@ final class RecoveryCodesProviderTest extends FunctionalTestCase
         self::assertTrue($this->subject->deactivate($request, MfaProviderPropertyManager::create($this->subject, $this->user)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function unlockTest(): void
     {
         $request = (new ServerRequest('https://example.com', 'POST'));
@@ -186,9 +173,7 @@ final class RecoveryCodesProviderTest extends FunctionalTestCase
         self::assertEquals('Your recovery codes were automatically updated!', $message->getTitle());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function updateTest(): void
     {
         $request = (new ServerRequest('https://example.com', 'POST'));
@@ -205,9 +190,7 @@ final class RecoveryCodesProviderTest extends FunctionalTestCase
         self::assertEquals('Recovery codes successfully regenerated', $message->getTitle());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setupFailsIfNoOtherMfaProviderIsActive(): void
     {
         $this->expectException(PropagateResponseException::class);
@@ -218,9 +201,7 @@ final class RecoveryCodesProviderTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setupReturnsHtmlWithRecoveryCodes(): void
     {
         $this->setupUser();
@@ -232,9 +213,7 @@ final class RecoveryCodesProviderTest extends FunctionalTestCase
         self::assertStringContainsString('<textarea type="text" id="recoveryCodes"', $response->getBody()->getContents());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function editViewTest(): void
     {
         $request = (new ServerRequest('https://example.com', 'POST'));
@@ -256,9 +235,7 @@ final class RecoveryCodesProviderTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/<input.*id="regenerateCodes"/s', $response);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function authViewTest(): void
     {
         $request = (new ServerRequest('https://example.com', 'POST'));
diff --git a/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/TotpProviderTest.php b/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/TotpProviderTest.php
index ef1eba363af4..d6faad065d90 100644
--- a/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/TotpProviderTest.php
+++ b/typo3/sysext/core/Tests/Functional/Authentication/Mfa/Provider/TotpProviderTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Authentication\Mfa\Provider;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Authentication\Mfa\MfaProviderManifestInterface;
 use TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager;
@@ -43,9 +44,7 @@ final class TotpProviderTest extends FunctionalTestCase
         $this->subject = $this->get(MfaProviderRegistry::class)->getProvider('totp');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canProcessTest(): void
     {
         self::assertFalse($this->subject->canProcess(new ServerRequest('https://example.com', 'POST')));
@@ -57,9 +56,7 @@ final class TotpProviderTest extends FunctionalTestCase
         ));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isActiveTest(): void
     {
         // No provider entry exists
@@ -78,9 +75,7 @@ final class TotpProviderTest extends FunctionalTestCase
         self::assertTrue($this->subject->isActive(MfaProviderPropertyManager::create($this->subject, $this->user)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isLockedTest(): void
     {
         // No provider entry exists
@@ -95,9 +90,7 @@ final class TotpProviderTest extends FunctionalTestCase
         self::assertTrue($this->subject->isLocked(MfaProviderPropertyManager::create($this->subject, $this->user)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyTest(): void
     {
         $request = (new ServerRequest('https://example.com', 'POST'));
@@ -143,9 +136,7 @@ final class TotpProviderTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function activateTest(): void
     {
         $request = (new ServerRequest('https://example.com', 'POST'));
@@ -168,9 +159,7 @@ final class TotpProviderTest extends FunctionalTestCase
         self::assertEquals('KRMVATZTJFZUC53FONXW2ZJB', $propertyManager->getProperty('secret'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deactivateTest(): void
     {
         $request = (new ServerRequest('https://example.com', 'POST'));
@@ -187,9 +176,7 @@ final class TotpProviderTest extends FunctionalTestCase
         self::assertTrue($this->subject->deactivate($request, MfaProviderPropertyManager::create($this->subject, $this->user)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function unlockTest(): void
     {
         $request = (new ServerRequest('https://example.com', 'POST'));
@@ -210,9 +197,7 @@ final class TotpProviderTest extends FunctionalTestCase
         self::assertTrue($this->subject->unlock($request, MfaProviderPropertyManager::create($this->subject, $this->user)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function updateTest(): void
     {
         $request = (new ServerRequest('https://example.com', 'POST'));
@@ -234,9 +219,7 @@ final class TotpProviderTest extends FunctionalTestCase
         self::assertTrue($this->subject->update($request, MfaProviderPropertyManager::create($this->subject, $this->user)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setupViewTest(): void
     {
         $request = (new ServerRequest('https://example.com', 'POST'));
@@ -249,9 +232,7 @@ final class TotpProviderTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/<typo3-mfa-totp-url-info-button.*url="otpauth:\/\//s', $response);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function editViewTest(): void
     {
         $request = (new ServerRequest('https://example.com', 'POST'));
@@ -264,9 +245,7 @@ final class TotpProviderTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/<td>.*Last used.*<td>.*18-03-21/s', $response);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function authViewTest(): void
     {
         $request = (new ServerRequest('https://example.com', 'POST'));
diff --git a/typo3/sysext/core/Tests/Functional/Cache/Backend/ApcuBackendTest.php b/typo3/sysext/core/Tests/Functional/Cache/Backend/ApcuBackendTest.php
index 835e0e935734..f085a1bc0f15 100644
--- a/typo3/sysext/core/Tests/Functional/Cache/Backend/ApcuBackendTest.php
+++ b/typo3/sysext/core/Tests/Functional/Cache/Backend/ApcuBackendTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Cache\Backend;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Cache\Backend\ApcuBackend;
 use TYPO3\CMS\Core\Cache\Exception;
 use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
@@ -49,9 +51,7 @@ final class ApcuBackendTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setThrowsExceptionIfNoFrontEndHasBeenSet(): void
     {
         $backend = new ApcuBackend('Testing');
@@ -62,9 +62,7 @@ final class ApcuBackendTest extends FunctionalTestCase
         $backend->set($identifier, $data);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function itIsPossibleToSetAndCheckExistenceInCache(): void
     {
         $backend = new ApcuBackend('Testing');
@@ -86,10 +84,8 @@ final class ApcuBackendTest extends FunctionalTestCase
         yield [ ['foo', 'bar'] ];
     }
 
-    /**
-     * @test
-     * @dataProvider itIsPossibleToSetAndGetEntryDataProvider
-     */
+    #[DataProvider('itIsPossibleToSetAndGetEntryDataProvider')]
+    #[Test]
     public function itIsPossibleToSetAndGetEntry(mixed $data): void
     {
         $backend = new ApcuBackend('Testing');
@@ -99,9 +95,7 @@ final class ApcuBackendTest extends FunctionalTestCase
         self::assertSame($data, $backend->get($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function itIsPossibleToSetAndGetObject(): void
     {
         $backend = new ApcuBackend('Testing');
@@ -114,9 +108,7 @@ final class ApcuBackendTest extends FunctionalTestCase
         self::assertEquals($object, $fetchedData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function itIsPossibleToRemoveEntryFromCache(): void
     {
         $backend = new ApcuBackend('Testing');
@@ -128,9 +120,7 @@ final class ApcuBackendTest extends FunctionalTestCase
         self::assertFalse($backend->has($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function itIsPossibleToOverwriteAnEntryInTheCache(): void
     {
         $backend = new ApcuBackend('Testing');
@@ -144,9 +134,7 @@ final class ApcuBackendTest extends FunctionalTestCase
         self::assertEquals($otherData, $fetchedData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findIdentifiersByTagFindsSetEntries(): void
     {
         $backend = new ApcuBackend('Testing');
@@ -160,9 +148,7 @@ final class ApcuBackendTest extends FunctionalTestCase
         self::assertEquals($identifier, $retrieved[0]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setRemovesTagsFromPreviousSet(): void
     {
         $backend = new ApcuBackend('Testing');
@@ -175,9 +161,7 @@ final class ApcuBackendTest extends FunctionalTestCase
         self::assertEquals([], $retrieved);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasReturnsFalseIfTheEntryDoesNotExist(): void
     {
         $backend = new ApcuBackend('Testing');
@@ -186,9 +170,7 @@ final class ApcuBackendTest extends FunctionalTestCase
         self::assertFalse($backend->has($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeReturnsFalseIfTheEntryDoesntExist(): void
     {
         $backend = new ApcuBackend('Testing');
@@ -197,9 +179,7 @@ final class ApcuBackendTest extends FunctionalTestCase
         self::assertFalse($backend->remove($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagRemovesCacheEntriesWithSpecifiedTag(): void
     {
         $backend = new ApcuBackend('Testing');
@@ -214,9 +194,7 @@ final class ApcuBackendTest extends FunctionalTestCase
         self::assertTrue($backend->has('BackendAPCUTest3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagsRemovesCacheEntriesWithSpecifiedTags(): void
     {
         $backend = new ApcuBackend('Testing');
@@ -231,9 +209,7 @@ final class ApcuBackendTest extends FunctionalTestCase
         self::assertTrue($backend->has('BackendAPCUTest3'), 'BackendAPCTest3');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushRemovesAllCacheEntries(): void
     {
         $backend = new ApcuBackend('Testing');
@@ -248,9 +224,7 @@ final class ApcuBackendTest extends FunctionalTestCase
         self::assertFalse($backend->has('BackendAPCUTest3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushRemovesOnlyOwnEntries(): void
     {
         $thisCache = $this->createMock(FrontendInterface::class);
@@ -271,9 +245,8 @@ final class ApcuBackendTest extends FunctionalTestCase
 
     /**
      * Check if we can store ~5 MB of data
-     *
-     * @test
      */
+    #[Test]
     public function largeDataIsStored(): void
     {
         $backend = new ApcuBackend('Testing');
@@ -285,9 +258,7 @@ final class ApcuBackendTest extends FunctionalTestCase
         self::assertEquals($backend->get($identifier), $data);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setTagsOnlyOnceToIdentifier(): void
     {
         $identifier = StringUtility::getUniqueId('MyIdentifier');
diff --git a/typo3/sysext/core/Tests/Functional/Cache/Backend/FileBackendTest.php b/typo3/sysext/core/Tests/Functional/Cache/Backend/FileBackendTest.php
index 3514f3db406a..ab4e41ea3e2c 100644
--- a/typo3/sysext/core/Tests/Functional/Cache/Backend/FileBackendTest.php
+++ b/typo3/sysext/core/Tests/Functional/Cache/Backend/FileBackendTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Cache\Backend;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Cache\Backend\FileBackend;
 use TYPO3\CMS\Core\Cache\Exception;
 use TYPO3\CMS\Core\Cache\Exception\InvalidDataException;
@@ -37,9 +39,7 @@ final class FileBackendTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setCacheDirectoryThrowsExceptionOnNonWritableDirectory(): void
     {
         $this->expectException(Exception::class);
@@ -49,9 +49,7 @@ final class FileBackendTest extends FunctionalTestCase
         $subject->setCache(new NullFrontend('foo'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setCacheDirectoryAllowsAbsolutePathWithoutTrailingSlash(): void
     {
         $subject = $this->getAccessibleMock(FileBackend::class, null, [], '', false);
@@ -59,9 +57,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals('/tmp/foo/', $subject->_get('temporaryCacheDirectory'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setCacheDirectoryAllowsAbsolutePathWithTrailingSlash(): void
     {
         $subject = $this->getAccessibleMock(FileBackend::class, null, [], '', false);
@@ -69,9 +65,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals('/tmp/foo/', $subject->_get('temporaryCacheDirectory'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setCacheDirectoryAllowsRelativePathWithoutTrailingSlash(): void
     {
         $subject = $this->getAccessibleMock(FileBackend::class, null, [], '', false);
@@ -80,9 +74,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals($path . '/tmp/foo/', $subject->_get('temporaryCacheDirectory'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setCacheDirectoryAllowsRelativePathWithTrailingSlash(): void
     {
         $subject = $this->getAccessibleMock(FileBackend::class, null, [], '', false);
@@ -91,9 +83,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals($path . '/tmp/foo/', $subject->_get('temporaryCacheDirectory'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setCacheDirectoryAllowsRelativeDottedPathWithoutTrailingSlash(): void
     {
         $subject = $this->getAccessibleMock(FileBackend::class, null, [], '', false);
@@ -102,9 +92,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals($path . '/../tmp/foo/', $subject->_get('temporaryCacheDirectory'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setCacheDirectoryAllowsRelativeDottedPathWithTrailingSlash(): void
     {
         $subject = $this->getAccessibleMock(FileBackend::class, null, [], '', false);
@@ -113,9 +101,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals($path . '/../tmp/foo/', $subject->_get('temporaryCacheDirectory'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setCacheDirectoryAllowsAbsoluteDottedPathWithoutTrailingSlash(): void
     {
         $subject = $this->getAccessibleMock(FileBackend::class, null, [], '', false);
@@ -123,9 +109,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals('/tmp/../foo/', $subject->_get('temporaryCacheDirectory'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setCacheDirectoryAllowsAbsoluteDottedPathWithTrailingSlash(): void
     {
         $subject = $this->getAccessibleMock(FileBackend::class, null, [], '', false);
@@ -133,9 +117,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals('/tmp/../foo/', $subject->_get('temporaryCacheDirectory'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getCacheDirectoryReturnsTheCurrentCacheDirectory(): void
     {
         $subject = $this->getMockBuilder(FileBackend::class)->addMethods(['dummy'])->disableOriginalConstructor()->getMock();
@@ -144,9 +126,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals($this->instancePath . '/Foo/cache/code/SomeCache/', $subject->getCacheDirectory());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function aDedicatedCacheDirectoryIsUsedForCodeCaches(): void
     {
         $mockCache = $this->createMock(PhpFrontend::class);
@@ -157,9 +137,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals($this->instancePath . '/Foo/cache/code/SomeCache/', $subject->getCacheDirectory());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setThrowsExceptionIfDataIsNotAString(): void
     {
         $this->expectException(InvalidDataException::class);
@@ -170,9 +148,7 @@ final class FileBackendTest extends FunctionalTestCase
         $subject->set('some identifier', ['not a string']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setReallySavesToTheSpecifiedDirectory(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -189,9 +165,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals($data, $retrievedData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setOverwritesAnAlreadyExistingCacheEntryForTheSameIdentifier(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -210,9 +184,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals($data2, $retrievedData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setAlsoSavesSpecifiedTags(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -229,9 +201,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals('Tag1 Tag2', $retrievedData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setCacheDetectsAndLoadsAFrozenCache(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -250,9 +220,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals($data, $subject->get($entryIdentifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsContentOfTheCorrectCacheFile(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -269,9 +237,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals($data, $loadedData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsFalseForExpiredEntries(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -283,9 +249,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertFalse($subject->get('ExpiredEntry'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDoesNotCheckIfAnEntryIsExpiredIfTheCacheIsFrozen(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -300,9 +264,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertFalse($subject->get('bar'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasReturnsTrueIfAnEntryExists(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -317,9 +279,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertFalse($subject->has($entryIdentifier . 'Not'), 'has() did not return FALSE.');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasReturnsFalseForExpiredEntries(): void
     {
         $subject = $this->getMockBuilder(FileBackend::class)->onlyMethods(['isCacheFileExpired'])->disableOriginalConstructor()->getMock();
@@ -331,9 +291,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertTrue($subject->has('bar'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasDoesNotCheckIfAnEntryIsExpiredIfTheCacheIsFrozen(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -348,9 +306,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertFalse($subject->has('bar'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeReallyRemovesACacheEntry(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -385,10 +341,8 @@ final class FileBackendTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider invalidEntryIdentifiers
-     */
+    #[DataProvider('invalidEntryIdentifiers')]
+    #[Test]
     public function setThrowsExceptionForInvalidIdentifier(string $identifier): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -401,10 +355,8 @@ final class FileBackendTest extends FunctionalTestCase
         $subject->set($identifier, 'cache data', []);
     }
 
-    /**
-     * @test
-     * @dataProvider invalidEntryIdentifiers
-     */
+    #[DataProvider('invalidEntryIdentifiers')]
+    #[Test]
     public function getThrowsExceptionForInvalidIdentifier(string $identifier): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -417,10 +369,8 @@ final class FileBackendTest extends FunctionalTestCase
         $subject->get($identifier);
     }
 
-    /**
-     * @test
-     * @dataProvider invalidEntryIdentifiers
-     */
+    #[DataProvider('invalidEntryIdentifiers')]
+    #[Test]
     public function hasThrowsExceptionForInvalidIdentifier(string $identifier): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -429,10 +379,8 @@ final class FileBackendTest extends FunctionalTestCase
         $subject->has($identifier);
     }
 
-    /**
-     * @test
-     * @dataProvider invalidEntryIdentifiers
-     */
+    #[DataProvider('invalidEntryIdentifiers')]
+    #[Test]
     public function removeThrowsExceptionForInvalidIdentifier(string $identifier): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -445,10 +393,8 @@ final class FileBackendTest extends FunctionalTestCase
         $subject->remove($identifier);
     }
 
-    /**
-     * @test
-     * @dataProvider invalidEntryIdentifiers
-     */
+    #[DataProvider('invalidEntryIdentifiers')]
+    #[Test]
     public function requireOnceThrowsExceptionForInvalidIdentifier(string $identifier): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -461,9 +407,7 @@ final class FileBackendTest extends FunctionalTestCase
         $subject->requireOnce($identifier);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function requireOnceIncludesAndReturnsResultOfIncludedPhpFile(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -478,9 +422,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals('foo', $loadedData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function requireOnceDoesNotCheckExpiryTimeIfBackendIsFrozen(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -496,10 +438,8 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals('foo', $loadedData);
     }
 
-    /**
-     * @test
-     * @dataProvider invalidEntryIdentifiers
-     */
+    #[DataProvider('invalidEntryIdentifiers')]
+    #[Test]
     public function requireThrowsExceptionForInvalidIdentifier(string $identifier): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -512,9 +452,7 @@ final class FileBackendTest extends FunctionalTestCase
         $subject->require($identifier);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function requireIncludesAndReturnsResultOfIncludedPhpFile(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -529,9 +467,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals('foo2', $loadedData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function requireDoesNotCheckExpiryTimeIfBackendIsFrozen(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -547,9 +483,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals('foo', $loadedData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function requireCanLoadSameEntryMultipleTimes(): void
     {
         $frontendMock = $this->getMockBuilder(AbstractFrontend::class)->disableOriginalConstructor()->getMock();
@@ -564,9 +498,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals('foo', $loadedData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findIdentifiersByTagFindsCacheEntriesWithSpecifiedTag(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -584,9 +516,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertEquals($expectedEntry, array_pop($actualEntries));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findIdentifiersByTagDoesNotReturnExpiredEntries(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -604,9 +534,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertContains('BackendFileTest3', $actualEntries);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushRemovesAllCacheEntries(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -624,9 +552,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertFileDoesNotExist($this->instancePath . '/Foo/cache/data/UnitTestCache/BackendFileTest2');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushCreatesCacheDirectoryAgain(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -638,9 +564,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertFileExists($this->instancePath . '/Foo/cache/data/UnitTestCache/');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagRemovesCacheEntriesWithSpecifiedTag(): void
     {
         $subject = $this->getMockBuilder(FileBackend::class)->onlyMethods(['findIdentifiersByTag', 'remove'])->disableOriginalConstructor()->getMock();
@@ -662,9 +586,7 @@ final class FileBackendTest extends FunctionalTestCase
         $subject->flushByTag('UnitTestTag%special');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function collectGarbageRemovesExpiredCacheEntries(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
@@ -686,9 +608,7 @@ final class FileBackendTest extends FunctionalTestCase
         self::assertFileDoesNotExist($this->instancePath . '/Foo/cache/data/UnitTestCache/BackendFileTest2');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushUnfreezesTheCache(): void
     {
         $mockCache = $this->createMock(AbstractFrontend::class);
diff --git a/typo3/sysext/core/Tests/Functional/Cache/Backend/MemcachedBackendTest.php b/typo3/sysext/core/Tests/Functional/Cache/Backend/MemcachedBackendTest.php
index c7aad47896f6..15b153b120f5 100644
--- a/typo3/sysext/core/Tests/Functional/Cache/Backend/MemcachedBackendTest.php
+++ b/typo3/sysext/core/Tests/Functional/Cache/Backend/MemcachedBackendTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Cache\Backend;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Cache\Backend\MemcachedBackend;
 use TYPO3\CMS\Core\Cache\Exception;
 use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
@@ -61,9 +62,7 @@ final class MemcachedBackendTest extends FunctionalTestCase
         return $subject;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setThrowsExceptionIfNoFrontEndHasBeenSet(): void
     {
         $subject = $this->initializeSubject();
@@ -74,9 +73,7 @@ final class MemcachedBackendTest extends FunctionalTestCase
         $subject->set(StringUtility::getUniqueId('MyIdentifier'), 'some data');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function initializeObjectThrowsExceptionIfNoMemcacheServerIsConfigured(): void
     {
         $subject = new MemcachedBackend('Testing');
@@ -85,9 +82,7 @@ final class MemcachedBackendTest extends FunctionalTestCase
         $subject->initializeObject();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function itIsPossibleToSetAndCheckExistenceInCache(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -101,9 +96,7 @@ final class MemcachedBackendTest extends FunctionalTestCase
         self::assertTrue($subject->has($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function itIsPossibleToSetAndGetEntry(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -118,9 +111,7 @@ final class MemcachedBackendTest extends FunctionalTestCase
         self::assertEquals($data, $subject->get($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsPreviouslySetDataWithVariousTypes(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -147,9 +138,8 @@ final class MemcachedBackendTest extends FunctionalTestCase
 
     /**
      * Check if we can store ~5 MB of data.
-     *
-     * @test
      */
+    #[Test]
     public function largeDataIsStored(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -164,9 +154,7 @@ final class MemcachedBackendTest extends FunctionalTestCase
         self::assertEquals($subject->get('tooLargeData'), $data);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function itIsPossibleToRemoveEntryFromCache(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -182,9 +170,7 @@ final class MemcachedBackendTest extends FunctionalTestCase
         self::assertFalse($subject->has($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function itIsPossibleToOverwriteAnEntryInTheCache(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -201,9 +187,7 @@ final class MemcachedBackendTest extends FunctionalTestCase
         self::assertEquals($otherData, $subject->get($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findIdentifiersByTagFindsCacheEntriesWithSpecifiedTag(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -221,9 +205,7 @@ final class MemcachedBackendTest extends FunctionalTestCase
         self::assertEquals($identifier, $retrieved[0]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setRemovesTagsFromPreviousSet(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -239,9 +221,7 @@ final class MemcachedBackendTest extends FunctionalTestCase
         self::assertEquals([], $subject->findIdentifiersByTag('UnitTestTag%tagX'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasReturnsFalseIfTheEntryDoesntExist(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -254,9 +234,7 @@ final class MemcachedBackendTest extends FunctionalTestCase
         self::assertFalse($subject->has($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeReturnsFalseIfTheEntryDoesntExist(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -269,9 +247,7 @@ final class MemcachedBackendTest extends FunctionalTestCase
         self::assertFalse($subject->remove($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagRemovesCacheEntriesWithSpecifiedTag(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -290,9 +266,7 @@ final class MemcachedBackendTest extends FunctionalTestCase
         self::assertTrue($subject->has('BackendMemcacheTest3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagsRemovesCacheEntriesWithSpecifiedTags(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -311,9 +285,7 @@ final class MemcachedBackendTest extends FunctionalTestCase
         self::assertTrue($subject->has('BackendMemcacheTest3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushRemovesAllCacheEntries(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -332,9 +304,7 @@ final class MemcachedBackendTest extends FunctionalTestCase
         self::assertFalse($subject->has('BackendMemcacheTest3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushRemovesOnlyOwnEntries(): void
     {
         $thisFrontendMock = $this->createMock(FrontendInterface::class);
diff --git a/typo3/sysext/core/Tests/Functional/Cache/Backend/RedisBackendTest.php b/typo3/sysext/core/Tests/Functional/Cache/Backend/RedisBackendTest.php
index f2b48e5978bb..674432d6e99a 100644
--- a/typo3/sysext/core/Tests/Functional/Cache/Backend/RedisBackendTest.php
+++ b/typo3/sysext/core/Tests/Functional/Cache/Backend/RedisBackendTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Cache\Backend;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Log\LoggerInterface;
 use TYPO3\CMS\Core\Cache\Backend\RedisBackend;
 use TYPO3\CMS\Core\Cache\Exception\InvalidDataException;
@@ -87,9 +88,7 @@ final class RedisBackendTest extends FunctionalTestCase
         return $redis;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setDatabaseThrowsExceptionIfGivenDatabaseNumberIsNotAnInteger(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -98,9 +97,7 @@ final class RedisBackendTest extends FunctionalTestCase
         $this->setUpSubject(['database' => 'foo']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setDatabaseThrowsExceptionIfGivenDatabaseNumberIsNegative(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -109,9 +106,7 @@ final class RedisBackendTest extends FunctionalTestCase
         $this->setUpSubject(['database' => -1]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setCompressionThrowsExceptionIfCompressionParameterIsNotOfTypeBoolean(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -120,9 +115,7 @@ final class RedisBackendTest extends FunctionalTestCase
         $this->setUpSubject(['compression' => 'foo']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setCompressionLevelThrowsExceptionIfCompressionLevelIsNotInteger(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -131,9 +124,7 @@ final class RedisBackendTest extends FunctionalTestCase
         $this->setUpSubject(['compressionLevel' => 'foo']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setCompressionLevelThrowsExceptionIfCompressionLevelIsNotBetweenMinusOneAndNine(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -142,9 +133,7 @@ final class RedisBackendTest extends FunctionalTestCase
         $this->setUpSubject(['compressionLevel' => 11]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setConnectionTimeoutThrowsExceptionIfConnectionTimeoutIsNotInteger(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -153,9 +142,7 @@ final class RedisBackendTest extends FunctionalTestCase
         $this->setUpSubject(['connectionTimeout' => 'foo']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setConnectionTimeoutThrowsExceptionIfConnectionTimeoutIsNegative(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -164,9 +151,7 @@ final class RedisBackendTest extends FunctionalTestCase
         $this->setUpSubject(['connectionTimeout' => -1]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setThrowsExceptionIfIdentifierIsNotAString(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -176,9 +161,7 @@ final class RedisBackendTest extends FunctionalTestCase
         $subject->set([], 'data');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setThrowsExceptionIfDataIsNotAString(): void
     {
         $this->expectException(InvalidDataException::class);
@@ -188,9 +171,7 @@ final class RedisBackendTest extends FunctionalTestCase
         $subject->set(StringUtility::getUniqueId('identifier'), []);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setThrowsExceptionIfLifetimeIsNegative(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -200,9 +181,7 @@ final class RedisBackendTest extends FunctionalTestCase
         $subject->set(StringUtility::getUniqueId('identifier'), 'data', [], -42);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setThrowsExceptionIfLifetimeIsNotNullOrAnInteger(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -212,9 +191,7 @@ final class RedisBackendTest extends FunctionalTestCase
         $subject->set(StringUtility::getUniqueId('identifier'), 'data', [], []);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setStoresEntriesInSelectedDatabase(): void
     {
         $redis = $this->setUpRedis();
@@ -230,9 +207,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertTrue($result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setSavesStringDataTypeForIdentifierToDataEntry(): void
     {
         $subject = $this->setUpSubject();
@@ -242,9 +217,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame(\Redis::REDIS_STRING, $redis->type('identData:' . $identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setSavesEntryWithDefaultLifeTime(): void
     {
         $subject = $this->setUpSubject();
@@ -257,9 +230,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame($defaultLifetime, $lifetimeRegisteredInBackend);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setSavesEntryWithSpecifiedLifeTime(): void
     {
         $subject = $this->setUpSubject();
@@ -271,9 +242,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame($lifetime, $lifetimeRegisteredInBackend);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setSavesEntryWithUnlimitedLifeTime(): void
     {
         $subject = $this->setUpSubject();
@@ -284,9 +253,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame(31536000, $lifetimeRegisteredInBackend);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setOverwritesExistingEntryWithNewData(): void
     {
         $subject = $this->setUpSubject();
@@ -299,9 +266,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame($otherData, $fetchedData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setOverwritesExistingEntryWithSpecifiedLifetime(): void
     {
         $subject = $this->setUpSubject();
@@ -315,9 +280,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame($lifetime, $lifetimeRegisteredInBackend);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setOverwritesExistingEntryWithNewDefaultLifetime(): void
     {
         $subject = $this->setUpSubject();
@@ -333,9 +296,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame($newDefaultLifetime, $lifetimeRegisteredInBackend);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setOverwritesExistingEntryWithNewUnlimitedLifetime(): void
     {
         $subject = $this->setUpSubject();
@@ -349,9 +310,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame(31536000, $lifetimeRegisteredInBackend);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setSavesSetDataTypeForIdentifierToTagsSet(): void
     {
         $subject = $this->setUpSubject();
@@ -361,9 +320,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame(\Redis::REDIS_SET, $redis->type('identTags:' . $identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setSavesSpecifiedTagsInIdentifierToTagsSet(): void
     {
         $subject = $this->setUpSubject();
@@ -376,9 +333,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame($tags, $savedTags);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setRemovesAllPreviouslySetTagsFromIdentifierToTagsSet(): void
     {
         $subject = $this->setUpSubject();
@@ -390,9 +345,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame([], $redis->sMembers('identTags:' . $identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setRemovesMultiplePreviouslySetTagsFromIdentifierToTagsSet(): void
     {
         $subject = $this->setUpSubject();
@@ -407,9 +360,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame($secondTagSet, $actualTagSet);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setSavesSetDataTypeForTagToIdentifiersSet(): void
     {
         $subject = $this->setUpSubject();
@@ -420,9 +371,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame(\Redis::REDIS_SET, $redis->type('tagIdents:' . $tag));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setSavesIdentifierInTagToIdentifiersSetOfSpecifiedTag(): void
     {
         $subject = $this->setUpSubject();
@@ -434,9 +383,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame([$identifier], $savedTagToIdentifiersMemberArray);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setAppendsSecondIdentifierInTagToIdentifiersEntry(): void
     {
         $subject = $this->setUpSubject();
@@ -453,9 +400,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame([$firstIdentifier, $secondIdentifier], $savedTagToIdentifiersMemberArray);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setRemovesIdentifierFromTagToIdentifiersEntryIfTagIsOmittedOnConsecutiveSet(): void
     {
         $subject = $this->setUpSubject();
@@ -468,9 +413,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame([], $savedTagToIdentifiersMemberArray);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setAddsIdentifierInTagToIdentifiersEntryIfTagIsAddedOnConsecutiveSet(): void
     {
         $subject = $this->setUpSubject();
@@ -483,9 +426,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame([$identifier], $savedTagToIdentifiersMemberArray);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setSavesCompressedDataWithEnabledCompression(): void
     {
         $subject = $this->setUpSubject([
@@ -503,9 +444,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertEquals($data, $uncompressedStoredData, 'Original and compressed data don\'t match');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setSavesPlaintextDataWithEnabledCompressionAndCompressionLevel0(): void
     {
         $subject = $this->setUpSubject([
@@ -519,9 +458,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertGreaterThan(0, substr_count($redis->get('identData:' . $identifier), $data), 'Plaintext data not found');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasThrowsExceptionIfIdentifierIsNotAString(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -531,9 +468,7 @@ final class RedisBackendTest extends FunctionalTestCase
         $subject->has([]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasReturnsFalseForNotExistingEntry(): void
     {
         $subject = $this->setUpSubject();
@@ -541,9 +476,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertFalse($subject->has($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasReturnsTrueForPreviouslySetEntry(): void
     {
         $subject = $this->setUpSubject();
@@ -552,9 +485,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertTrue($subject->has($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getThrowsExceptionIfIdentifierIsNotAString(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -564,9 +495,7 @@ final class RedisBackendTest extends FunctionalTestCase
         $subject->get([]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsPreviouslyCompressedSetEntry(): void
     {
         $subject = $this->setUpSubject([
@@ -579,9 +508,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame($data, $fetchedData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsPreviouslySetEntry(): void
     {
         $subject = $this->setUpSubject();
@@ -592,9 +519,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame($data, $fetchedData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeThrowsExceptionIfIdentifierIsNotAString(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -604,18 +529,14 @@ final class RedisBackendTest extends FunctionalTestCase
         $subject->remove([]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeReturnsFalseIfNoEntryWasDeleted(): void
     {
         $subject = $this->setUpSubject();
         self::assertFalse($subject->remove(StringUtility::getUniqueId('identifier')));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeReturnsTrueIfAnEntryWasDeleted(): void
     {
         $subject = $this->setUpSubject();
@@ -624,9 +545,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertTrue($subject->remove($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeDeletesEntryFromCache(): void
     {
         $subject = $this->setUpSubject();
@@ -636,9 +555,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertFalse($subject->has($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeDeletesIdentifierToTagEntry(): void
     {
         $subject = $this->setUpSubject();
@@ -655,9 +572,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertFalse($result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeDeletesIdentifierFromTagToIdentifiersSet(): void
     {
         $subject = $this->setUpSubject();
@@ -670,9 +585,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame([], $tagToIdentifiersMemberArray);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeDeletesIdentifierFromTagToIdentifiersSetWithMultipleEntries(): void
     {
         $subject = $this->setUpSubject();
@@ -687,9 +600,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame([$secondIdentifier], $tagToIdentifiersMemberArray);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findIdentifiersByTagThrowsExceptionIfTagIsNotAString(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -699,18 +610,14 @@ final class RedisBackendTest extends FunctionalTestCase
         $subject->findIdentifiersByTag([]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findIdentifiersByTagReturnsEmptyArrayForNotExistingTag(): void
     {
         $subject = $this->setUpSubject();
         self::assertSame([], $subject->findIdentifiersByTag('thisTag'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findIdentifiersByTagReturnsAllIdentifiersTagedWithSpecifiedTag(): void
     {
         $subject = $this->setUpSubject();
@@ -729,9 +636,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame($expectedResult, $actualResult);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushRemovesAllEntriesFromCache(): void
     {
         $subject = $this->setUpSubject();
@@ -742,9 +647,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame([], $redis->keys('*'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagThrowsExceptionIfTagIsNotAString(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -754,9 +657,7 @@ final class RedisBackendTest extends FunctionalTestCase
         $subject->flushByTag([]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagRemovesEntriesTaggedWithSpecifiedTag(): void
     {
         $subject = $this->setUpSubject();
@@ -774,9 +675,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame($expectedResult, $actualResult);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagsRemovesEntriesTaggedWithSpecifiedTags(): void
     {
         $subject = $this->setUpSubject();
@@ -796,9 +695,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame($expectedResult, $actualResult);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagRemovesTemporarySet(): void
     {
         $subject = $this->setUpSubject();
@@ -810,9 +707,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame([], $redis->keys('temp*'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagRemovesIdentifierToTagsSetOfEntryTaggedWithGivenTag(): void
     {
         $subject = $this->setUpSubject();
@@ -829,9 +724,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertFalse($result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagDoesNotRemoveIdentifierToTagsSetOfUnrelatedEntry(): void
     {
         $subject = $this->setUpSubject();
@@ -846,9 +739,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame([$tagNotToRemove], $redis->sMembers('identTags:' . $identifierNotToBeRemoved));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagRemovesTagToIdentifiersSetOfGivenTag(): void
     {
         $subject = $this->setUpSubject();
@@ -865,9 +756,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertFalse($result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagRemovesIdentifiersTaggedWithGivenTagFromTagToIdentifiersSets(): void
     {
         $subject = $this->setUpSubject();
@@ -880,9 +769,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame([$identifier . 'C'], $redis->sMembers('tagIdents:tag2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function collectGarbageDoesNotRemoveNotExpiredIdentifierToDataEntry(): void
     {
         $subject = $this->setUpSubject();
@@ -900,9 +787,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertTrue($result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function collectGarbageRemovesLeftOverIdentifierToTagsSet(): void
     {
         $subject = $this->setUpSubject();
@@ -930,9 +815,7 @@ final class RedisBackendTest extends FunctionalTestCase
         self::assertSame($expectedResult, $actualResult);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function collectGarbageRemovesExpiredIdentifierFromTagsToIdentifierSet(): void
     {
         $subject = $this->setUpSubject();
diff --git a/typo3/sysext/core/Tests/Functional/Cache/Backend/Typo3DatabaseBackendTest.php b/typo3/sysext/core/Tests/Functional/Cache/Backend/Typo3DatabaseBackendTest.php
index a7235fb5205b..82b6cd5fcf3c 100644
--- a/typo3/sysext/core/Tests/Functional/Cache/Backend/Typo3DatabaseBackendTest.php
+++ b/typo3/sysext/core/Tests/Functional/Cache/Backend/Typo3DatabaseBackendTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Cache\Backend;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend;
 use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
 use TYPO3\CMS\Core\Database\Connection;
@@ -38,9 +39,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         ],
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsPreviouslySetEntry(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -53,9 +52,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertSame('myData', $subject->get('myIdentifier'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsPreviouslySetEntryWithNewContentIfSetWasCalledMultipleTimes(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -69,9 +66,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertSame('myNewData', $subject->get('myIdentifier'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setInsertsDataWithTagsIntoCacheTable(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -89,9 +84,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertSame(1, $tagsTableConnection->count('*', 'cache_pages_tags', ['identifier' => 'myIdentifier', 'tag' => 'anotherTag']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setStoresCompressedContent(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -116,9 +109,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertSame('myCachedContent', gzuncompress($row['content']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsFalseIfNoCacheEntryExists(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -130,9 +121,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertFalse($subject->get('myIdentifier'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsFalseForExpiredCacheEntry(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -157,9 +146,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertFalse($subject->get('myIdentifier'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsNotExpiredCacheEntry(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -184,9 +171,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertSame('myCachedContent', $subject->get('myIdentifier'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsUnzipsNotExpiredCacheEntry(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -213,9 +198,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertSame('myCachedContent', $subject->get('myIdentifier'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsEmptyStringUnzipped(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -242,9 +225,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertSame('', $subject->get('myIdentifier'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasReturnsFalseIfNoCacheEntryExists(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -256,9 +237,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertFalse($subject->has('myIdentifier'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasReturnsFalseForExpiredCacheEntry(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -283,9 +262,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertFalse($subject->has('myIdentifier'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasReturnsNotExpiredCacheEntry(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -310,9 +287,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertTrue($subject->has('myIdentifier'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeReturnsFalseIfNoEntryHasBeenRemoved(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -324,9 +299,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertFalse($subject->remove('myIdentifier'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeReturnsTrueIfAnEntryHasBeenRemoved(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -351,9 +324,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertTrue($subject->remove('myIdentifier'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeRemovesCorrectEntriesFromDatabase(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -399,9 +370,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertSame(2, $tagsTableConnection->count('*', 'cache_pages_tags', ['identifier' => 'otherIdentifier']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findIdentifiersByTagReturnsIdentifierTaggedWithGivenTag(): void
     {
         $subject = $this->getSubjectObject();
@@ -411,27 +380,21 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertEquals(['idB' => 'idB', 'idC' => 'idC'], $subject->findIdentifiersByTag('tagC'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagWorksWithEmptyCacheTables(): void
     {
         $subject = $this->getSubjectObject();
         $subject->flushByTag('tagB');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagsWorksWithEmptyCacheTables(): void
     {
         $subject = $this->getSubjectObject();
         $subject->flushByTags(['tagB']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagRemovesCorrectRowsFromDatabase(): void
     {
         $subject = $this->getSubjectObject();
@@ -447,9 +410,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertSame(2, $tagsTableConnection->count('*', 'cache_pages_tags', ['identifier' => 'idC']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagsRemovesCorrectRowsFromDatabase(): void
     {
         $subject = $this->getSubjectObject();
@@ -465,18 +426,14 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertSame(0, $tagsTableConnection->count('*', 'cache_pages_tags', ['identifier' => 'idC']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function collectGarbageWorksWithEmptyTable(): void
     {
         $subject = $this->getSubjectObject();
         $subject->collectGarbage();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function collectGarbageRemovesCacheEntryWithExpiredLifetime(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -498,9 +455,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertSame(1, $cacheTableConnection->count('*', 'cache_pages', ['identifier' => 'idB']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function collectGarbageRemovesTagEntriesForCacheEntriesWithExpiredLifetime(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -522,9 +477,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertSame(2, $tagsTableConnection->count('*', 'cache_pages_tags', ['identifier' => 'idB']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function collectGarbageRemovesOrphanedTagEntriesFromTagsTable(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
@@ -564,9 +517,7 @@ final class Typo3DatabaseBackendTest extends FunctionalTestCase
         self::assertSame(0, $tagsTableConnection->count('*', 'cache_pages_tags', ['identifier' => 'idC']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushLeavesCacheAndTagsTableEmpty(): void
     {
         $frontendMock = $this->createMock(FrontendInterface::class);
diff --git a/typo3/sysext/core/Tests/Functional/Cache/Core/ClassAliasLoaderTest.php b/typo3/sysext/core/Tests/Functional/Cache/Core/ClassAliasLoaderTest.php
index 7594898c5a77..bb9a66b50997 100644
--- a/typo3/sysext/core/Tests/Functional/Cache/Core/ClassAliasLoaderTest.php
+++ b/typo3/sysext/core/Tests/Functional/Cache/Core/ClassAliasLoaderTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Cache\Core;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
 
@@ -28,9 +29,7 @@ final class ClassAliasLoaderTest extends FunctionalTestCase
         'typo3/sysext/core/Tests/Functional/Cache/Core/Fixtures/Extensions/aliases_test',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function aliasMapsFromExtensionsCanBeLoaded(): void
     {
         // @phpstan-ignore-next-line PHPStan does not know about class aliases.
diff --git a/typo3/sysext/core/Tests/Functional/Cache/Frontend/VariableFrontendTest.php b/typo3/sysext/core/Tests/Functional/Cache/Frontend/VariableFrontendTest.php
index 43643be2228a..e5c9455c587f 100644
--- a/typo3/sysext/core/Tests/Functional/Cache/Frontend/VariableFrontendTest.php
+++ b/typo3/sysext/core/Tests/Functional/Cache/Frontend/VariableFrontendTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Cache\Frontend;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend;
 use TYPO3\CMS\Core\Cache\Frontend\VariableFrontend;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -59,11 +61,8 @@ final class VariableFrontendTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider insertSerializedArrayIntoLobAndRetrieveItDataProvider
-     *
-     * @test
-     */
+    #[DataProvider('insertSerializedArrayIntoLobAndRetrieveItDataProvider')]
+    #[Test]
     public function insertSerializedArrayIntoLobAndRetrieveIt(
         array $expected,
         string $identifier,
diff --git a/typo3/sysext/core/Tests/Functional/Category/Collection/CategoryCollectionTest.php b/typo3/sysext/core/Tests/Functional/Category/Collection/CategoryCollectionTest.php
index 8860e585c99d..e00c3a5e107d 100644
--- a/typo3/sysext/core/Tests/Functional/Category/Collection/CategoryCollectionTest.php
+++ b/typo3/sysext/core/Tests/Functional/Category/Collection/CategoryCollectionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Category\Collection;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Category\Collection\CategoryCollection;
 use TYPO3\CMS\Core\Database\Connection;
 use TYPO3\CMS\Core\Utility\StringUtility;
@@ -49,9 +50,7 @@ final class CategoryCollectionTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/Fixtures/DataSet/categoryRelations.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function checkIfFromArrayMethodSetCorrectProperties(): void
     {
         $subject = new CategoryCollection('tx_test_test');
@@ -63,27 +62,21 @@ final class CategoryCollectionTest extends FunctionalTestCase
         self::assertEquals($this->collectionRecord['table_name'], $subject->getItemTableName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canCreateDummyCollection(): void
     {
         $collection = CategoryCollection::create($this->collectionRecord);
         self::assertInstanceOf(CategoryCollection::class, $collection);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canCreateDummyCollectionAndFillItems(): void
     {
         $collection = CategoryCollection::create($this->collectionRecord, true);
         self::assertInstanceOf(CategoryCollection::class, $collection);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getCollectedRecordsReturnsEmptyRecordSet(): void
     {
         $subject = new CategoryCollection('tx_test_test');
@@ -93,25 +86,19 @@ final class CategoryCollectionTest extends FunctionalTestCase
         self::assertEmpty($records);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isStorageTableNameEqualsToSysCategory(): void
     {
         self::assertEquals('sys_category', CategoryCollection::getStorageTableName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isStorageItemsFieldEqualsToItems(): void
     {
         self::assertEquals('items', CategoryCollection::getStorageItemsField());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canLoadADummyCollectionFromDatabase(): void
     {
         $collection = CategoryCollection::load(1, true, 'tx_test_test');
@@ -141,9 +128,7 @@ final class CategoryCollectionTest extends FunctionalTestCase
         self::assertEquals(6, $collection->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canLoadADummyCollectionFromDatabaseAndAddRecord(): void
     {
         $collection = CategoryCollection::load(1, true, 'tx_test_test');
@@ -159,9 +144,7 @@ final class CategoryCollectionTest extends FunctionalTestCase
         self::assertEquals(6, $collection->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canLoadADummyCollectionWithoutContentFromDatabase(): void
     {
         $collection = CategoryCollection::load(1, false, 'tx_test_test');
@@ -169,9 +152,7 @@ final class CategoryCollectionTest extends FunctionalTestCase
         self::assertEquals(0, $collection->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canLoadADummyCollectionFromDatabaseAfterRemoveOneRelation(): void
     {
         // Remove one relation
diff --git a/typo3/sysext/core/Tests/Functional/Command/CacheFlushCommandTest.php b/typo3/sysext/core/Tests/Functional/Command/CacheFlushCommandTest.php
index 13852e415cbb..e38cf476122b 100644
--- a/typo3/sysext/core/Tests/Functional/Command/CacheFlushCommandTest.php
+++ b/typo3/sysext/core/Tests/Functional/Command/CacheFlushCommandTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Command;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Cache\CacheManager;
 use TYPO3\CMS\Core\Configuration\SiteConfiguration;
 use TYPO3\CMS\Core\Core\Environment;
@@ -38,9 +39,7 @@ final class CacheFlushCommandTest extends AbstractCommandTestCase
         ],
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function cachesCanBeFlushed(): void
     {
         $containerBuilder = $this->get(ContainerBuilder::class);
@@ -71,9 +70,7 @@ final class CacheFlushCommandTest extends AbstractCommandTestCase
         self::assertGreaterThan(0, filemtime($diCacheFile));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function diCachesCanBeFlushed(): void
     {
         $containerBuilder = $this->get(ContainerBuilder::class);
@@ -90,9 +87,7 @@ final class CacheFlushCommandTest extends AbstractCommandTestCase
         self::assertFileDoesNotExist($diCacheFile);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function systemCachesCanBeFlushed(): void
     {
         $containerBuilder = $this->get(ContainerBuilder::class);
@@ -125,9 +120,7 @@ final class CacheFlushCommandTest extends AbstractCommandTestCase
         self::assertGreaterThan(0, filemtime($diCacheFile));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageCachesCanBeFlushed(): void
     {
         $containerBuilder = $this->get(ContainerBuilder::class);
diff --git a/typo3/sysext/core/Tests/Functional/Command/CacheWarmupCommandTest.php b/typo3/sysext/core/Tests/Functional/Command/CacheWarmupCommandTest.php
index 031a1ca57b88..2010ebbd3dae 100644
--- a/typo3/sysext/core/Tests/Functional/Command/CacheWarmupCommandTest.php
+++ b/typo3/sysext/core/Tests/Functional/Command/CacheWarmupCommandTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Command;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\DependencyInjection\ContainerBuilder;
 use TYPO3\CMS\Core\Package\PackageManager;
@@ -24,9 +25,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 final class CacheWarmupCommandTest extends AbstractCommandTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function cachesCanBeWarmed(): void
     {
         $containerBuilder = $this->get(ContainerBuilder::class);
@@ -41,9 +40,7 @@ final class CacheWarmupCommandTest extends AbstractCommandTestCase
         self::assertFileExists(Environment::getVarPath() . '/cache/code/core/sites-configuration.php');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function systemCachesCanBeWarmed(): void
     {
         $containerBuilder = $this->get(ContainerBuilder::class);
@@ -58,9 +55,7 @@ final class CacheWarmupCommandTest extends AbstractCommandTestCase
         self::assertFileExists(Environment::getVarPath() . '/cache/code/core/sites-configuration.php');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function diCachesDoesNotWarmSystemCaches(): void
     {
         $containerBuilder = $this->get(ContainerBuilder::class);
@@ -75,9 +70,7 @@ final class CacheWarmupCommandTest extends AbstractCommandTestCase
         self::assertFileDoesNotExist(Environment::getVarPath() . '/cache/code/core/sites-configuration.php');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function systemCachesCanBeWarmedIfCacheIsBroken(): void
     {
         $containerBuilder = $this->get(ContainerBuilder::class);
diff --git a/typo3/sysext/core/Tests/Functional/Command/CliCommandTest.php b/typo3/sysext/core/Tests/Functional/Command/CliCommandTest.php
index 12308cc5bdef..0026862fc333 100644
--- a/typo3/sysext/core/Tests/Functional/Command/CliCommandTest.php
+++ b/typo3/sysext/core/Tests/Functional/Command/CliCommandTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Command;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 
 final class CliCommandTest extends AbstractCommandTestCase
@@ -73,10 +75,8 @@ final class CliCommandTest extends AbstractCommandTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider commandTestDataProvider
-     */
+    #[DataProvider('commandTestDataProvider')]
+    #[Test]
     public function cliCommand(string $command, array $args, int $expectedExitCode): void
     {
         $result = $this->executeConsoleCommand($command, ...$args);
diff --git a/typo3/sysext/core/Tests/Functional/Configuration/FlexForm/FlexFormToolsTest.php b/typo3/sysext/core/Tests/Functional/Configuration/FlexForm/FlexFormToolsTest.php
index 155f89045dac..81cadfb4d0ab 100644
--- a/typo3/sysext/core/Tests/Functional/Configuration/FlexForm/FlexFormToolsTest.php
+++ b/typo3/sysext/core/Tests/Functional/Configuration/FlexForm/FlexFormToolsTest.php
@@ -18,6 +18,8 @@ declare(strict_types=1);
 namespace TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm;
 
 use Doctrine\DBAL\Result;
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Cache\CacheManager;
@@ -64,9 +66,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         GeneralUtility::setSingletonInstance(CacheManager::class, $cacheManagerMock);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierWithNoListenersReturnsDefault(): void
     {
         $subject = new FlexFormTools();
@@ -85,9 +85,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierWithNoOpListenerReturnsDefault(): void
     {
         $subject = new FlexFormTools();
@@ -118,9 +116,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierWithListenerReturnsThatListenersValue(): void
     {
         $subject = new FlexFormTools();
@@ -146,9 +142,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierWithModifyListenerCallsListener(): void
     {
         $subject = new FlexFormTools();
@@ -181,9 +175,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierThrowsExceptionIfDsIsNotAnArrayAndNoDsPointerField(): void
     {
         $fieldTca = [
@@ -197,9 +189,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', []);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierReturnsDefaultIfDsIsSetButNoDsPointerField(): void
     {
         $fieldTca = [
@@ -213,9 +203,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', []));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierThrowsExceptionsIfNoDsPointerFieldIsSetAndDefaultDoesNotExist(): void
     {
         $fieldTca = [
@@ -228,9 +216,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame('default', (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', []));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierThrowsExceptionIfPointerFieldStringHasMoreThanTwoFields(): void
     {
         $fieldTca = [
@@ -244,9 +230,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', []);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierThrowsExceptionIfPointerFieldWithStringSingleFieldDoesNotExist(): void
     {
         $fieldTca = [
@@ -263,9 +247,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierThrowsExceptionIfPointerFieldSWithTwoFieldsFirstDoesNotExist(): void
     {
         $fieldTca = [
@@ -282,9 +264,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierThrowsExceptionIfPointerFieldSWithTwoFieldsSecondDoesNotExist(): void
     {
         $fieldTca = [
@@ -301,9 +281,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierReturnsPointerFieldValueIfDataStructureExists(): void
     {
         $fieldTca = [
@@ -321,9 +299,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierReturnsDefaultIfPointerFieldValueDoesNotExist(): void
     {
         $fieldTca = [
@@ -341,9 +317,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierThrowsExceptionIfPointerFieldValueDoesNotExistAndDefaultToo(): void
     {
         $fieldTca = [
@@ -459,10 +433,8 @@ final class FlexFormToolsTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getDataStructureIdentifierReturnsValidNameForTwoFieldCombinationsDataProvider
-     */
+    #[DataProvider('getDataStructureIdentifierReturnsValidNameForTwoFieldCombinationsDataProvider')]
+    #[Test]
     public function getDataStructureIdentifierReturnsValidNameForTwoFieldCombinations(array $row, array $ds, string $expected): void
     {
         $fieldTca = [
@@ -474,9 +446,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierThrowsExceptionForTwoFieldsWithNoMatchAndNoDefault(): void
     {
         $fieldTca = [
@@ -497,9 +467,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierThrowsExceptionIfParentRowLookupFails(): void
     {
         $fieldTca = [
@@ -544,9 +512,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierThrowsExceptionIfParentRowsFormALoop(): void
     {
         $GLOBALS['BE_USER'] = new BackendUserAuthentication();
@@ -637,9 +603,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $initialRow);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierThrowsExceptionIfNoValidPointerFoundUntilRoot(): void
     {
         $GLOBALS['BE_USER'] = new BackendUserAuthentication();
@@ -730,9 +694,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $initialRow);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierThrowsExceptionIfNoValidPointerValueFound(): void
     {
         $fieldTca = [
@@ -748,9 +710,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierThrowsExceptionIfReservedPointerValueIsIntegerButDsFieldNameIsNotConfigured(): void
     {
         $fieldTca = [
@@ -766,9 +726,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierThrowsExceptionIfDsTableFieldIsMisconfigured(): void
     {
         $fieldTca = [
@@ -785,9 +743,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierReturnsValidIdentifierForPointerField(): void
     {
         $fieldTca = [
@@ -803,9 +759,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierReturnsValidIdentifierForParentLookup(): void
     {
         $GLOBALS['BE_USER'] = new BackendUserAuthentication();
@@ -895,9 +849,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $initialRow));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierReturnsValidIdentifierForParentLookupAndBreaksLoop(): void
     {
         $GLOBALS['BE_USER'] = new BackendUserAuthentication();
@@ -952,9 +904,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $initialRow));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierReturnsValidIdentifierForParentLookupAndPrefersSubField(): void
     {
         $GLOBALS['BE_USER'] = new BackendUserAuthentication();
@@ -1013,9 +963,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $initialRow));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierReturnsValidIdentifierForTableAndFieldPointer(): void
     {
         $fieldTca = [
@@ -1033,9 +981,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDataStructureIdentifierReturnsValidIdentifierForTableAndFieldPointerWithParentLookup(): void
     {
         $GLOBALS['BE_USER'] = new BackendUserAuthentication();
@@ -1095,9 +1041,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, (new FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $initialRow));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierThrowsExceptionWithEmptyString(): void
     {
         $this->expectException(InvalidIdentifierException::class);
@@ -1105,9 +1049,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->parseDataStructureByIdentifier('');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierThrowsExceptionOnInvalidJson(): void
     {
         $this->expectException(\RuntimeException::class);
@@ -1115,9 +1057,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->parseDataStructureByIdentifier('egon');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierRejectsInvalidInput(): void
     {
         $this->expectException(InvalidIdentifierException::class);
@@ -1125,9 +1065,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->parseDataStructureByIdentifier('{"some":"input"}');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierParsesDataStructureReturnedByEvent(): void
     {
         /** @var Container $container */
@@ -1155,9 +1093,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, (new FlexFormTools())->parseDataStructureByIdentifier($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierThrowsExceptionForInvalidSyntax(): void
     {
         $this->expectException(InvalidIdentifierException::class);
@@ -1165,9 +1101,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->parseDataStructureByIdentifier('{"type":"bernd"}');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierThrowsExceptionForIncompleteTcaSyntax(): void
     {
         $this->expectException(\RuntimeException::class);
@@ -1176,9 +1110,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->parseDataStructureByIdentifier($identifier);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierThrowsExceptionForInvalidTcaSyntaxPointer(): void
     {
         $this->expectException(InvalidIdentifierException::class);
@@ -1187,9 +1119,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->parseDataStructureByIdentifier($identifier);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierResolvesTcaSyntaxPointer(): void
     {
         $GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
@@ -1204,9 +1134,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, (new FlexFormTools())->parseDataStructureByIdentifier($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierThrowsExceptionForIncompleteRecordSyntax(): void
     {
         $this->expectException(\RuntimeException::class);
@@ -1215,9 +1143,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->parseDataStructureByIdentifier($identifier);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierResolvesRecordSyntaxPointer(): void
     {
         // Mocks for a lot of the database stack classes
@@ -1254,9 +1180,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, (new FlexFormTools())->parseDataStructureByIdentifier($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierThrowsExceptionIfDataStructureFileDoesNotExist(): void
     {
         $GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default']
@@ -1267,9 +1191,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->parseDataStructureByIdentifier($identifier);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierFetchesFromFile(): void
     {
         $GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default']
@@ -1296,9 +1218,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertEquals($expected, (new FlexFormTools())->parseDataStructureByIdentifier($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierThrowsExceptionForInvalidXmlStructure(): void
     {
         $GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
@@ -1314,9 +1234,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->parseDataStructureByIdentifier($identifier);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierThrowsExceptionIfStructureHasBothSheetAndRoot(): void
     {
         $GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
@@ -1331,9 +1249,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->parseDataStructureByIdentifier($identifier);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierCreatesDefaultSheet(): void
     {
         $GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
@@ -1374,9 +1290,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertEquals($expected, (new FlexFormTools())->parseDataStructureByIdentifier($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierResolvesExtReferenceForSingleSheets(): void
     {
         $GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
@@ -1410,9 +1324,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertEquals($expected, (new FlexFormTools())->parseDataStructureByIdentifier($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierResolvesExtReferenceForSingleSheetsWithFilePrefix(): void
     {
         $GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
@@ -1446,9 +1358,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertEquals($expected, (new FlexFormTools())->parseDataStructureByIdentifier($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierModifyEventManipulatesDataStructure(): void
     {
         $GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
@@ -1482,9 +1392,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertSame($expected, (new FlexFormTools())->parseDataStructureByIdentifier($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierPreparesCategoryField(): void
     {
         $GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
@@ -1548,9 +1456,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         self::assertEquals($expected, (new FlexFormTools())->parseDataStructureByIdentifier($identifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierThrowsExceptionOnInvalidCategoryRelationship(): void
     {
         $GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
@@ -1577,9 +1483,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->parseDataStructureByIdentifier($identifier);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierThrowsEsxceptionOnInvalidMaxitemsForOneToOne(): void
     {
         $GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
@@ -1607,9 +1511,7 @@ final class FlexFormToolsTest extends FunctionalTestCase
         (new FlexFormTools())->parseDataStructureByIdentifier($identifier);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseDataStructureByIdentifierThrowsExceptionOnInvalidMaxitems(): void
     {
         $GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
diff --git a/typo3/sysext/core/Tests/Functional/Configuration/Loader/YamlFileLoaderTest.php b/typo3/sysext/core/Tests/Functional/Configuration/Loader/YamlFileLoaderTest.php
index abbc1f10a9c0..3100e0472a76 100644
--- a/typo3/sysext/core/Tests/Functional/Configuration/Loader/YamlFileLoaderTest.php
+++ b/typo3/sysext/core/Tests/Functional/Configuration/Loader/YamlFileLoaderTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Configuration\Loader;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Log\AbstractLogger;
 use Psr\Log\LogLevel;
 use TYPO3\CMS\Core\Configuration\Loader\YamlFileLoader;
@@ -28,9 +29,8 @@ final class YamlFileLoaderTest extends FunctionalTestCase
 
     /**
      * Generic method to check if the load method returns an array from a YAML file
-     *
-     * @test
      */
+    #[Test]
     public function load(): void
     {
         $fileName = 'EXT:core/Tests/Functional/Configuration/Loader/Fixtures/Berta.yaml';
@@ -48,9 +48,8 @@ final class YamlFileLoaderTest extends FunctionalTestCase
 
     /**
      * Method checking for imports that they have been processed properly
-     *
-     * @test
      */
+    #[Test]
     public function loadWithAnImport(): void
     {
         $fileName = 'EXT:core/Tests/Functional/Configuration/Loader/Fixtures/LoadWithAnImport.yaml';
@@ -70,9 +69,8 @@ final class YamlFileLoaderTest extends FunctionalTestCase
 
     /**
      * Method checking for multiple imports that they have been loaded in the right order
-     *
-     * @test
      */
+    #[Test]
     public function loadWithMultipleImports(): void
     {
         $fileName = 'EXT:core/Tests/Functional/Configuration/Loader/Fixtures/LoadWithMultipleImports.yaml';
@@ -93,9 +91,8 @@ final class YamlFileLoaderTest extends FunctionalTestCase
 
     /**
      * Method checking for imports that they have been processed properly
-     *
-     * @test
      */
+    #[Test]
     public function loadWithImportAndRelativePaths(): void
     {
         $fileName = 'EXT:core/Tests/Functional/Configuration/Loader/Fixtures/LoadWithImportAndRelativeFiles.yaml';
@@ -115,9 +112,8 @@ final class YamlFileLoaderTest extends FunctionalTestCase
 
     /**
      * Method checking for placeholders
-     *
-     * @test
      */
+    #[Test]
     public function loadWithPlaceholders(): void
     {
         $fileName = 'EXT:core/Tests/Functional/Configuration/Loader/Fixtures/LoadWithPlaceholders.yaml';
@@ -140,9 +136,8 @@ final class YamlFileLoaderTest extends FunctionalTestCase
 
     /**
      * Method checking for nested placeholders
-     *
-     * @test
      */
+    #[Test]
     public function loadWithNestedPlaceholders(): void
     {
         $fileName = 'EXT:core/Tests/Functional/Configuration/Loader/Fixtures/LoadWithNestedPlaceholders.yaml';
@@ -166,9 +161,8 @@ final class YamlFileLoaderTest extends FunctionalTestCase
 
     /**
      * Method checking for imports with env vars that they have been processed properly
-     *
-     * @test
      */
+    #[Test]
     public function loadWithImportAndEnvVars(): void
     {
         $loader = new YamlFileLoader();
@@ -191,9 +185,8 @@ final class YamlFileLoaderTest extends FunctionalTestCase
 
     /**
      * Method checking for imports with placeholder values in the file name
-     *
-     * @test
      */
+    #[Test]
     public function loadWithImportAndPlaceholderInFileName(): void
     {
         $output = (new YamlFileLoader())->load('EXT:core/Tests/Functional/Configuration/Loader/Fixtures/Placeholder/Berta.yaml');
@@ -210,9 +203,8 @@ final class YamlFileLoaderTest extends FunctionalTestCase
 
     /**
      * Method checking for multiple imports via glob() call
-     *
-     * @test
      */
+    #[Test]
     public function loadWithGlobbedImports(): void
     {
         $output = (new YamlFileLoader())->load('EXT:core/Tests/Functional/Configuration/Loader/Fixtures/LoadWithGlobbedImports.yaml');
@@ -232,9 +224,8 @@ final class YamlFileLoaderTest extends FunctionalTestCase
 
     /**
      * Method checking for path traversal imports via glob() call
-     *
-     * @test
      */
+    #[Test]
     public function loadWithGlobbedImportsWithPathTraversalShouldFail(): void
     {
         $logger = new class () extends AbstractLogger {
diff --git a/typo3/sysext/core/Tests/Functional/Country/CountryTest.php b/typo3/sysext/core/Tests/Functional/Country/CountryTest.php
index 1151da8b3e98..a1d904c95dbc 100644
--- a/typo3/sysext/core/Tests/Functional/Country/CountryTest.php
+++ b/typo3/sysext/core/Tests/Functional/Country/CountryTest.php
@@ -17,15 +17,14 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Country;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Country\Country;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class CountryTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function countryLabelCanBeLocalized(): void
     {
         $languageServiceFactory = $this->get(LanguageServiceFactory::class);
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/CheckboxValidationTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/CheckboxValidationTest.php
index 41c2f53ecf16..16b0384f2b67 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/CheckboxValidationTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/CheckboxValidationTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Context\Context;
@@ -65,9 +66,7 @@ final class CheckboxValidationTest extends FunctionalTestCase
         Bootstrap::initializeLanguageObject();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validMaximumRecordsCheckedPermitsPersisting(): void
     {
         $actionService = new ActionService();
@@ -80,9 +79,7 @@ final class CheckboxValidationTest extends FunctionalTestCase
         self::assertEquals(1, $newContentRecord['tx_testdatahandler_checkbox_with_eval']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function violationOfMaximumRecordsCheckedResetsValueToZero(): void
     {
         $actionService = new ActionService();
@@ -98,9 +95,7 @@ final class CheckboxValidationTest extends FunctionalTestCase
         self::assertEquals(0, $newContentRecord['tx_testdatahandler_checkbox_with_eval']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validMaximumRecordsCheckedInPidPermitsPersisting(): void
     {
         $actionService = new ActionService();
@@ -113,9 +108,7 @@ final class CheckboxValidationTest extends FunctionalTestCase
         self::assertEquals(1, $newContentRecord['tx_testdatahandler_checkbox_with_eval']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function violationOfMaximumRecordsCheckedInPidResetsValueToZero(): void
     {
         $actionService = new ActionService();
@@ -131,9 +124,7 @@ final class CheckboxValidationTest extends FunctionalTestCase
         self::assertEquals(0, $newContentRecord['tx_testdatahandler_checkbox_with_eval']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function violationOfMaximumRecordsCheckedInWorkspaceResetsValueToZero(): void
     {
         $actionService = new ActionService();
@@ -148,9 +139,7 @@ final class CheckboxValidationTest extends FunctionalTestCase
         self::assertEquals(0, $newContentRecord['tx_testdatahandler_checkbox_with_eval']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function violationOfMaximumRecordsCheckedInPidInWorkspaceResetsValueToZero(): void
     {
         $actionService = new ActionService();
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DefaultValuesTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DefaultValuesTest.php
index 2df20c39238f..90f6d2175fcf 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DefaultValuesTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DefaultValuesTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
@@ -42,9 +43,7 @@ final class DefaultValuesTest extends AbstractDataHandlerActionTestCase
         $this->backendUser->workspace = 0;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function defaultValuesFromTCAForNewRecordsIsRespected(): void
     {
         $GLOBALS['TCA']['pages']['columns']['keywords']['config']['default'] = 'a few,random,keywords';
@@ -73,9 +72,7 @@ final class DefaultValuesTest extends AbstractDataHandlerActionTestCase
         self::assertEquals($newContentRecord['header'], $GLOBALS['TCA']['tt_content']['columns']['header']['config']['default']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function defaultValuesFromGlobalTSconfigForNewRecordsIsRespected(): void
     {
         ExtensionManagementUtility::addPageTSConfig('
@@ -105,9 +102,7 @@ TCAdefaults.tt_content.header = global space');
         self::assertEquals('global space', $newContentRecord['header']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function defaultValuesFromPageSpecificTSconfigForNewRecordsIsRespected(): void
     {
         ExtensionManagementUtility::addPageTSConfig('
@@ -144,9 +139,7 @@ TCAdefaults.tt_content.header = local space
         self::assertEquals('local space', $newContentRecord['header']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function defaultValueForNullTextfieldsIsConsidered(): void
     {
         // New content element without bodytext
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DeleteTranslatedSubpagesTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DeleteTranslatedSubpagesTest.php
index f273adf165d0..0028cba21089 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DeleteTranslatedSubpagesTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/DeleteTranslatedSubpagesTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\DataHandling\DataHandler;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -37,9 +38,7 @@ final class DeleteTranslatedSubpagesTest extends AbstractDataHandlerActionTestCa
         $this->backendUser->workspace = 0;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletePageCausesNoErrorsWithTranslatedSubpage(): void
     {
         $cmd = null;
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/GetUniqueTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/GetUniqueTest.php
index d8f94118148a..2a1bfd8a5897 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/GetUniqueTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/GetUniqueTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Crypto\Random;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\DataHandling\DataHandler;
@@ -54,10 +56,8 @@ final class GetUniqueTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getUniqueDataProvider
-     */
+    #[DataProvider('getUniqueDataProvider')]
+    #[Test]
     public function getUnique(string $value, string $expected): void
     {
         $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/GetUniqueTranslationTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/GetUniqueTranslationTest.php
index 8288e7a5e5f3..70bed4b72346 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/GetUniqueTranslationTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/GetUniqueTranslationTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 
@@ -38,9 +39,7 @@ final class GetUniqueTranslationTest extends AbstractDataHandlerActionTestCase
         $this->backendUser->workspace = 0;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function valueOfUniqueFieldExcludedInTranslationIsUntouchedInTranslation(): void
     {
         // Mis-using the "keywords" field in the scenario data-set to check for uniqueness
@@ -58,9 +57,7 @@ final class GetUniqueTranslationTest extends AbstractDataHandlerActionTestCase
         self::assertEquals('datahandler', $translatedRecord['keywords']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function valueOfUniqueFieldExcludedInTranslationIsUntouchedInOriginalLanguage(): void
     {
         // Mis-using the "nav_title" field in the scenario data-set to check for uniqueness
@@ -83,9 +80,7 @@ final class GetUniqueTranslationTest extends AbstractDataHandlerActionTestCase
         self::assertEquals('datahandler', $translatedRecord['nav_title']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function valueOfUniqueFieldExcludedInTranslationIsIncrementedInNewOriginalRecord(): void
     {
         // Mis-using the "nav_title" field in the scenario data-set to check for uniqueness
@@ -108,9 +103,7 @@ final class GetUniqueTranslationTest extends AbstractDataHandlerActionTestCase
         self::assertEquals('datahandler0', $newRecord['nav_title']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function valueOfUniqueFieldExcludedInTranslationIsIncrementedInNewTranslatedRecord(): void
     {
         // Mis-using the "nav_title" field in the scenario data-set to check for uniqueness
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/HookTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/HookTest.php
index 1522ff75a10d..8cda529691e9 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/HookTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/HookTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler\Fixtures\HookFixture;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -67,18 +68,14 @@ final class HookTest extends AbstractDataHandlerActionTestCase
         unset($this->hookFixture);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hooksAreExecutedForNewRecords(): void
     {
         $newTableIds = $this->actionService->createNewRecord(
@@ -105,9 +102,7 @@ final class HookTest extends AbstractDataHandlerActionTestCase
         ]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hooksAreExecutedForExistingRecords(): void
     {
         $this->actionService->modifyRecord(
@@ -133,9 +128,7 @@ final class HookTest extends AbstractDataHandlerActionTestCase
         ]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hooksAreExecutedForNewRelations(): void
     {
         $contentNewId = StringUtility::getUniqueId('NEW');
@@ -230,9 +223,7 @@ final class HookTest extends AbstractDataHandlerActionTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hooksAreExecutedForExistingRelations(): void
     {
         $this->actionService->modifyRecord(
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/SecurityTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/SecurityTest.php
index b4f5c8c3cbf9..81643b682d9c 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/SecurityTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/SecurityTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\WorkspaceAspect;
@@ -241,11 +243,9 @@ final class SecurityTest extends FunctionalTestCase
      * This test does not define any additional configuration, scope is to test
      * the factory-default configuration of TYPO3 when editing content via backend
      * user interface.
-     *
-     *
-     * @test
-     * @dataProvider crossSiteScriptingDataProvider
      */
+    #[DataProvider('crossSiteScriptingDataProvider')]
+    #[Test]
     public function markupIsSanitizedForContentBodytextWithHtmlSanitizerEnabled(string $input, array $expectations): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['security.backend.htmlSanitizeRte'] = true;
@@ -269,11 +269,9 @@ final class SecurityTest extends FunctionalTestCase
      * This test does not define any additional configuration, scope is to test
      * the factory-default configuration of TYPO3 when editing content via backend
      * user interface.
-     *
-     *
-     * @test
-     * @dataProvider crossSiteScriptingDataProvider
      */
+    #[DataProvider('crossSiteScriptingDataProvider')]
+    #[Test]
     public function markupIsSanitizedForContentBodytextWithHtmlSanitizerDisabled(string $input, array $expectations): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['security.backend.htmlSanitizeRte'] = false;
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/SelectCheckBoxTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/SelectCheckBoxTest.php
index f82b6c032dd2..266f7a86259f 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/SelectCheckBoxTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/SelectCheckBoxTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Core\Bootstrap;
@@ -36,9 +37,7 @@ final class SelectCheckBoxTest extends FunctionalTestCase
         Bootstrap::initializeLanguageObject();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validMultipleChecked(): void
     {
         $newUserRecord = $this->createBackendUser([
@@ -50,9 +49,7 @@ final class SelectCheckBoxTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validNoneCheckedEmptyValuesAllowed(): void
     {
         $newUserRecord = $this->createBackendUser(['file_permissions' => '']);
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/SlugUniqueTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/SlugUniqueTest.php
index 3a2a4d7de955..4d0d3f0d7f33 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/SlugUniqueTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/SlugUniqueTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\DataHandling\DataHandler;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -48,10 +50,8 @@ final class SlugUniqueTest extends AbstractDataHandlerActionTestCase
         ];
     }
 
-    /**
-     * @dataProvider getEvalSettingDataProvider
-     * @test
-     */
+    #[DataProvider('getEvalSettingDataProvider')]
+    #[Test]
     public function differentUniqueEvalSettingsDeDuplicateSlug(string $uniqueSetting): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/TestSlugUniqueBase.csv');
@@ -73,10 +73,8 @@ final class SlugUniqueTest extends AbstractDataHandlerActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/TestSlugUniqueResult.csv');
     }
 
-    /**
-     * @dataProvider getEvalSettingDataProvider
-     * @test
-     */
+    #[DataProvider('getEvalSettingDataProvider')]
+    #[Test]
     public function currentRecordIsExcludedWhenDeDuplicateSlug(string $uniqueSetting): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/TestSlugUniqueWithDeduplicatedSlugBase.csv');
@@ -98,10 +96,8 @@ final class SlugUniqueTest extends AbstractDataHandlerActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/TestSlugUniqueResult.csv');
     }
 
-    /**
-     * @dataProvider getEvalSettingDataProvider
-     * @test
-     */
+    #[DataProvider('getEvalSettingDataProvider')]
+    #[Test]
     public function differentUniqueEvalSettingsDeDuplicateSlugWhenCreatingNewRecords(string $uniqueSetting): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/TestSlugUniqueBase.csv');
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/TranslationDiffSourceTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/TranslationDiffSourceTest.php
index b7c42674aeec..5cb47ed0ee4a 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/TranslationDiffSourceTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/TranslationDiffSourceTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\DataHandler;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\History\RecordHistory;
 use TYPO3\CMS\Backend\History\RecordHistoryRollback;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
@@ -35,9 +36,7 @@ final class TranslationDiffSourceTest extends AbstractDataHandlerActionTestCase
         $this->backendUser->workspace = 0;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function transOrigDiffSourceFieldWrittenAfterTranslation(): void
     {
         $map = $this->actionService->localizeRecord('pages', self::PAGE_DATAHANDLER, 1);
@@ -51,9 +50,7 @@ final class TranslationDiffSourceTest extends AbstractDataHandlerActionTestCase
         self::assertEquals('DataHandlerTest', $transOrigDiffSourceField['title']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function transOrigDiffSourceNotUpdatedAfterUndo(): void
     {
         $map = $this->actionService->localizeRecord('pages', self::PAGE_DATAHANDLER, 1);
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/DataResolving/PlainDataResolverTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/DataResolving/PlainDataResolverTest.php
index 9abd4a216300..e1adbe35be48 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/DataResolving/PlainDataResolverTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/DataResolving/PlainDataResolverTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\DataResolving;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\DataHandling\PlainDataResolver;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 
@@ -121,10 +123,8 @@ final class PlainDataResolverTest extends AbstractDataHandlerActionTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider sortingDataProvider
-     */
+    #[DataProvider('sortingDataProvider')]
+    #[Test]
     public function processSortingReturnsExpectedSequenceOfUids(array $input, array $expected, array $sortings): void
     {
         $subject = new PlainDataResolver('pages', [], $sortings);
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Flexform/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/Flexform/ActionTest.php
index 11950997575e..c416d4b9c1cd 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/Flexform/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/Flexform/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\Flexform;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\Connection;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 
@@ -35,9 +36,7 @@ final class ActionTest extends AbstractDataHandlerActionTestCase
         $this->importCSVDataSet(__DIR__ . '/DataSet/LiveDefaultElements.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function transformationAppliesForRichTextFieldsWithoutSheets(): void
     {
         $GLOBALS['TCA']['tt_content']['columns']['pi_flexform']['config']['ds']['default'] = '<?xml version="1.0" encoding="UTF-8"?>
@@ -110,9 +109,7 @@ final class ActionTest extends AbstractDataHandlerActionTestCase
         self::assertEquals($expected, $flexFormContent);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function transformationAppliesForRichTextFieldsWithSheets(): void
     {
         $GLOBALS['TCA']['tt_content']['columns']['pi_flexform']['config']['ds']['default'] = '<T3DataStructure>
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/FlexformIrre/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/FlexformIrre/ActionTest.php
index 918cbc247dbe..8f7e0b4a97d5 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/FlexformIrre/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/FlexformIrre/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\FlexformIrre;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\Connection;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 
@@ -32,18 +33,14 @@ final class ActionTest extends AbstractDataHandlerActionTestCase
         'typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_irre_foreignfield',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function newVersionOfFileRelationInFlexformFieldIsCreatedOnSave(): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/ImportDefault.csv');
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/CheckValueTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/CheckValueTest.php
index 19ebe55dbe8c..7fa15df295aa 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/CheckValueTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/CheckValueTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\Regular;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 
@@ -35,9 +36,7 @@ final class CheckValueTest extends AbstractDataHandlerActionTestCase
         $this->importCSVDataSet(__DIR__ . '/DataSet/ImportDefault.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function radioButtonValueMustBeDefinedInTcaItems(): void
     {
         $record = $this->insertRecordWithRadioFieldValue('predefined value');
@@ -45,9 +44,7 @@ final class CheckValueTest extends AbstractDataHandlerActionTestCase
         self::assertEquals('predefined value', $record['tx_testdatahandler_radio']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function radioButtonValueMustComeFromItemsProcFuncIfNotDefinedInTcaItems(): void
     {
         $record = $this->insertRecordWithRadioFieldValue('processed value');
@@ -55,9 +52,7 @@ final class CheckValueTest extends AbstractDataHandlerActionTestCase
         self::assertEquals('processed value', $record['tx_testdatahandler_radio']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function radioButtonValueIsNotSavedIfNotDefinedInTcaItemsOrProcessingItems(): void
     {
         $record = $this->insertRecordWithRadioFieldValue('some other value');
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/CheckValueTestForCheckboxesTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/CheckValueTestForCheckboxesTest.php
index 0baf2a7fda3b..55100a56724a 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/CheckValueTestForCheckboxesTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/CheckValueTestForCheckboxesTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\Regular;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 
@@ -35,9 +36,7 @@ final class CheckValueTestForCheckboxesTest extends AbstractDataHandlerActionTes
         $this->importCSVDataSet(__DIR__ . '/DataSet/ImportDefault.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function checkBoxValueMustBeDefinedInTcaItems(): void
     {
         // pid 88 comes from ImportDefault
@@ -51,9 +50,7 @@ final class CheckValueTestForCheckboxesTest extends AbstractDataHandlerActionTes
         self::assertEquals(1, $record['tx_testdatahandler_checkbox']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function checkBoxValueMustComeFromItemsProcFuncIfNotDefinedInTcaItems(): void
     {
         // pid 88 comes from ImportDefault
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/CheckValueTestForSelectTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/CheckValueTestForSelectTest.php
index 9d9e29f00d16..b3c3eca57904 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/CheckValueTestForSelectTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/CheckValueTestForSelectTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\Regular;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 
@@ -35,9 +36,7 @@ final class CheckValueTestForSelectTest extends AbstractDataHandlerActionTestCas
         $this->importCSVDataSet(__DIR__ . '/DataSet/ImportDefault.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectValueMustBeDefinedInTcaItems(): void
     {
         // pid 88 comes from ImportDefault
@@ -51,9 +50,7 @@ final class CheckValueTestForSelectTest extends AbstractDataHandlerActionTestCas
         self::assertEquals('predefined value', $record['tx_testdatahandler_select_dynamic']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectValueMustComeFromItemsProcFuncIfNotDefinedInTcaItems(): void
     {
         // pid 88 comes from ImportDefault
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Hooks/PagesTsConfigGuardTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Hooks/PagesTsConfigGuardTest.php
index be2457e70906..9d461341722a 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Hooks/PagesTsConfigGuardTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Hooks/PagesTsConfigGuardTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\Regular\Hooks;
 
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\Yaml\Yaml;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Cache\CacheManager;
@@ -47,9 +48,7 @@ final class PagesTsConfigGuardTest extends FunctionalTestCase
             );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pagesTsConfigIsConsideredForAdminUser(): void
     {
         $backendUser = $this->setUpBackendUser(1);
@@ -71,9 +70,7 @@ final class PagesTsConfigGuardTest extends FunctionalTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/pagesTsConfigIsConsideredForAdminUser.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pagesTsConfigIsIgnoredForNonAdminUser(): void
     {
         $backendUser = $this->setUpBackendUser(9);
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/MinValueTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/MinValueTest.php
index ebb0e751279d..c63bbe5cb765 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/MinValueTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/MinValueTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\Regular;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\ActionService;
@@ -64,10 +66,8 @@ final class MinValueTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider valuesLowerThanMinResetToEmptyStringDataProvider
-     */
+    #[DataProvider('valuesLowerThanMinResetToEmptyStringDataProvider')]
+    #[Test]
     public function valuesLowerThanMinResetToEmptyString(string $string, string $expected): void
     {
         // Should work for type=input and type=text (except RTE).
@@ -82,9 +82,7 @@ final class MinValueTest extends FunctionalTestCase
         self::assertEquals($expected, $newRecord['tx_testdatahandler_text_minvalue']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function minDoesNotWorkForRTE(): void
     {
         $actionService = new ActionService();
@@ -96,9 +94,7 @@ final class MinValueTest extends FunctionalTestCase
         self::assertEquals('Not working', $newRecord['tx_testdatahandler_richttext_minvalue']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function minValueZeroIsIgnored(): void
     {
         $actionService = new ActionService();
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/MultiSite/MultiSiteTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/MultiSite/MultiSiteTest.php
index cd440622483b..cfced1dcc5ed 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/MultiSite/MultiSiteTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/MultiSite/MultiSiteTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\Regular\MultiSite;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Routing\SiteMatcher;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -43,10 +44,7 @@ final class MultiSiteTest extends AbstractDataHandlerActionTestCase
         $this->setUpFrontendSite(1, $this->siteLanguageConfiguration);
     }
 
-    /**
-     * @test
-     * See DataSet/moveRootPageToDifferentPageTree.csv
-     */
+    #[Test]
     public function moveRootPageToDifferentPageTree(): void
     {
         // Warm up caches for the root line utility to identify side effects
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/PagePermissionTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/PagePermissionTest.php
index 97df27dc0d12..d96474ffa193 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/PagePermissionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/PagePermissionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\Regular;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 use TYPO3\CMS\Core\Type\Bitmask\Permission;
@@ -36,9 +37,7 @@ final class PagePermissionTest extends AbstractDataHandlerActionTestCase
         $this->importCSVDataSet(__DIR__ . '/DataSet/ImportDefault.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function newPageReceivesDefaultPermissionSet(): void
     {
         $this->backendUser->user['uid'] = 13;
@@ -56,9 +55,7 @@ final class PagePermissionTest extends AbstractDataHandlerActionTestCase
         self::assertEquals(Permission::PAGE_SHOW, $record['perms_everybody']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function newPageReceivesOverriddenPageTsPermissionSet(): void
     {
         $this->backendUser->user['uid'] = 13;
@@ -83,9 +80,7 @@ TCEMAIN.permissions.everybody = show,delete
         self::assertEquals(Permission::PAGE_SHOW + Permission::PAGE_DELETE, $record['perms_everybody']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function newPageReceivesOverriddenPageTsPermissionSetFromParent()
     {
         $this->backendUser->user['uid'] = 13;
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Slug/SlugHelperTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/Slug/SlugHelperTest.php
index 6d9581b7b01e..8f40419addea 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/Slug/SlugHelperTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/Slug/SlugHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\Slug;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\DataHandling\SlugHelper;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -76,9 +78,7 @@ final class SlugHelperTest extends AbstractDataHandlerActionTestCase
         $this->setUpFrontendRootPage(1, ['typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
@@ -135,10 +135,8 @@ final class SlugHelperTest extends AbstractDataHandlerActionTestCase
         ];
     }
 
-    /**
-     * @dataProvider generateRespectsFallbackLanguageOfParentPageSlugDataProvider
-     * @test
-     */
+    #[DataProvider('generateRespectsFallbackLanguageOfParentPageSlugDataProvider')]
+    #[Test]
     public function generateRespectsFallbackLanguageOfParentPageSlug(string $expected, array $page): void
     {
         $slugHelper = GeneralUtility::makeInstance(
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Slug/SlugHelperUniqueTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/Slug/SlugHelperUniqueTest.php
index 5e2c3ded6e5d..4d2925f8e3c2 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/Slug/SlugHelperUniqueTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/Slug/SlugHelperUniqueTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\Slug;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\DataHandling\Model\RecordStateFactory;
 use TYPO3\CMS\Core\DataHandling\SlugHelper;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
@@ -37,9 +38,7 @@ final class SlugHelperUniqueTest extends AbstractDataHandlerActionTestCase
         $this->setUpFrontendRootPage(1, ['typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function buildSlugForUniqueInSiteRespectsMaxRetryOverflow(): void
     {
         $subject = GeneralUtility::makeInstance(
@@ -64,9 +63,7 @@ final class SlugHelperUniqueTest extends AbstractDataHandlerActionTestCase
         self::assertSame(32, strlen($variablePartOfSlug));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function buildSlugForUniqueInPidRespectsMaxRetryOverflow(): void
     {
         $subject = GeneralUtility::makeInstance(
@@ -90,9 +87,7 @@ final class SlugHelperUniqueTest extends AbstractDataHandlerActionTestCase
         self::assertSame(32, strlen($variablePartOfSlug));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function buildSlugForUniqueInTableRespectsMaxRetryOverflow(): void
     {
         $subject = GeneralUtility::makeInstance(
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Slug/SlugHelperUniqueWithLanguageTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/Slug/SlugHelperUniqueWithLanguageTest.php
index be1191c731f7..070e35e324b9 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/Slug/SlugHelperUniqueWithLanguageTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/Slug/SlugHelperUniqueWithLanguageTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataHandling\Slug;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\DataHandling\Model\RecordStateFactory;
 use TYPO3\CMS\Core\DataHandling\SlugHelper;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
@@ -83,10 +85,8 @@ final class SlugHelperUniqueWithLanguageTest extends AbstractDataHandlerActionTe
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider buildSlugForUniqueRespectsLanguageDataProvider
-     */
+    #[DataProvider('buildSlugForUniqueRespectsLanguageDataProvider')]
+    #[Test]
     public function buildSlugForUniqueRespectsLanguage(string $expectedSlug, array $recordData): void
     {
         $subject = GeneralUtility::makeInstance(
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/CategoryManyToMany/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/CategoryManyToMany/Modify/ActionTest.php
index e14563b5e3d0..85c44029e3bf 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/CategoryManyToMany/Modify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/CategoryManyToMany/Modify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\CategoryManyToMany\Modify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\CategoryManyToMany\AbstractActionTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
@@ -26,19 +27,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
  */
 final class ActionTest extends AbstractActionTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     * See DataSet/addCategoryRelation.csv
-     */
+    #[Test]
     public function addCategoryRelation(): void
     {
         parent::addCategoryRelation();
@@ -55,10 +51,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/addCategoryRelations.csv
-     */
+    #[Test]
     public function addCategoryRelations(): void
     {
         parent::addCategoryRelations();
@@ -75,10 +68,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/addCategoryRelationToExisting.csv
-     */
+    #[Test]
     public function addCategoryRelationToExisting(): void
     {
         parent::addCategoryRelationToExisting();
@@ -95,10 +85,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/addCategoryRelationsToExisting.csv
-     */
+    #[Test]
     public function addCategoryRelationsToExisting(): void
     {
         parent::addCategoryRelationsToExisting();
@@ -115,10 +102,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/createAndAddCategoryRelation.csv
-     */
+    #[Test]
     public function createAndAddCategoryRelation(): void
     {
         parent::createAndAddCategoryRelation();
@@ -148,10 +132,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/createAndReplaceCategoryRelation.csv
-     */
+    #[Test]
     public function createAndReplaceCategoryRelation(): void
     {
         parent::createAndReplaceCategoryRelation();
@@ -174,10 +155,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/addAndDeleteCategoryRelationsOnExisting.csv
-     */
+    #[Test]
     public function addAndDeleteCategoryRelationsOnExisting(): void
     {
         parent::addAndDeleteCategoryRelationsOnExisting();
@@ -194,10 +172,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/modifyReferencingContentElement.csv
-     */
+    #[Test]
     public function modifyReferencingContentElement(): void
     {
         parent::modifyReferencingContentElement();
@@ -213,10 +188,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/modifyContentOfRelatedCategory.csv
-     */
+    #[Test]
     public function modifyContentOfRelatedCategory(): void
     {
         parent::modifyContentOfRelatedCategory();
@@ -233,10 +205,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/deleteCategoryRelation.csv
-     */
+    #[Test]
     public function moveContentAndCategoryRelationToDifferentPage(): void
     {
         parent::moveContentAndCategoryRelationToDifferentPage();
@@ -253,10 +222,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/changeContentAndCategorySorting.csv
-     */
+    #[Test]
     public function changeContentAndCategorySorting(): void
     {
         parent::changeContentAndCategorySorting();
@@ -273,10 +239,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/deleteCategoryRelation.csv
-     */
+    #[Test]
     public function deleteCategoryRelation(): void
     {
         parent::deleteCategoryRelation();
@@ -300,10 +263,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/deleteCategoryRelations.csv
-     */
+    #[Test]
     public function deleteCategoryRelations(): void
     {
         parent::deleteCategoryRelations();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/CategoryOneToMany/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/CategoryOneToMany/Modify/ActionTest.php
index 4a7ef90903a5..6df3a4c1ad89 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/CategoryOneToMany/Modify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/CategoryOneToMany/Modify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\CategoryOneToMany\Modify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\CategoryOneToMany\AbstractActionTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
@@ -26,19 +27,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
  */
 final class ActionTest extends AbstractActionTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     * See DataSet/addCategoryRelation.csv
-     */
+    #[Test]
     public function addCategoryRelation(): void
     {
         parent::addCategoryRelation();
@@ -55,10 +51,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/addCategoryRelations.csv
-     */
+    #[Test]
     public function addCategoryRelations(): void
     {
         parent::addCategoryRelations();
@@ -75,10 +68,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/addCategoryRelationToExisting.csv
-     */
+    #[Test]
     public function addCategoryRelationToExisting(): void
     {
         parent::addCategoryRelationToExisting();
@@ -95,10 +85,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/addCategoryRelationsToExisting.csv
-     */
+    #[Test]
     public function addCategoryRelationsToExisting(): void
     {
         parent::addCategoryRelationsToExisting();
@@ -115,10 +102,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/createAndAddCategoryRelation.csv
-     */
+    #[Test]
     public function createAndAddCategoryRelation(): void
     {
         parent::createAndAddCategoryRelation();
@@ -148,10 +132,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/createAndReplaceCategoryRelation.csv
-     */
+    #[Test]
     public function createAndReplaceCategoryRelation(): void
     {
         parent::createAndReplaceCategoryRelation();
@@ -174,10 +155,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/addAndDeleteCategoryRelationsOnExisting.csv
-     */
+    #[Test]
     public function addAndDeleteCategoryRelationsOnExisting(): void
     {
         parent::addAndDeleteCategoryRelationsOnExisting();
@@ -194,10 +172,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/modifyReferencingContentElement.csv
-     */
+    #[Test]
     public function modifyReferencingContentElement(): void
     {
         parent::modifyReferencingContentElement();
@@ -213,10 +188,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/modifyContentOfRelatedCategory.csv
-     */
+    #[Test]
     public function modifyContentOfRelatedCategory(): void
     {
         parent::modifyContentOfRelatedCategory();
@@ -233,10 +205,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/deleteCategoryRelation.csv
-     */
+    #[Test]
     public function moveContentAndCategoryRelationToDifferentPage(): void
     {
         parent::moveContentAndCategoryRelationToDifferentPage();
@@ -253,10 +222,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/changeContentAndCategorySorting.csv
-     */
+    #[Test]
     public function changeContentAndCategorySorting(): void
     {
         parent::changeContentAndCategorySorting();
@@ -273,10 +239,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/deleteCategoryRelation.csv
-     */
+    #[Test]
     public function deleteCategoryRelation(): void
     {
         parent::deleteCategoryRelation();
@@ -300,10 +263,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/deleteCategoryRelations.csv
-     */
+    #[Test]
     public function deleteCategoryRelations(): void
     {
         parent::deleteCategoryRelations();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/CategoryOneToOne/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/CategoryOneToOne/Modify/ActionTest.php
index f986ca4b6287..c0b673746133 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/CategoryOneToOne/Modify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/CategoryOneToOne/Modify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\CategoryOneToOne\Modify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\CategoryOneToOne\AbstractActionTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
@@ -26,19 +27,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
  */
 final class ActionTest extends AbstractActionTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     * See DataSet/addCategoryRelation.csv
-     */
+    #[Test]
     public function addCategoryRelation(): void
     {
         parent::addCategoryRelation();
@@ -55,10 +51,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/createAndAddCategoryRelation.csv
-     */
+    #[Test]
     public function createAndAddCategoryRelation(): void
     {
         parent::createAndAddCategoryRelation();
@@ -81,10 +74,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/createAndReplaceCategoryRelation.csv
-     */
+    #[Test]
     public function createAndReplaceCategoryRelation(): void
     {
         parent::createAndReplaceCategoryRelation();
@@ -107,10 +97,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/changeExistingCategoryRelation.csv
-     */
+    #[Test]
     public function changeExistingCategoryRelation(): void
     {
         parent::changeExistingCategoryRelation();
@@ -127,10 +114,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/modifyReferencingContentElement.csv
-     */
+    #[Test]
     public function modifyReferencingContentElement(): void
     {
         parent::modifyReferencingContentElement();
@@ -146,10 +130,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/modifyContentOfRelatedCategory.csv
-     */
+    #[Test]
     public function modifyContentOfRelatedCategory(): void
     {
         parent::modifyContentOfRelatedCategory();
@@ -166,10 +147,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/moveContentAndCategoryRelationToDifferentPage.csv
-     */
+    #[Test]
     public function moveContentAndCategoryRelationToDifferentPage(): void
     {
         parent::moveContentAndCategoryRelationToDifferentPage();
@@ -186,10 +164,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/changeContentAndCategorySorting.csv
-     */
+    #[Test]
     public function changeContentAndCategorySorting(): void
     {
         parent::changeContentAndCategorySorting();
@@ -206,10 +181,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/copyContentAndCategoryRelation.csv
-     */
+    #[Test]
     public function copyContentAndCategoryRelation(): void
     {
         parent::copyContentAndCategoryRelation();
@@ -225,10 +197,7 @@ final class ActionTest extends AbstractActionTestCase
         );
     }
 
-    /**
-     * @test
-     * See DataSet/deleteCategoryRelation.csv
-     */
+    #[Test]
     public function deleteCategoryRelation(): void
     {
         parent::deleteCategoryRelation();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/ActionTest.php
index bbdc39649a01..3e0112bfa661 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\FAL\Modify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\FAL\AbstractActionTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
@@ -26,19 +27,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
  */
 final class ActionTest extends AbstractActionTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     * See DataSet/modifyContent.csv
-     */
+    #[Test]
     public function modifyContent(): void
     {
         parent::modifyContent();
@@ -53,10 +49,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD'));
     }
 
-    /**
-     * @test
-     * See DataSet/deleteContent.csv
-     */
+    #[Test]
     public function deleteContent(): void
     {
         parent::deleteContent();
@@ -70,10 +63,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyContent.csv
-     */
+    #[Test]
     public function copyContent(): void
     {
         parent::copyContent();
@@ -88,10 +78,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyContentToLanguage.csv
-     */
+    #[Test]
     public function copyContentToLanguage(): void
     {
         // Create translated page first
@@ -112,10 +99,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('[Translate to Dansk:] This is Kasper', '[Translate to Dansk:] Taken at T3BOARD'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContent.csv
-     */
+    #[Test]
     public function localizeContent(): void
     {
         parent::localizeContent();
@@ -131,10 +115,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('[Translate to Dansk:] This is Kasper', '[Translate to Dansk:] Taken at T3BOARD'));
     }
 
-    /**
-     * @test
-     * See DataSet/changeContentSorting.csv
-     */
+    #[Test]
     public function changeContentSorting(): void
     {
         parent::changeContentSorting();
@@ -152,10 +133,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD'));
     }
 
-    /**
-     * @test
-     * See DataSet/moveContentToDifferentPage.csv
-     */
+    #[Test]
     public function moveContentToDifferentPage(): void
     {
         parent::moveContentToDifferentPage();
@@ -177,10 +155,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD'));
     }
 
-    /**
-     * @test
-     * See DataSet/moveContentToDifferentPageNChangeSorting.csv
-     */
+    #[Test]
     public function moveContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveContentToDifferentPageAndChangeSorting();
@@ -198,14 +173,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD'));
     }
 
-    /**
-     * File references
-     */
-
-    /**
-     * @test
-     * See DataSets/createContentWFileReference.csv
-     */
+    #[Test]
     public function createContentWithFileReference(): void
     {
         parent::createContentWithFileReference();
@@ -220,10 +188,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Image #1'));
     }
 
-    /**
-     * @test
-     * See DataSets/modifyContentWFileReference.csv
-     */
+    #[Test]
     public function modifyContentWithFileReference(): void
     {
         parent::modifyContentWithFileReference();
@@ -238,10 +203,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD', 'Image #1'));
     }
 
-    /**
-     * @test
-     * See DataSets/modifyContentNAddFileReference.csv
-     */
+    #[Test]
     public function modifyContentAndAddFileReference(): void
     {
         parent::modifyContentAndAddFileReference();
@@ -254,10 +216,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD', 'This is Kasper', 'Image #3'));
     }
 
-    /**
-     * @test
-     * See DataSets/modifyContentNDeleteFileReference.csv
-     */
+    #[Test]
     public function modifyContentAndDeleteFileReference(): void
     {
         parent::modifyContentAndDeleteFileReference();
@@ -273,10 +232,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD'));
     }
 
-    /**
-     * @test
-     * See DataSets/modifyContentNDeleteAllFileReference.csv
-     */
+    #[Test]
     public function modifyContentAndDeleteAllFileReference(): void
     {
         parent::modifyContentAndDeleteAllFileReference();
@@ -289,9 +245,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD', 'This is Kasper'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentWithFileReferenceAndDeleteFileReference(): void
     {
         parent::createContentWithFileReferenceAndDeleteFileReference();
@@ -299,9 +253,7 @@ final class ActionTest extends AbstractActionTestCase
         // No FE test: Create and delete scenarios have FE coverage, this test is only about DB state.
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function creatingFileIsDenied(): void
     {
         $this->expectedErrorLogEntries = 1;
@@ -316,9 +268,7 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/sysFileUnchanged.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyingFileIsDenied(): void
     {
         $this->expectedErrorLogEntries = 1;
@@ -333,9 +283,7 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/sysFileUnchanged.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function usingLegacyStorageFileInFileReferenceIsDenied(): void
     {
         $this->expectedErrorLogEntries = 1;
@@ -345,9 +293,7 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/sysFileUnchanged.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function usingLegacyStorageFileInFileMetadataIsDenied(): void
     {
         $this->expectedErrorLogEntries = 1;
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/ActionTest.php
index 0ca3ebbf23ae..203f21834dd8 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\FAL\WorkspacesDiscard;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\FAL\AbstractActionWorkspacesTestCase;
 
 /**
@@ -24,18 +25,14 @@ use TYPO3\CMS\Core\Tests\Functional\DataScenarios\FAL\AbstractActionWorkspacesTe
  */
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContent(): void
     {
         parent::modifyContent();
@@ -43,9 +40,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContent(): void
     {
         parent::deleteContent();
@@ -53,9 +48,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContent(): void
     {
         parent::copyContent();
@@ -63,9 +56,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContent(): void
     {
         parent::localizeContent();
@@ -73,9 +64,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSorting(): void
     {
         parent::changeContentSorting();
@@ -83,9 +72,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changeContentSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPage(): void
     {
         $newRecordIds = parent::moveContentToDifferentPage();
@@ -93,9 +80,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveContentToDifferentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveContentToDifferentPageAndChangeSorting();
@@ -105,13 +90,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveContentToDifferentPageNChangeSorting.csv');
     }
 
-    /**
-     * File references
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentWithFileReference(): void
     {
         parent::createContentWithFileReference();
@@ -119,9 +98,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContentWFileReference.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentWithFileReference(): void
     {
         parent::modifyContentWithFileReference();
@@ -129,9 +106,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyContentWFileReference.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentAndAddFileReference(): void
     {
         parent::modifyContentAndAddFileReference();
@@ -139,9 +114,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyContentNAddFileReference.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentAndDeleteFileReference(): void
     {
         parent::modifyContentAndDeleteFileReference();
@@ -149,9 +122,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyContentNDeleteFileReference.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentAndDeleteAllFileReference(): void
     {
         parent::modifyContentAndDeleteAllFileReference();
@@ -159,9 +130,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyContentNDeleteAllFileReference.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentWithFileReferenceAndDeleteFileReference(): void
     {
         parent::createContentWithFileReferenceAndDeleteFileReference();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/ActionTest.php
index ba3968056623..37d70ba3943c 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\FAL\WorkspacesModify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\FAL\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -27,18 +28,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
  */
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContent(): void
     {
         parent::modifyContent();
@@ -56,9 +53,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContent(): void
     {
         parent::deleteContent();
@@ -75,9 +70,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContent(): void
     {
         parent::copyContent();
@@ -95,9 +88,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContent(): void
     {
         parent::localizeContent();
@@ -116,9 +107,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('[Translate to Dansk:] This is Kasper', '[Translate to Dansk:] Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSorting(): void
     {
         parent::changeContentSorting();
@@ -139,9 +128,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPage(): void
     {
         parent::moveContentToDifferentPage();
@@ -170,9 +157,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveContentToDifferentPageAndChangeSorting();
@@ -193,13 +178,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * File references
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentWithFileReference(): void
     {
         parent::createContentWithFileReference();
@@ -217,9 +196,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Image #1')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentWithFileReference(): void
     {
         parent::modifyContentWithFileReference();
@@ -237,9 +214,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD', 'Image #1')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentAndAddFileReference(): void
     {
         parent::modifyContentAndAddFileReference();
@@ -255,9 +230,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD', 'This is Kasper', 'Image #3')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentAndDeleteFileReference(): void
     {
         parent::modifyContentAndDeleteFileReference();
@@ -276,9 +249,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentAndDeleteAllFileReference(): void
     {
         parent::modifyContentAndDeleteAllFileReference();
@@ -294,9 +265,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD', 'This is Kasper'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentWithFileReferenceAndDeleteFileReference(): void
     {
         parent::createContentWithFileReferenceAndDeleteFileReference();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/ActionTest.php
index db34f8bb5d7c..c2fea1311132 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\FAL\WorkspacesPublish;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\FAL\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
@@ -26,18 +27,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
  */
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContent(): void
     {
         parent::modifyContent();
@@ -53,9 +50,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContent(): void
     {
         parent::deleteContent();
@@ -70,9 +65,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContent(): void
     {
         parent::copyContent();
@@ -88,9 +81,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContent(): void
     {
         parent::localizeContent();
@@ -108,9 +99,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('[Translate to Dansk:] This is Kasper', '[Translate to Dansk:] Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSorting(): void
     {
         parent::changeContentSorting();
@@ -129,9 +118,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPage(): void
     {
         parent::moveContentToDifferentPage();
@@ -154,9 +141,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveContentToDifferentPageAndChangeSorting();
@@ -179,13 +164,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * File references
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentWithFileReference(): void
     {
         parent::createContentWithFileReference();
@@ -201,9 +180,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Image #1')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentWithFileReference(): void
     {
         parent::modifyContentWithFileReference();
@@ -219,9 +196,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD', 'Image #1')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentAndAddFileReference(): void
     {
         parent::modifyContentAndAddFileReference();
@@ -235,9 +210,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD', 'This is Kasper', 'Image #3')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentAndDeleteFileReference(): void
     {
         parent::modifyContentAndDeleteFileReference();
@@ -254,9 +227,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentAndDeleteAllFileReference(): void
     {
         parent::modifyContentAndDeleteAllFileReference();
@@ -270,9 +241,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD', 'This is Kasper'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentWithFileReferenceAndDeleteFileReference(): void
     {
         parent::createContentWithFileReferenceAndDeleteFileReference();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/ActionTest.php
index 16c892cd85dd..c17b671243b0 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/ActionTest.php
@@ -17,24 +17,21 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\FAL\WorkspacesPublishAll;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\FAL\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContent(): void
     {
         parent::modifyContent();
@@ -50,9 +47,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContent(): void
     {
         parent::deleteContent();
@@ -67,9 +62,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContent(): void
     {
         parent::copyContent();
@@ -85,9 +78,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContent(): void
     {
         parent::localizeContent();
@@ -104,9 +95,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('[Translate to Dansk:] This is Kasper', '[Translate to Dansk:] Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSorting(): void
     {
         parent::changeContentSorting();
@@ -125,9 +114,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPage(): void
     {
         parent::moveContentToDifferentPage();
@@ -150,9 +137,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveContentToDifferentPageAndChangeSorting();
@@ -171,13 +156,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('This is Kasper', 'Taken at T3BOARD')->setStrict(true));
     }
 
-    /**
-     * File references
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentWithFileReference(): void
     {
         parent::createContentWithFileReference();
@@ -193,9 +172,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Image #1')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentWithFileReference(): void
     {
         parent::modifyContentWithFileReference();
@@ -211,9 +188,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD', 'Image #1')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentAndAddFileReference(): void
     {
         parent::modifyContentAndAddFileReference();
@@ -227,9 +202,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD', 'This is Kasper', 'Image #3')->setStrict(true));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentAndDeleteFileReference(): void
     {
         parent::modifyContentAndDeleteFileReference();
@@ -246,9 +219,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentAndDeleteAllFileReference(): void
     {
         parent::modifyContentAndDeleteAllFileReference();
@@ -262,9 +233,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_FileReference)->setField('title')->setValues('Taken at T3BOARD', 'This is Kasper'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentWithFileReferenceAndDeleteFileReference(): void
     {
         parent::createContentWithFileReferenceAndDeleteFileReference();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/Modify/ActionTest.php
index ae00b6edb6f9..6121653b9070 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/Modify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/Modify/ActionTest.php
@@ -17,31 +17,26 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\FlexSectionContainer\Modify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\FlexSectionContainer\AbstractActionTestCase;
 
 final class ActionTest extends AbstractActionTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteSection(): void
     {
         parent::deleteSection();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteSection.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeSorting(): void
     {
         parent::changeSorting();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesDiscard/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesDiscard/ActionTest.php
index 73596503cece..e2b41bfcf456 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesDiscard/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesDiscard/ActionTest.php
@@ -17,22 +17,19 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\FlexSectionContainer\WorkspacesDiscard;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\FlexSectionContainer\AbstractActionWorkspacesTestCase;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteSection(): void
     {
         parent::deleteSection();
@@ -40,9 +37,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteSection.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeSorting(): void
     {
         parent::changeSorting();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesModify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesModify/ActionTest.php
index 28071d2248a2..d686960cae19 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesModify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesModify/ActionTest.php
@@ -17,31 +17,26 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\FlexSectionContainer\WorkspacesModify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\FlexSectionContainer\AbstractActionWorkspacesTestCase;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteSection(): void
     {
         parent::deleteSection();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteSection.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeSorting(): void
     {
         parent::changeSorting();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesPublish/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesPublish/ActionTest.php
index 3b79a75f76ca..6bea3f921882 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesPublish/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesPublish/ActionTest.php
@@ -17,22 +17,19 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\FlexSectionContainer\WorkspacesPublish;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\FlexSectionContainer\AbstractActionWorkspacesTestCase;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteSection(): void
     {
         parent::deleteSection();
@@ -40,9 +37,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteSection.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeSorting(): void
     {
         parent::changeSorting();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesPublishAll/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesPublishAll/ActionTest.php
index 49929fc8f5c8..ea1c34f46b0e 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesPublishAll/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FlexSectionContainer/WorkspacesPublishAll/ActionTest.php
@@ -17,22 +17,19 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\FlexSectionContainer\WorkspacesPublishAll;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\FlexSectionContainer\AbstractActionWorkspacesTestCase;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteSection(): void
     {
         parent::deleteSection();
@@ -40,9 +37,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteSection.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeSorting(): void
     {
         parent::changeSorting();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/Group/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/Group/Modify/ActionTest.php
index a75631e2b23d..c56147a4a56d 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/Group/Modify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/Group/Modify/ActionTest.php
@@ -17,25 +17,21 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\Group\Modify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\Group\AbstractActionTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     * See DataSet/addElementRelation.csv
-     */
+    #[Test]
     public function addElementRelation(): void
     {
         parent::addElementRelation();
@@ -48,10 +44,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     * See DataSet/deleteElementRelation.csv
-     */
+    #[Test]
     public function deleteElementRelation(): void
     {
         parent::deleteElementRelation();
@@ -67,10 +60,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     * See DataSet/changeElementSorting.csv
-     */
+    #[Test]
     public function changeElementSorting(): void
     {
         parent::changeElementSorting();
@@ -83,10 +73,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/changeElementRelationSorting.csv
-     */
+    #[Test]
     public function changeElementRelationSorting(): void
     {
         parent::changeElementRelationSorting();
@@ -99,10 +86,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/createContentNAddRelation.csv
-     */
+    #[Test]
     public function createContentAndAddElementRelation(): void
     {
         parent::createContentAndAddElementRelation();
@@ -117,9 +101,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCreateElementRelation(): void
     {
         parent::createContentAndCreateElementRelation();
@@ -134,10 +116,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyElementOfRelation.csv
-     */
+    #[Test]
     public function modifyElementOfRelation(): void
     {
         parent::modifyElementOfRelation();
@@ -150,10 +129,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyContentOfRelation.csv
-     */
+    #[Test]
     public function modifyContentOfRelation(): void
     {
         parent::modifyContentOfRelation();
@@ -165,10 +141,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyBothSidesOfRelation.csv
-     */
+    #[Test]
     public function modifyBothSidesOfRelation(): void
     {
         parent::modifyBothSidesOfRelation();
@@ -183,10 +156,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/deleteContentOfRelation.csv
-     */
+    #[Test]
     public function deleteContentOfRelation(): void
     {
         parent::deleteContentOfRelation();
@@ -198,10 +168,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/deleteElementOfRelation.csv
-     */
+    #[Test]
     public function deleteElementOfRelation(): void
     {
         parent::deleteElementOfRelation();
@@ -214,10 +181,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyContentOfRelation.csv
-     */
+    #[Test]
     public function copyContentOfRelation(): void
     {
         parent::copyContentOfRelation();
@@ -231,10 +195,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyElementOfRelation.csv
-     */
+    #[Test]
     public function copyElementOfRelation(): void
     {
         parent::copyElementOfRelation();
@@ -251,10 +212,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1 (copy 1)'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyContentToLanguageOfRelation.csv
-     */
+    #[Test]
     public function copyContentToLanguageOfRelation(): void
     {
         // Create translated page first
@@ -276,10 +234,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyElementToLanguageOfRelation.csv
-     */
+    #[Test]
     public function copyElementToLanguageOfRelation(): void
     {
         parent::copyElementToLanguageOfRelation();
@@ -294,10 +249,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentOfRelation.csv
-     */
+    #[Test]
     public function localizeContentOfRelation(): void
     {
         parent::localizeContentOfRelation();
@@ -310,10 +262,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentOfRelationWSynchronization.csv
-     */
+    #[Test]
     public function localizeContentOfRelationWithLanguageSynchronization(): void
     {
         parent::localizeContentOfRelationWithLanguageSynchronization();
@@ -326,19 +275,14 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLocalizeReferencesAtParentLocalization()
     {
         parent::localizeContentOfRelationWithLocalizeReferencesAtParentLocalization();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentOfRelationWLocalizeReferencesAtParentLocalization.csv');
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentChainOfRelationWSynchronizationSource.csv
-     */
+    #[Test]
     public function localizeContentChainOfRelationWithLanguageSynchronizationSource(): void
     {
         parent::localizeContentChainOfRelationWithLanguageSynchronizationSource();
@@ -351,10 +295,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeElementOfRelation.csv
-     */
+    #[Test]
     public function localizeElementOfRelation(): void
     {
         // Create translated page first
@@ -369,10 +310,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('[Translate to Dansk:] Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/moveContentOfRelationToDifferentPage.csv
-     */
+    #[Test]
     public function moveContentOfRelationToDifferentPage(): void
     {
         parent::moveContentOfRelationToDifferentPage();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesDiscard/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesDiscard/ActionTest.php
index 6b42b0ab25b4..f309d52f9bb1 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesDiscard/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesDiscard/ActionTest.php
@@ -17,22 +17,19 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\Group\WorkspacesDiscard;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\Group\AbstractActionWorkspacesTestCase;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addElementRelation(): void
     {
         parent::addElementRelation();
@@ -40,9 +37,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/addElementRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementRelation(): void
     {
         parent::deleteElementRelation();
@@ -50,9 +45,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteElementRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementSorting(): void
     {
         parent::changeElementSorting();
@@ -60,9 +53,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changeElementSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementRelationSorting(): void
     {
         parent::changeElementRelationSorting();
@@ -70,9 +61,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changeElementRelationSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndAddElementRelation(): void
     {
         parent::createContentAndAddElementRelation();
@@ -80,10 +69,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContentNAddRelation.csv');
     }
 
-    /**
-     * @test
-     * Special discard case of createContentAndCreateElementRelation from Modify
-     */
+    #[Test]
     public function createContentAndCreateElementRelationAndDiscardElement(): void
     {
         $this->createContentAndCreateElementRelation();
@@ -91,10 +77,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContentNCreateRelationNDiscardElement.csv');
     }
 
-    /**
-     * @test
-     * Special discard case for createContentAndCreateElementRelation from Modify
-     */
+    #[Test]
     public function createContentAndCreateElementRelationAndDiscardContent(): void
     {
         $this->createContentAndCreateElementRelation();
@@ -102,9 +85,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContentNCreateRelationNDiscardContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyElementOfRelation(): void
     {
         parent::modifyElementOfRelation();
@@ -112,9 +93,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyElementOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentOfRelation(): void
     {
         parent::modifyContentOfRelation();
@@ -122,9 +101,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyContentOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyBothSidesOfRelation(): void
     {
         parent::modifyBothSidesOfRelation();
@@ -135,9 +112,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyBothSidesOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentOfRelation(): void
     {
         parent::deleteContentOfRelation();
@@ -145,9 +120,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteContentOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementOfRelation(): void
     {
         parent::deleteElementOfRelation();
@@ -155,9 +128,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteElementOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentOfRelation(): void
     {
         parent::copyContentOfRelation();
@@ -165,9 +136,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyContentOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyElementOfRelation(): void
     {
         parent::copyElementOfRelation();
@@ -175,9 +144,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyElementOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelation(): void
     {
         parent::localizeContentOfRelation();
@@ -185,9 +152,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeElementOfRelation(): void
     {
         // Create translated page first
@@ -197,9 +162,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeElementOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentOfRelationToDifferentPage(): void
     {
         parent::moveContentOfRelationToDifferentPage();
@@ -207,9 +170,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveContentOfRelationToDifferentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLocalizeReferencesAtParentLocalization()
     {
         parent::localizeContentOfRelationWithLocalizeReferencesAtParentLocalization();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesModify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesModify/ActionTest.php
index ce83c3ee8a76..22dacba765e6 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesModify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesModify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\Group\WorkspacesModify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\Group\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -24,18 +25,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addElementRelation(): void
     {
         parent::addElementRelation();
@@ -51,9 +48,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementRelation(): void
     {
         parent::deleteElementRelation();
@@ -72,9 +67,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementSorting(): void
     {
         parent::changeElementSorting();
@@ -90,9 +83,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementRelationSorting(): void
     {
         parent::changeElementRelationSorting();
@@ -108,9 +99,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndAddElementRelation(): void
     {
         parent::createContentAndAddElementRelation();
@@ -128,9 +117,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCreateElementRelation(): void
     {
         parent::createContentAndCreateElementRelation();
@@ -148,9 +135,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyElementOfRelation(): void
     {
         parent::modifyElementOfRelation();
@@ -166,9 +151,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentOfRelation(): void
     {
         parent::modifyContentOfRelation();
@@ -183,9 +166,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyBothSidesOfRelation(): void
     {
         parent::modifyBothSidesOfRelation();
@@ -203,9 +184,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentOfRelation(): void
     {
         parent::deleteContentOfRelation();
@@ -220,9 +199,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementOfRelation(): void
     {
         parent::deleteElementOfRelation();
@@ -238,9 +215,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentOfRelation(): void
     {
         parent::copyContentOfRelation();
@@ -257,9 +232,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyElementOfRelation(): void
     {
         parent::copyElementOfRelation();
@@ -279,9 +252,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1 (copy 1)'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelation(): void
     {
         parent::localizeContentOfRelation();
@@ -297,9 +268,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeElementOfRelation(): void
     {
         // Create translated page first
@@ -317,9 +286,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('[Translate to Dansk:] Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentOfRelationToDifferentPage(): void
     {
         parent::moveContentOfRelationToDifferentPage();
@@ -335,9 +302,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLocalizeReferencesAtParentLocalization()
     {
         parent::localizeContentOfRelationWithLocalizeReferencesAtParentLocalization();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesPublish/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesPublish/ActionTest.php
index a8614bc7a338..c72ba07a7c64 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesPublish/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesPublish/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\Group\WorkspacesPublish;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\Group\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -24,18 +25,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addElementRelation(): void
     {
         parent::addElementRelation();
@@ -52,9 +49,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementRelation(): void
     {
         parent::deleteElementRelation();
@@ -74,9 +69,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementSorting(): void
     {
         parent::changeElementSorting();
@@ -90,9 +83,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementRelationSorting(): void
     {
         parent::changeElementRelationSorting();
@@ -109,9 +100,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndAddElementRelation(): void
     {
         parent::createContentAndAddElementRelation();
@@ -130,9 +119,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCreateElementRelation(): void
     {
         parent::createContentAndCreateElementRelation();
@@ -154,9 +141,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyElementOfRelation(): void
     {
         parent::modifyElementOfRelation();
@@ -173,9 +158,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentOfRelation(): void
     {
         parent::modifyContentOfRelation();
@@ -191,9 +174,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyBothSidesOfRelation(): void
     {
         parent::modifyBothSidesOfRelation();
@@ -215,9 +196,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentOfRelation(): void
     {
         parent::deleteContentOfRelation();
@@ -233,9 +212,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementOfRelation(): void
     {
         parent::deleteElementOfRelation();
@@ -252,9 +229,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentOfRelation(): void
     {
         parent::copyContentOfRelation();
@@ -272,9 +247,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyElementOfRelation(): void
     {
         parent::copyElementOfRelation();
@@ -295,9 +268,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1 (copy 1)'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelation(): void
     {
         parent::localizeContentOfRelation();
@@ -314,9 +285,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeElementOfRelation(): void
     {
         // Create and publish translated page first
@@ -336,9 +305,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('[Translate to Dansk:] Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentOfRelationToDifferentPage(): void
     {
         parent::moveContentOfRelationToDifferentPage();
@@ -355,9 +322,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLocalizeReferencesAtParentLocalization()
     {
         parent::localizeContentOfRelationWithLocalizeReferencesAtParentLocalization();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesPublishAll/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesPublishAll/ActionTest.php
index 638b9a8d579e..93e7411b9296 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesPublishAll/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/Group/WorkspacesPublishAll/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\Group\WorkspacesPublishAll;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\Group\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -24,18 +25,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addElementRelation(): void
     {
         parent::addElementRelation();
@@ -52,9 +49,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementRelation(): void
     {
         parent::deleteElementRelation();
@@ -74,9 +69,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementSorting(): void
     {
         parent::changeElementSorting();
@@ -90,9 +83,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementRelationSorting(): void
     {
         parent::changeElementRelationSorting();
@@ -109,9 +100,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndAddElementRelation(): void
     {
         parent::createContentAndAddElementRelation();
@@ -130,9 +119,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCreateElementRelation(): void
     {
         parent::createContentAndCreateElementRelation();
@@ -151,9 +138,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyElementOfRelation(): void
     {
         parent::modifyElementOfRelation();
@@ -170,9 +155,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentOfRelation(): void
     {
         parent::modifyContentOfRelation();
@@ -188,9 +171,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyBothSidesOfRelation(): void
     {
         parent::modifyBothSidesOfRelation();
@@ -209,9 +190,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentOfRelation(): void
     {
         parent::deleteContentOfRelation();
@@ -227,9 +206,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementOfRelation(): void
     {
         parent::deleteElementOfRelation();
@@ -246,9 +223,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentOfRelation(): void
     {
         parent::copyContentOfRelation();
@@ -266,9 +241,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyElementOfRelation(): void
     {
         parent::copyElementOfRelation();
@@ -289,9 +262,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1 (copy 1)'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelation(): void
     {
         parent::localizeContentOfRelation();
@@ -308,9 +279,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeElementOfRelation(): void
     {
         // Create translated page first
@@ -329,9 +298,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('[Translate to Dansk:] Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentOfRelationToDifferentPage(): void
     {
         parent::moveContentOfRelationToDifferentPage();
@@ -348,9 +315,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLocalizeReferencesAtParentLocalization()
     {
         parent::localizeContentOfRelationWithLocalizeReferencesAtParentLocalization();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/Modify/ActionTest.php
index 72a43da4a5a2..3d8a79bb106f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/Modify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/Modify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreCsv\Modify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreCsv\AbstractActionTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
@@ -26,19 +27,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
  */
 final class ActionTest extends AbstractActionTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     * See DataSet/createParentContentRecord.csv
-     */
+    #[Test]
     public function createParentContent(): void
     {
         parent::createParentContent();
@@ -50,10 +46,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyParentContentRecord.csv
-     */
+    #[Test]
     public function modifyParentContent(): void
     {
         parent::modifyParentContent();
@@ -68,10 +61,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/deleteParentContentRecord.csv
-     */
+    #[Test]
     public function deleteParentContent(): void
     {
         parent::deleteParentContent();
@@ -83,10 +73,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyParentContentRecord.csv
-     */
+    #[Test]
     public function copyParentContent(): void
     {
         parent::copyParentContent();
@@ -99,10 +86,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyParentContentToDifferentPage.csv
-     */
+    #[Test]
     public function copyParentContentToDifferentPage(): void
     {
         parent::copyParentContentToDifferentPage();
@@ -115,10 +99,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyParentContentToLanguageWithAllChildren.csv
-     */
+    #[Test]
     public function copyParentContentToLanguageWithAllChildren(): void
     {
         parent::copyParentContentToLanguageWithAllChildren();
@@ -136,10 +117,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeParentContentWAllChildren.csv
-     */
+    #[Test]
     public function localizeParentContentWithAllChildren(): void
     {
         // Create translated page first
@@ -155,10 +133,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeParentContentLanguageSynchronization.csv
-     */
+    #[Test]
     public function localizeParentContentWithLanguageSynchronization(): void
     {
         // Create translated page first
@@ -174,10 +149,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1', '[Translate to Dansk:] Hotel #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/changeParentContentRecordSorting.csv
-     */
+    #[Test]
     public function changeParentContentSorting(): void
     {
         parent::changeParentContentSorting();
@@ -193,10 +165,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/moveParentContentRecordToDifferentPage.csv
-     */
+    #[Test]
     public function moveParentContentToDifferentPage(): void
     {
         parent::moveParentContentToDifferentPage();
@@ -211,10 +180,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/moveParentContentRecordToDifferentPageAndChangeSorting.csv
-     */
+    #[Test]
     public function moveParentContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveParentContentToDifferentPageAndChangeSorting();
@@ -232,14 +198,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     * See DataSet/modifyPageRecord.csv
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
@@ -251,10 +210,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/deletePageRecord.csv
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -264,10 +220,7 @@ final class ActionTest extends AbstractActionTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     * See DataSet/copyPageRecord.csv
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
@@ -279,10 +232,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyPageWHotelBeforeParentContent.csv
-     */
+    #[Test]
     public function copyPageWithHotelBeforeParentContent(): void
     {
         parent::copyPageWithHotelBeforeParentContent();
@@ -294,14 +244,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * IRRE Child Records
-     */
-
-    /**
-     * @test
-     * See DataSet/createParentContentRecordWithHotelAndOfferChildRecords.csv
-     */
+    #[Test]
     public function createParentContentWithHotelAndOfferChildren(): void
     {
         parent::createParentContentWithHotelAndOfferChildren();
@@ -316,10 +259,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/createAndCopyParentContentRecordWithHotelAndOfferChildRecords.csv
-     */
+    #[Test]
     public function createAndCopyParentContentWithHotelAndOfferChildren(): void
     {
         parent::createAndCopyParentContentWithHotelAndOfferChildren();
@@ -338,10 +278,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('Offer #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/createAndLocalizeParentContentRecordWithHotelAndOfferChildRecords.csv
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildren(): void
     {
         // Create translated page first
@@ -362,10 +299,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('[Translate to Dansk:] Offer #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyOnlyHotelChildRecord.csv
-     */
+    #[Test]
     public function modifyOnlyHotelChild(): void
     {
         parent::modifyOnlyHotelChild();
@@ -378,10 +312,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyParentRecordAndChangeHotelChildRecordsSorting.csv
-     */
+    #[Test]
     public function modifyParentAndChangeHotelChildrenSorting(): void
     {
         parent::modifyParentAndChangeHotelChildrenSorting();
@@ -394,10 +325,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyParentRecordWithHotelChildRecord.csv
-     */
+    #[Test]
     public function modifyParentWithHotelChild(): void
     {
         parent::modifyParentWithHotelChild();
@@ -410,10 +338,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyParentRecordAndAddHotelChildRecord.csv
-     */
+    #[Test]
     public function modifyParentAndAddHotelChild(): void
     {
         parent::modifyParentAndAddHotelChild();
@@ -426,10 +351,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyParentRecordAndDeleteHotelChildRecord.csv
-     */
+    #[Test]
     public function modifyParentAndDeleteHotelChild(): void
     {
         parent::modifyParentAndDeleteHotelChild();
@@ -445,10 +367,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageWExclude.csv
-     */
+    #[Test]
     public function localizePageWithLocalizationExclude(): void
     {
         parent::localizePageWithLocalizationExclude();
@@ -461,10 +380,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #0'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageTwiceWExclude.csv
-     */
+    #[Test]
     public function localizePageTwiceWithLocalizationExclude(): void
     {
         parent::localizePageTwiceWithLocalizationExclude();
@@ -477,10 +393,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #0'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageNAddHotelChildWExclude.csv
-     */
+    #[Test]
     public function localizePageAndAddHotelChildWithLocalizationExclude(): void
     {
         parent::localizePageAndAddHotelChildWithLocalizationExclude();
@@ -493,10 +406,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #0', 'Hotel #007'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageWSynchronization.csv
-     */
+    #[Test]
     public function localizePageWithLanguageSynchronization(): void
     {
         parent::localizePageWithLanguageSynchronization();
@@ -509,10 +419,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #0'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageNAddHotelChildWSynchronization.csv
-     */
+    #[Test]
     public function localizePageAndAddHotelChildWithLanguageSynchronization(): void
     {
         parent::localizePageAndAddHotelChildWithLanguageSynchronization();
@@ -525,10 +432,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #0', '[Translate to Dansk:] Hotel #007'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageNAddMonoglotHotelChildWSynchronization.csv
-     */
+    #[Test]
     public function localizePageAndAddMonoglotHotelChildWithLanguageSynchronization(): void
     {
         parent::localizePageAndAddMonoglotHotelChildWithLanguageSynchronization();
@@ -541,10 +445,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #0', 'Hotel #007'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeNCopyPageWSynchronization.csv
-     */
+    #[Test]
     public function localizeAndCopyPageWithLanguageSynchronization(): void
     {
         parent::localizeAndCopyPageWithLanguageSynchronization();
@@ -560,10 +461,8 @@ final class ActionTest extends AbstractActionTestCase
     /**
      * Checks for a page having an IRRE record. The page is then localized and
      * an IRRE record is then added to the localized page
-     *
-     * @test
-     * See DataSet/localizePageWithSynchronizationAndCustomLocalizedHotel.csv
      */
+    #[Test]
     public function localizePageWithSynchronizationAndCustomLocalizedHotel(): void
     {
         parent::localizePageWithSynchronizationAndCustomLocalizedHotel();
@@ -576,10 +475,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #0'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageAddMonoglotHotelChildNCopyPageWSynchronization.csv
-     */
+    #[Test]
     public function localizePageAddMonoglotHotelChildAndCopyPageWithLanguageSynchronization(): void
     {
         parent::localizePageAndAddMonoglotHotelChildWithLanguageSynchronization();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesDiscard/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesDiscard/ActionTest.php
index b862a9727866..41492597cced 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesDiscard/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesDiscard/ActionTest.php
@@ -17,22 +17,19 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreCsv\WorkspacesDiscard;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreCsv\AbstractActionWorkspacesTestCase;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContent(): void
     {
         parent::createParentContent();
@@ -40,9 +37,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createParentContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentContent(): void
     {
         parent::modifyParentContent();
@@ -50,9 +45,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteParentContent(): void
     {
         parent::deleteParentContent();
@@ -60,9 +53,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteParentContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContent(): void
     {
         parent::copyParentContent();
@@ -70,9 +61,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyParentContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContentToDifferentPage(): void
     {
         parent::copyParentContentToDifferentPage();
@@ -80,9 +69,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyParentContentToDifferentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeParentContentWithAllChildren(): void
     {
         // Create translated page first
@@ -92,9 +79,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeParentContentWAllChildren.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeParentContentSorting(): void
     {
         parent::changeParentContentSorting();
@@ -102,9 +87,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changeParentContentSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPage(): void
     {
         parent::moveParentContentToDifferentPage();
@@ -112,9 +95,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveParentContentToDifferentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageTwice(): void
     {
         parent::moveParentContentToDifferentPageTwice();
@@ -122,9 +103,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveParentContentToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveParentContentToDifferentPageAndChangeSorting();
@@ -134,13 +113,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveParentContentToDifferentPageNChangeSorting.csv');
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
@@ -148,9 +121,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -158,9 +129,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deletePage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
@@ -170,9 +139,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPageWithHotelBeforeParentContent(): void
     {
         parent::copyPageWithHotelBeforeParentContent();
@@ -182,13 +149,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyPageWHotelBeforeParentContent.csv');
     }
 
-    /**
-     * IRRE Child Records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContentWithHotelAndOfferChildren(): void
     {
         parent::createParentContentWithHotelAndOfferChildren();
@@ -196,9 +157,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createParentContentNHotelNOfferChildren.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndCopyParentContentWithHotelAndOfferChildren(): void
     {
         parent::createAndCopyParentContentWithHotelAndOfferChildren();
@@ -207,9 +166,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createNCopyParentContentNHotelNOfferChildren.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildren(): void
     {
         // Create translated page first
@@ -220,19 +177,14 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createNLocalizeParentContentNHotelNOfferChildren.csv');
     }
 
-    /**
-     * @test
-     * No pair tests in Modify, Publish, PublishAll
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildrenAndDiscardLocalizedParent(): void
     {
         parent::createAndLocalizeParentContentWithHotelAndOfferChildrenAndDiscardLocalizedParent();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createNLocParentNHotelNOfferChildrenNDiscardLocParent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyOnlyHotelChild(): void
     {
         parent::modifyOnlyHotelChild();
@@ -240,9 +192,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyOnlyHotelChild.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndChangeHotelChildrenSorting(): void
     {
         parent::modifyParentAndChangeHotelChildrenSorting();
@@ -250,9 +200,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentNChangeHotelChildrenSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentWithHotelChild(): void
     {
         parent::modifyParentWithHotelChild();
@@ -261,9 +209,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentNHotelChild.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndAddHotelChild(): void
     {
         parent::modifyParentAndAddHotelChild();
@@ -271,9 +217,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentNAddHotelChild.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndDeleteHotelChild(): void
     {
         parent::modifyParentAndDeleteHotelChild();
@@ -281,9 +225,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentNDeleteHotelChild.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyAndDiscardAndModifyParentWithHotelChild(): void
     {
         parent::modifyAndDiscardAndModifyParentWithHotelChild();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesModify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesModify/ActionTest.php
index bd2eb2813674..17e6d08ab92c 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesModify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesModify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreCsv\WorkspacesModify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreCsv\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -24,18 +25,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContent(): void
     {
         parent::createParentContent();
@@ -50,9 +47,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentContent(): void
     {
         parent::modifyParentContent();
@@ -70,9 +65,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteParentContent(): void
     {
         parent::deleteParentContent();
@@ -87,9 +80,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContent(): void
     {
         parent::copyParentContent();
@@ -105,9 +96,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContentToDifferentPage(): void
     {
         parent::copyParentContentToDifferentPage();
@@ -123,9 +112,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeParentContentWithAllChildren(): void
     {
         // Create translated page first
@@ -143,9 +130,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeParentContentSorting(): void
     {
         parent::changeParentContentSorting();
@@ -164,9 +149,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPage(): void
     {
         parent::moveParentContentToDifferentPage();
@@ -184,18 +167,14 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageTwice(): void
     {
         parent::moveParentContentToDifferentPageTwice();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveParentContentToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveParentContentToDifferentPageAndChangeSorting();
@@ -216,13 +195,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
@@ -240,9 +213,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -255,9 +226,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
@@ -271,9 +240,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPageWithHotelBeforeParentContent(): void
     {
         parent::copyPageWithHotelBeforeParentContent();
@@ -288,14 +255,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * IRRE Child Records
-     */
-
-    /**
-     * @test
-     * Publish, PublishAll and Discard currently not implemented - they make little sense
-     */
+    #[Test]
     public function changeHotelSortingWithOfferNotWorkspaceAware(): void
     {
         parent::changeHotelSortingWithOfferNotWorkspaceAware();
@@ -319,9 +279,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('Offer #2.1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContentWithHotelAndOfferChildren(): void
     {
         parent::createParentContentWithHotelAndOfferChildren();
@@ -339,9 +297,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndCopyParentContentWithHotelAndOfferChildren(): void
     {
         parent::createAndCopyParentContentWithHotelAndOfferChildren();
@@ -365,9 +321,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('Offer #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildren(): void
     {
         // Create translated page first
@@ -390,9 +344,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('[Translate to Dansk:] Offer #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyOnlyHotelChild(): void
     {
         parent::modifyOnlyHotelChild();
@@ -408,9 +360,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndChangeHotelChildrenSorting(): void
     {
         parent::modifyParentAndChangeHotelChildrenSorting();
@@ -426,9 +376,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentWithHotelChild(): void
     {
         parent::modifyParentWithHotelChild();
@@ -444,9 +392,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndAddHotelChild(): void
     {
         parent::modifyParentAndAddHotelChild();
@@ -462,9 +408,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndDeleteHotelChild(): void
     {
         parent::modifyParentAndDeleteHotelChild();
@@ -483,9 +427,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyAndDiscardAndModifyParentWithHotelChild(): void
     {
         parent::modifyAndDiscardAndModifyParentWithHotelChild();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesPublish/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesPublish/ActionTest.php
index 763889c350e2..61a0fbe6f748 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesPublish/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesPublish/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreCsv\WorkspacesPublish;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreCsv\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -24,18 +25,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContent(): void
     {
         parent::createParentContent();
@@ -48,9 +45,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentContent(): void
     {
         parent::modifyParentContent();
@@ -66,9 +61,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteParentContent(): void
     {
         parent::deleteParentContent();
@@ -81,9 +74,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContent(): void
     {
         parent::copyParentContent();
@@ -97,9 +88,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContentToDifferentPage(): void
     {
         parent::copyParentContentToDifferentPage();
@@ -113,9 +102,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeParentContentWithAllChildren(): void
     {
         // Create and publish translated page first
@@ -132,9 +119,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeParentContentSorting(): void
     {
         parent::changeParentContentSorting();
@@ -151,9 +136,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPage(): void
     {
         parent::moveParentContentToDifferentPage();
@@ -169,9 +152,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageTwice(): void
     {
         parent::moveParentContentToDifferentPageTwice();
@@ -179,9 +160,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveParentContentToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveParentContentToDifferentPageAndChangeSorting();
@@ -202,13 +181,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
@@ -224,9 +197,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -239,9 +210,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
@@ -257,9 +226,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPageWithHotelBeforeParentContent(): void
     {
         parent::copyPageWithHotelBeforeParentContent();
@@ -277,13 +244,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * IRRE Child Records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContentWithHotelAndOfferChildren(): void
     {
         parent::createParentContentWithHotelAndOfferChildren();
@@ -299,9 +260,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndCopyParentContentWithHotelAndOfferChildren(): void
     {
         parent::createAndCopyParentContentWithHotelAndOfferChildren();
@@ -324,9 +283,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('Offer #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildren(): void
     {
         // Create and publish translated page first
@@ -349,9 +306,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('[Translate to Dansk:] Offer #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyOnlyHotelChild(): void
     {
         parent::modifyOnlyHotelChild();
@@ -365,9 +320,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndChangeHotelChildrenSorting(): void
     {
         parent::modifyParentAndChangeHotelChildrenSorting();
@@ -381,9 +334,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentWithHotelChild(): void
     {
         parent::modifyParentWithHotelChild();
@@ -397,9 +348,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndAddHotelChild(): void
     {
         parent::modifyParentAndAddHotelChild();
@@ -413,9 +362,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndDeleteHotelChild(): void
     {
         parent::modifyParentAndDeleteHotelChild();
@@ -432,9 +379,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyAndDiscardAndModifyParentWithHotelChild(): void
     {
         parent::modifyAndDiscardAndModifyParentWithHotelChild();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesPublishAll/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesPublishAll/ActionTest.php
index 66bd04de3f3b..0cb48b433629 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesPublishAll/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreCsv/WorkspacesPublishAll/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreCsv\WorkspacesPublishAll;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreCsv\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -24,18 +25,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContent(): void
     {
         parent::createParentContent();
@@ -48,9 +45,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentContent(): void
     {
         parent::modifyParentContent();
@@ -66,9 +61,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteParentContent(): void
     {
         parent::deleteParentContent();
@@ -81,9 +74,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContent(): void
     {
         parent::copyParentContent();
@@ -97,9 +88,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContentToDifferentPage(): void
     {
         parent::copyParentContentToDifferentPage();
@@ -113,9 +102,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeParentContentWithAllChildren(): void
     {
         // Create translated page first
@@ -131,9 +118,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeParentContentSorting(): void
     {
         parent::changeParentContentSorting();
@@ -150,9 +135,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPage(): void
     {
         parent::moveParentContentToDifferentPage();
@@ -168,9 +151,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageTwice(): void
     {
         parent::moveParentContentToDifferentPageTwice();
@@ -178,9 +159,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveParentContentToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveParentContentToDifferentPageAndChangeSorting();
@@ -199,13 +178,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
@@ -221,9 +194,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -236,9 +207,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
@@ -251,9 +220,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPageWithHotelBeforeParentContent(): void
     {
         parent::copyPageWithHotelBeforeParentContent();
@@ -266,13 +233,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * IRRE Child Records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContentWithHotelAndOfferChildren(): void
     {
         parent::createParentContentWithHotelAndOfferChildren();
@@ -288,9 +249,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndCopyParentContentWithHotelAndOfferChildren(): void
     {
         parent::createAndCopyParentContentWithHotelAndOfferChildren();
@@ -312,9 +271,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('Offer #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildren(): void
     {
         // Create translated page first
@@ -335,9 +292,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('[Translate to Dansk:] Offer #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyOnlyHotelChild(): void
     {
         parent::modifyOnlyHotelChild();
@@ -351,9 +306,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndChangeHotelChildrenSorting(): void
     {
         parent::modifyParentAndChangeHotelChildrenSorting();
@@ -367,9 +320,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentWithHotelChild(): void
     {
         parent::modifyParentWithHotelChild();
@@ -383,9 +334,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndAddHotelChild(): void
     {
         parent::modifyParentAndAddHotelChild();
@@ -399,9 +348,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndDeleteHotelChild(): void
     {
         parent::modifyParentAndDeleteHotelChild();
@@ -418,9 +365,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyAndDiscardAndModifyParentWithHotelChild(): void
     {
         parent::modifyAndDiscardAndModifyParentWithHotelChild();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/Modify/ActionTest.php
index 387150f4a8d9..373558248dd1 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/Modify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/Modify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreForeignField\Modify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreForeignField\AbstractActionTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
@@ -26,19 +27,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
  */
 final class ActionTest extends AbstractActionTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     * See DataSet/createParentContentRecord.csv
-     */
+    #[Test]
     public function createParentContent(): void
     {
         parent::createParentContent();
@@ -50,10 +46,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyParentContentRecord.csv
-     */
+    #[Test]
     public function modifyParentContent(): void
     {
         parent::modifyParentContent();
@@ -68,10 +61,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/deleteParentContentRecord.csv
-     */
+    #[Test]
     public function deleteParentContent(): void
     {
         parent::deleteParentContent();
@@ -83,10 +73,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyParentContentRecord.csv
-     */
+    #[Test]
     public function copyParentContent(): void
     {
         parent::copyParentContent();
@@ -99,10 +86,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyParentContentToDifferentPage.csv
-     */
+    #[Test]
     public function copyParentContentToDifferentPage(): void
     {
         parent::copyParentContentToDifferentPage();
@@ -115,10 +99,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyParentContentToLanguageWAllChildren.csv
-     */
+    #[Test]
     public function copyParentContentToLanguageWithAllChildren(): void
     {
         // Create translated page first
@@ -137,10 +118,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeParentContentWAllChildren.csv
-     */
+    #[Test]
     public function localizeParentContentWithAllChildren(): void
     {
         // Create translated page first
@@ -155,10 +133,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeParentContentSynchronization.csv
-     */
+    #[Test]
     public function localizeParentContentWithLanguageSynchronization(): void
     {
         // Create translated page first
@@ -173,10 +148,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeParentContentChainLanguageSynchronizationSource.csv
-     */
+    #[Test]
     public function localizeParentContentChainLanguageSynchronizationSource(): void
     {
         // Create translated page first
@@ -192,10 +164,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Deutsch:] [Translate to Dansk:] Hotel #1', '[Translate to Deutsch:] [Translate to Dansk:] Hotel #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/Modify/localizeParentContentNCreateNestedChildrenWLanguageSynchronization.csv
-     */
+    #[Test]
     public function localizeParentContentAndCreateNestedChildrenWithLanguageSynchronization(): void
     {
         // Create translated page first
@@ -210,10 +179,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1', '[Translate to Dansk:] New Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeParentContentSynchronization.csv
-     */
+    #[Test]
     public function localizeParentContentAndSetInvalidChildReferenceWithLanguageSynchronization(): void
     {
         // Create translated page first
@@ -229,10 +195,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeParentContentSynchronization.csv
-     */
+    #[Test]
     public function localizeParentContentAndSetInvalidChildReferenceWithLateLanguageSynchronization(): void
     {
         // Create translated page first
@@ -248,10 +211,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/changeParentContentRecordSorting.csv
-     */
+    #[Test]
     public function changeParentContentSorting(): void
     {
         parent::changeParentContentSorting();
@@ -267,10 +227,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/moveParentContentRecordToDifferentPage.csv
-     */
+    #[Test]
     public function moveParentContentToDifferentPage(): void
     {
         parent::moveParentContentToDifferentPage();
@@ -285,10 +242,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/moveParentContentRecordToDifferentPageAndChangeSorting.csv
-     */
+    #[Test]
     public function moveParentContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveParentContentToDifferentPageAndChangeSorting();
@@ -306,14 +260,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     * See DataSet/modifyPageRecord.csv
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
@@ -325,10 +272,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/deletePageRecord.csv
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -338,10 +282,7 @@ final class ActionTest extends AbstractActionTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     * See DataSet/copyPageRecord.csv
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
@@ -353,10 +294,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyPageWHotelBeforeParentContent.csv
-     */
+    #[Test]
     public function copyPageWithHotelBeforeParentContent(): void
     {
         parent::copyPageWithHotelBeforeParentContent();
@@ -368,14 +306,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * IRRE Child Records
-     */
-
-    /**
-     * @test
-     * See DataSet/createParentContentRecordWithHotelAndOfferChildRecords.csv
-     */
+    #[Test]
     public function createParentContentWithHotelAndOfferChildren(): void
     {
         parent::createParentContentWithHotelAndOfferChildren();
@@ -390,10 +321,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/createAndCopyParentContentRecordWithHotelAndOfferChildRecords.csv
-     */
+    #[Test]
     public function createAndCopyParentContentWithHotelAndOfferChildren(): void
     {
         parent::createAndCopyParentContentWithHotelAndOfferChildren();
@@ -412,10 +340,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('Offer #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/createAndLocalizeParentContentRecordWithHotelAndOfferChildRecords.csv
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildren(): void
     {
         // Create translated page first
@@ -435,9 +360,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('[Translate to Dansk:] Offer #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildrenWithoutSortByConfiguration(): void
     {
         // Create translated page first
@@ -457,10 +380,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('[Translate to Dansk:] Offer #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyOnlyHotelChildRecord.csv
-     */
+    #[Test]
     public function modifyOnlyHotelChild(): void
     {
         parent::modifyOnlyHotelChild();
@@ -473,10 +393,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyParentRecordAndChangeHotelChildRecordsSorting.csv
-     */
+    #[Test]
     public function modifyParentAndChangeHotelChildrenSorting(): void
     {
         parent::modifyParentAndChangeHotelChildrenSorting();
@@ -489,10 +406,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyParentRecordWithHotelChildRecord.csv
-     */
+    #[Test]
     public function modifyParentWithHotelChild(): void
     {
         parent::modifyParentWithHotelChild();
@@ -505,10 +419,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyParentRecordAndAddHotelChildRecord.csv
-     */
+    #[Test]
     public function modifyParentAndAddHotelChild(): void
     {
         parent::modifyParentAndAddHotelChild();
@@ -521,10 +432,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyParentRecordAndDeleteHotelChildRecord.csv
-     */
+    #[Test]
     public function modifyParentAndDeleteHotelChild(): void
     {
         parent::modifyParentAndDeleteHotelChild();
@@ -540,10 +448,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageWExclude.csv
-     */
+    #[Test]
     public function localizePageWithLocalizationExclude(): void
     {
         parent::localizePageWithLocalizationExclude();
@@ -556,10 +461,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #0'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageTwiceWExclude.csv
-     */
+    #[Test]
     public function localizePageTwiceWithLocalizationExclude(): void
     {
         parent::localizePageTwiceWithLocalizationExclude();
@@ -572,10 +474,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #0'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageNAddHotelChildWExclude.csv
-     */
+    #[Test]
     public function localizePageAndAddHotelChildWithLocalizationExclude(): void
     {
         parent::localizePageAndAddHotelChildWithLocalizationExclude();
@@ -588,10 +487,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #0', 'Hotel #007'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageWSynchronization.csv
-     */
+    #[Test]
     public function localizePageWithLanguageSynchronization(): void
     {
         parent::localizePageWithLanguageSynchronization();
@@ -604,10 +500,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #0'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageNAddHotelChildWSynchronization.csv
-     */
+    #[Test]
     public function localizePageAndAddHotelChildWithLanguageSynchronization(): void
     {
         parent::localizePageAndAddHotelChildWithLanguageSynchronization();
@@ -620,10 +513,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #0', '[Translate to Dansk:] Hotel #007'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageNAddMonoglotHotelChildWSynchronization.csv
-     */
+    #[Test]
     public function localizePageAndAddMonoglotHotelChildWithLanguageSynchronization(): void
     {
         parent::localizePageAndAddMonoglotHotelChildWithLanguageSynchronization();
@@ -636,10 +526,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #0', 'Hotel #007'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeNCopyPageWSynchronization.csv
-     */
+    #[Test]
     public function localizeAndCopyPageWithLanguageSynchronization(): void
     {
         parent::localizeAndCopyPageWithLanguageSynchronization();
@@ -655,10 +542,8 @@ final class ActionTest extends AbstractActionTestCase
     /**
      * Checks for a page having an IRRE record. The page is then localized and
      * an IRRE record is then added to the localized page
-     *
-     * @test
-     * See DataSet/localizePageWithSynchronizationAndCustomLocalizedHotel.csv
      */
+    #[Test]
     public function localizePageWithSynchronizationAndCustomLocalizedHotel(): void
     {
         parent::localizePageWithSynchronizationAndCustomLocalizedHotel();
@@ -671,10 +556,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #0'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageAddMonoglotHotelChildNCopyPageWSynchronization.csv
-     */
+    #[Test]
     public function localizePageAddMonoglotHotelChildAndCopyPageWithLanguageSynchronization(): void
     {
         parent::localizePageAndAddMonoglotHotelChildWithLanguageSynchronization();
@@ -688,9 +570,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #0', 'Hotel #007'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inlineLocalizeSynchronizeLocalizeMissing(): void
     {
         parent::inlineLocalizeSynchronizeLocalizeMissing();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesDiscard/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesDiscard/ActionTest.php
index 61efda11f48c..dc8f293c44c4 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesDiscard/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesDiscard/ActionTest.php
@@ -17,22 +17,19 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreForeignField\WorkspacesDiscard;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreForeignField\AbstractActionWorkspacesTestCase;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContent(): void
     {
         parent::createParentContent();
@@ -40,9 +37,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createParentContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentContent(): void
     {
         parent::modifyParentContent();
@@ -50,9 +45,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteParentContent(): void
     {
         parent::deleteParentContent();
@@ -60,9 +53,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteParentContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContent(): void
     {
         parent::copyParentContent();
@@ -70,9 +61,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyParentContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContentToDifferentPage(): void
     {
         parent::copyParentContentToDifferentPage();
@@ -80,9 +69,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyParentContentToDifferentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeParentContentWithAllChildren(): void
     {
         // Create translated page first
@@ -92,9 +79,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeParentContentWAllChildren.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeParentContentSorting(): void
     {
         parent::changeParentContentSorting();
@@ -102,9 +87,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changeParentContentSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPage(): void
     {
         parent::moveParentContentToDifferentPage();
@@ -112,9 +95,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveParentContentToDifferentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageTwice(): void
     {
         parent::moveParentContentToDifferentPageTwice();
@@ -122,9 +103,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveParentContentToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveParentContentToDifferentPageAndChangeSorting();
@@ -134,13 +113,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveParentContentToDifferentPageNChangeSorting.csv');
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
@@ -148,9 +121,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -158,9 +129,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deletePage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
@@ -170,9 +139,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPageWithHotelBeforeParentContent(): void
     {
         parent::copyPageWithHotelBeforeParentContent();
@@ -182,13 +149,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyPageWHotelBeforeParentContent.csv');
     }
 
-    /**
-     * IRRE Child Records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContentWithHotelAndOfferChildren(): void
     {
         parent::createParentContentWithHotelAndOfferChildren();
@@ -196,9 +157,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createParentContentNHotelNOfferChildren.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndCopyParentContentWithHotelAndOfferChildren(): void
     {
         parent::createAndCopyParentContentWithHotelAndOfferChildren();
@@ -207,9 +166,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createNCopyParentContentNHotelNOfferChildren.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildren(): void
     {
         // Create translated page first
@@ -220,19 +177,14 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createNLocalizeParentContentNHotelNOfferChildren.csv');
     }
 
-    /**
-     * @test
-     * No pair tests in Modify, Publish, PublishAll
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildrenAndDiscardLocalizedParent(): void
     {
         parent::createAndLocalizeParentContentWithHotelAndOfferChildrenAndDiscardLocalizedParent();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createNLocParentNHotelNOfferChildrenNDiscardLocParent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyOnlyHotelChild(): void
     {
         parent::modifyOnlyHotelChild();
@@ -240,9 +192,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyOnlyHotelChild.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndChangeHotelChildrenSorting(): void
     {
         parent::modifyParentAndChangeHotelChildrenSorting();
@@ -250,9 +200,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentNChangeHotelChildrenSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentWithHotelChild(): void
     {
         parent::modifyParentWithHotelChild();
@@ -261,9 +209,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentNHotelChild.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndAddHotelChild(): void
     {
         parent::modifyParentAndAddHotelChild();
@@ -271,9 +217,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentNAddHotelChild.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndDeleteHotelChild(): void
     {
         parent::modifyParentAndDeleteHotelChild();
@@ -281,9 +225,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentNDeleteHotelChild.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyAndDiscardAndModifyParentWithHotelChild(): void
     {
         parent::modifyAndDiscardAndModifyParentWithHotelChild();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesModify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesModify/ActionTest.php
index 0f68b9e7ef0f..b28a99101927 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesModify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesModify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreForeignField\WorkspacesModify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreForeignField\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -24,18 +25,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContent(): void
     {
         parent::createParentContent();
@@ -50,9 +47,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentContent(): void
     {
         parent::modifyParentContent();
@@ -70,9 +65,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteParentContent(): void
     {
         parent::deleteParentContent();
@@ -87,9 +80,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContent(): void
     {
         parent::copyParentContent();
@@ -105,9 +96,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContentToDifferentPage(): void
     {
         parent::copyParentContentToDifferentPage();
@@ -123,9 +112,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeParentContentWithAllChildren(): void
     {
         // Create translated page first
@@ -143,9 +130,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeParentContentSorting(): void
     {
         parent::changeParentContentSorting();
@@ -164,9 +149,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPage(): void
     {
         parent::moveParentContentToDifferentPage();
@@ -184,18 +167,14 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageTwice(): void
     {
         parent::moveParentContentToDifferentPageTwice();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveParentContentToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveParentContentToDifferentPageAndChangeSorting();
@@ -216,13 +195,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
@@ -240,9 +213,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -255,9 +226,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
@@ -272,9 +241,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPageWithHotelBeforeParentContent(): void
     {
         parent::copyPageWithHotelBeforeParentContent();
@@ -289,13 +256,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * IRRE Child Records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContentWithHotelAndOfferChildren(): void
     {
         parent::createParentContentWithHotelAndOfferChildren();
@@ -313,9 +274,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndCopyParentContentWithHotelAndOfferChildren(): void
     {
         parent::createAndCopyParentContentWithHotelAndOfferChildren();
@@ -339,9 +298,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('Offer #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildren(): void
     {
         // Create translated page first
@@ -364,10 +321,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('[Translate to Dansk:] Offer #1'));
     }
 
-    /**
-     * @test
-     * Test not implemented for Publish, PublishAll and Discard
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildrenWithoutSortByConfiguration(): void
     {
         // Create translated page first
@@ -390,9 +344,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('[Translate to Dansk:] Offer #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyOnlyHotelChild(): void
     {
         parent::modifyOnlyHotelChild();
@@ -408,9 +360,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndChangeHotelChildrenSorting(): void
     {
         parent::modifyParentAndChangeHotelChildrenSorting();
@@ -426,9 +376,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentWithHotelChild(): void
     {
         parent::modifyParentWithHotelChild();
@@ -444,9 +392,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndAddHotelChild(): void
     {
         parent::modifyParentAndAddHotelChild();
@@ -462,9 +408,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndDeleteHotelChild(): void
     {
         parent::modifyParentAndDeleteHotelChild();
@@ -483,9 +427,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyAndDiscardAndModifyParentWithHotelChild(): void
     {
         parent::modifyAndDiscardAndModifyParentWithHotelChild();
@@ -506,10 +448,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Testing #2'));
     }
 
-    /**
-     * @test
-     * Publish, PublishAll and Discard currently not implemented - they make little sense
-     */
+    #[Test]
     public function inlineLocalizeSynchronizeLocalizeMissing(): void
     {
         parent::inlineLocalizeSynchronizeLocalizeMissing();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesPublish/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesPublish/ActionTest.php
index a36b61a50fc1..62fb97271cb8 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesPublish/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesPublish/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreForeignField\WorkspacesPublish;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreForeignField\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -24,18 +25,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContent(): void
     {
         parent::createParentContent();
@@ -48,9 +45,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentContent(): void
     {
         parent::modifyParentContent();
@@ -66,9 +61,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteParentContent(): void
     {
         parent::deleteParentContent();
@@ -81,9 +74,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContent(): void
     {
         parent::copyParentContent();
@@ -97,9 +88,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContentToDifferentPage(): void
     {
         parent::copyParentContentToDifferentPage();
@@ -113,9 +102,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeParentContentWithAllChildren(): void
     {
         // Create and publish translated page first
@@ -132,9 +119,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeParentContentSorting(): void
     {
         parent::changeParentContentSorting();
@@ -151,9 +136,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPage(): void
     {
         parent::moveParentContentToDifferentPage();
@@ -170,9 +153,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageTwice(): void
     {
         parent::moveParentContentToDifferentPageTwice();
@@ -180,9 +161,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveParentContentToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveParentContentToDifferentPageAndChangeSorting();
@@ -205,13 +184,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
@@ -227,9 +200,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -242,9 +213,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
@@ -262,9 +231,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPageWithHotelBeforeParentContent(): void
     {
         parent::copyPageWithHotelBeforeParentContent();
@@ -282,13 +249,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * IRRE Child Records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContentWithHotelAndOfferChildren(): void
     {
         parent::createParentContentWithHotelAndOfferChildren();
@@ -304,9 +265,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndCopyParentContentWithHotelAndOfferChildren(): void
     {
         parent::createAndCopyParentContentWithHotelAndOfferChildren();
@@ -329,9 +288,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('Offer #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildren(): void
     {
         // Create and publish translated page first
@@ -354,9 +311,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('[Translate to Dansk:] Offer #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyOnlyHotelChild(): void
     {
         parent::modifyOnlyHotelChild();
@@ -370,9 +325,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndChangeHotelChildrenSorting(): void
     {
         parent::modifyParentAndChangeHotelChildrenSorting();
@@ -386,9 +339,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentWithHotelChild(): void
     {
         parent::modifyParentWithHotelChild();
@@ -402,9 +353,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndAddHotelChild(): void
     {
         parent::modifyParentAndAddHotelChild();
@@ -418,9 +367,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndDeleteHotelChild(): void
     {
         parent::modifyParentAndDeleteHotelChild();
@@ -437,9 +384,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyAndDiscardAndModifyParentWithHotelChild(): void
     {
         parent::modifyAndDiscardAndModifyParentWithHotelChild();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesPublishAll/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesPublishAll/ActionTest.php
index 0b85fc74c750..f0da6df1034b 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesPublishAll/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignField/WorkspacesPublishAll/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreForeignField\WorkspacesPublishAll;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreForeignField\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -24,18 +25,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContent(): void
     {
         parent::createParentContent();
@@ -48,9 +45,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentContent(): void
     {
         parent::modifyParentContent();
@@ -66,9 +61,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteParentContent(): void
     {
         parent::deleteParentContent();
@@ -81,9 +74,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContent(): void
     {
         parent::copyParentContent();
@@ -97,9 +88,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContentToDifferentPage(): void
     {
         parent::copyParentContentToDifferentPage();
@@ -113,9 +102,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeParentContentWithAllChildren(): void
     {
         // Create translated page first
@@ -131,9 +118,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeParentContentSorting(): void
     {
         parent::changeParentContentSorting();
@@ -150,9 +135,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPage(): void
     {
         parent::moveParentContentToDifferentPage();
@@ -169,9 +152,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageTwice(): void
     {
         parent::moveParentContentToDifferentPageTwice();
@@ -179,9 +160,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveParentContentToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveParentContentToDifferentPageAndChangeSorting();
@@ -200,13 +179,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
@@ -222,9 +195,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -237,9 +208,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
@@ -252,9 +221,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPageWithHotelBeforeParentContent(): void
     {
         parent::copyPageWithHotelBeforeParentContent();
@@ -267,13 +234,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * IRRE Child Records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContentWithHotelAndOfferChildren(): void
     {
         parent::createParentContentWithHotelAndOfferChildren();
@@ -289,9 +250,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndCopyParentContentWithHotelAndOfferChildren(): void
     {
         parent::createAndCopyParentContentWithHotelAndOfferChildren();
@@ -313,9 +272,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('Offer #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildren(): void
     {
         // Create translated page first
@@ -336,9 +293,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Offer)->setField('title')->setValues('[Translate to Dansk:] Offer #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyOnlyHotelChild(): void
     {
         parent::modifyOnlyHotelChild();
@@ -352,9 +307,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndChangeHotelChildrenSorting(): void
     {
         parent::modifyParentAndChangeHotelChildrenSorting();
@@ -368,9 +321,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2', 'Hotel #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentWithHotelChild(): void
     {
         parent::modifyParentWithHotelChild();
@@ -384,9 +335,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndAddHotelChild(): void
     {
         parent::modifyParentAndAddHotelChild();
@@ -400,9 +349,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #1', 'Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndDeleteHotelChild(): void
     {
         parent::modifyParentAndDeleteHotelChild();
@@ -419,9 +366,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyAndDiscardAndModifyParentWithHotelChild(): void
     {
         parent::modifyAndDiscardAndModifyParentWithHotelChild();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignFieldNonWs/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignFieldNonWs/Modify/ActionTest.php
index 2dde42925f5e..116e49c5cdd3 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignFieldNonWs/Modify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignFieldNonWs/Modify/ActionTest.php
@@ -17,67 +17,54 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreForeignFieldNonWs\Modify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreForeignFieldNonWs\AbstractActionTestCase;
 
 final class ActionTest extends AbstractActionTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContent(): void
     {
         parent::createParentContent();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createParentContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentContent(): void
     {
         parent::modifyParentContent();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteParentContent(): void
     {
         parent::deleteParentContent();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteParentContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContent(): void
     {
         parent::copyParentContent();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyParentContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContentToDifferentPage(): void
     {
         parent::copyParentContentToDifferentPage();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyParentContentToDifferentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyParentContentToLanguageWithAllChildren(): void
     {
         // Create translated page first
@@ -86,9 +73,7 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyParentContentToLanguageWAllChildren.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeParentContentWithAllChildren(): void
     {
         // Create translated page first
@@ -97,9 +82,7 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeParentContentWAllChildren.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeParentContentWithLanguageSynchronization(): void
     {
         // Create translated page first
@@ -108,9 +91,7 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeParentContentSynchronization.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeParentContentChainLanguageSynchronizationSource(): void
     {
         // Create translated page first
@@ -120,9 +101,7 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeParentContentChainLanguageSynchronizationSource.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeParentContentAndCreateNestedChildrenWithLanguageSynchronization(): void
     {
         // Create translated page first
@@ -131,9 +110,7 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeParentContentNCreateNestedChildrenWLanguageSynchronization.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeParentContentAndSetInvalidChildReferenceWithLanguageSynchronization(): void
     {
         // Create translated page first
@@ -143,9 +120,7 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeParentContentSynchronization.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeParentContentAndSetInvalidChildReferenceWithLateLanguageSynchronization(): void
     {
         // Create translated page first
@@ -155,98 +130,70 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeParentContentSynchronization.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeParentContentSorting(): void
     {
         parent::changeParentContentSorting();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changeParentContentSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPage(): void
     {
         parent::moveParentContentToDifferentPage();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveParentContentToDifferentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveParentContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveParentContentToDifferentPageAndChangeSorting();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveParentContentToDifferentPageNChangeSorting.csv');
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deletePage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPageWithHotelBeforeParentContent(): void
     {
         parent::copyPageWithHotelBeforeParentContent();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyPageWHotelBeforeParentContent.csv');
     }
 
-    /**
-     * IRRE Child Records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContentWithHotelAndOfferChildren(): void
     {
         parent::createParentContentWithHotelAndOfferChildren();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createParentContentNHotelNOfferChildren.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndCopyParentContentWithHotelAndOfferChildren(): void
     {
         parent::createAndCopyParentContentWithHotelAndOfferChildren();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createNCopyParentContentNHotelNOfferChildren.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildren(): void
     {
         // Create translated page first
@@ -255,9 +202,7 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createNLocalizeParentContentNHotelNOfferChildren.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildrenWithoutSortByConfiguration(): void
     {
         // Create translated page first
@@ -266,108 +211,84 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createNLocalizeParentContentNHotelNOfferChildrenWOSortBy.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyOnlyHotelChild(): void
     {
         parent::modifyOnlyHotelChild();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyOnlyHotelChild.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndChangeHotelChildrenSorting(): void
     {
         parent::modifyParentAndChangeHotelChildrenSorting();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentNChangeHotelChildrenSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentWithHotelChild(): void
     {
         parent::modifyParentWithHotelChild();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentNHotelChild.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndAddHotelChild(): void
     {
         parent::modifyParentAndAddHotelChild();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentNAddHotelChild.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndDeleteHotelChild(): void
     {
         parent::modifyParentAndDeleteHotelChild();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentNDeleteHotelChild.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageWithLocalizationExclude(): void
     {
         parent::localizePageWithLocalizationExclude();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageWExclude.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageTwiceWithLocalizationExclude(): void
     {
         parent::localizePageTwiceWithLocalizationExclude();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageTwiceWExclude.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageAndAddHotelChildWithLocalizationExclude(): void
     {
         parent::localizePageAndAddHotelChildWithLocalizationExclude();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNAddHotelChildWExclude.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageWithLanguageSynchronization(): void
     {
         parent::localizePageWithLanguageSynchronization();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageWSynchronization.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageAndAddHotelChildWithLanguageSynchronization(): void
     {
         parent::localizePageAndAddHotelChildWithLanguageSynchronization();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNAddHotelChildWSynchronization.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageAndAddMonoglotHotelChildWithLanguageSynchronization(): void
     {
         parent::localizePageAndAddMonoglotHotelChildWithLanguageSynchronization();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNAddMonoglotHotelChildWSynchronization.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeAndCopyPageWithLanguageSynchronization(): void
     {
         parent::localizeAndCopyPageWithLanguageSynchronization();
@@ -377,18 +298,15 @@ final class ActionTest extends AbstractActionTestCase
     /**
      * Checks for a page having an IRRE record. The page is then localized and
      * an IRRE record is then added to the localized page
-     *
-     * @test
      */
+    #[Test]
     public function localizePageWithSynchronizationAndCustomLocalizedHotel(): void
     {
         parent::localizePageWithSynchronizationAndCustomLocalizedHotel();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageWithSynchronizationAndCustomLocalizedHotel.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageAddMonoglotHotelChildAndCopyPageWithLanguageSynchronization(): void
     {
         parent::localizePageAndAddMonoglotHotelChildWithLanguageSynchronization();
@@ -396,9 +314,7 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageAddMonoglotHotelChildNCopyPageWSynchronization.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inlineLocalizeSynchronizeLocalizeMissing(): void
     {
         parent::inlineLocalizeSynchronizeLocalizeMissing();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignFieldNonWs/WorkspacesModify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignFieldNonWs/WorkspacesModify/ActionTest.php
index 37112e4eae42..1494710ad6a9 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignFieldNonWs/WorkspacesModify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/IrreForeignFieldNonWs/WorkspacesModify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreForeignFieldNonWs\WorkspacesModify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreForeignFieldNonWs\AbstractActionWorkspacesTestCase;
 
 /**
@@ -36,36 +37,28 @@ use TYPO3\CMS\Core\Tests\Functional\DataScenarios\IrreForeignFieldNonWs\Abstract
  */
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContent(): void
     {
         parent::createParentContent();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createParentContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentContent(): void
     {
         parent::modifyParentContent();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteParentContent(): void
     {
         parent::deleteParentContent();
@@ -90,9 +83,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyParentContentToDifferentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeParentContentWithAllChildren(): void
     {
         $this->expectedErrorLogEntries = 3;
@@ -102,9 +93,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeParentContentWAllChildren.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeParentContentSorting(): void
     {
         parent::changeParentContentSorting();
@@ -138,22 +127,14 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveParentContentToDifferentPageNChangeSorting.csv');
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -180,13 +161,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyPageWHotelBeforeParentContent.csv');
     }
 
-    /**
-     * IRRE Child Records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createParentContentWithHotelAndOfferChildren(): void
     {
         $this->expectedErrorLogEntries = 2;
@@ -203,9 +178,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createNCopyParentContentNHotelNOfferChildren.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildren(): void
     {
         $this->expectedErrorLogEntries = 2;
@@ -215,10 +188,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createNLocalizeParentContentNHotelNOfferChildren.csv');
     }
 
-    /**
-     * @test
-     * Test not implemented for Publish, PublishAll and Discard
-     */
+    #[Test]
     public function createAndLocalizeParentContentWithHotelAndOfferChildrenWithoutSortByConfiguration(): void
     {
         $this->expectedErrorLogEntries = 2;
@@ -228,9 +198,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createNLocalizeParentContentNHotelNOfferChildrenWOSortBy.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyOnlyHotelChild(): void
     {
         $this->expectedErrorLogEntries = 1;
@@ -247,9 +215,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentNChangeHotelChildrenSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentWithHotelChild(): void
     {
         $this->expectedErrorLogEntries = 1;
@@ -257,9 +223,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentNHotelChild.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndAddHotelChild(): void
     {
         $this->expectedErrorLogEntries = 1;
@@ -267,9 +231,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyParentNAddHotelChild.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyParentAndDeleteHotelChild(): void
     {
         $this->expectedErrorLogEntries = 1;
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/Modify/ActionTest.php
index fe96c2ccf3ca..79d80c3a369e 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/Modify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/Modify/ActionTest.php
@@ -17,25 +17,21 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\ManyToMany\Modify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\ManyToMany\AbstractActionTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     * See DataSet/addCategoryRelation.csv
-     */
+    #[Test]
     public function addCategoryRelation(): void
     {
         parent::addCategoryRelation();
@@ -48,9 +44,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A', 'Category B', 'Category A.A'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createCategoryAndAddRelation(): void
     {
         parent::createCategoryAndAddRelation();
@@ -63,10 +57,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A', 'Category B', 'Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/deleteCategoryRelation.csv
-     */
+    #[Test]
     public function deleteCategoryRelation(): void
     {
         parent::deleteCategoryRelation();
@@ -82,10 +73,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C', 'Category A.A'));
     }
 
-    /**
-     * @test
-     * See DataSet/changeCategoryRelationSorting.csv
-     */
+    #[Test]
     public function changeCategoryRelationSorting(): void
     {
         parent::changeCategoryRelationSorting();
@@ -98,10 +86,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A', 'Category B'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyCategoryRecordOfCategoryRelation.csv
-     */
+    #[Test]
     public function modifyCategoryOfRelation(): void
     {
         parent::modifyCategoryOfRelation();
@@ -114,10 +99,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Testing #1', 'Category B'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyContentRecordOfCategoryRelation.csv
-     */
+    #[Test]
     public function modifyContentOfRelation(): void
     {
         parent::modifyContentOfRelation();
@@ -129,10 +111,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyBothRecordsOfCategoryRelation.csv
-     */
+    #[Test]
     public function modifyBothsOfRelation(): void
     {
         parent::modifyBothsOfRelation();
@@ -147,10 +126,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/deleteContentRecordOfCategoryRelation.csv
-     */
+    #[Test]
     public function deleteContentOfRelation(): void
     {
         parent::deleteContentOfRelation();
@@ -162,10 +138,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/deleteCategoryRecordOfCategoryRelation.csv
-     */
+    #[Test]
     public function deleteCategoryOfRelation(): void
     {
         parent::deleteCategoryOfRelation();
@@ -178,10 +151,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyContentRecordOfCategoryRelation.csv
-     */
+    #[Test]
     public function copyContentOfRelation(): void
     {
         parent::copyContentOfRelation();
@@ -194,20 +164,14 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyCategoryRecordOfCategoryRelation.csv
-     */
+    #[Test]
     public function copyCategoryOfRelation(): void
     {
         parent::copyCategoryOfRelation();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyCategoryOfRelation.csv');
     }
 
-    /**
-     * @test
-     * See DataSet/copyContentToLanguageOfRelation.csv
-     */
+    #[Test]
     public function copyContentToLanguageOfRelation(): void
     {
         parent::copyContentToLanguageOfRelation();
@@ -220,10 +184,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyCategoryToLanguageOfRelation.csv
-     */
+    #[Test]
     public function copyCategoryToLanguageOfRelation(): void
     {
         parent::copyCategoryToLanguageOfRelation();
@@ -237,10 +198,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A', 'Category B'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentRecordOfCategoryRelation.csv
-     */
+    #[Test]
     public function localizeContentOfRelation(): void
     {
         parent::localizeContentOfRelation();
@@ -253,10 +211,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentOfRelationWSynchronization.csv
-     */
+    #[Test]
     public function localizeContentOfRelationWithLanguageSynchronization(): void
     {
         parent::localizeContentOfRelationWithLanguageSynchronization();
@@ -269,10 +224,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentOfRelationWExclude.csv
-     */
+    #[Test]
     public function localizeContentOfRelationWithLanguageExclude(): void
     {
         parent::localizeContentOfRelationWithLanguageExclude();
@@ -285,10 +237,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentOfRelationNAddCategoryWSynchronization.csv
-     */
+    #[Test]
     public function localizeContentOfRelationAndAddCategoryWithLanguageSynchronization(): void
     {
         parent::localizeContentOfRelationAndAddCategoryWithLanguageSynchronization();
@@ -301,10 +250,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C', 'Category A.A'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentChainOfRelationNAddCategoryWSynchronization.csv
-     */
+    #[Test]
     public function localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization(): void
     {
         parent::localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization();
@@ -317,10 +263,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C', 'Category A.A'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeCategoryRecordOfCategoryRelation.csv
-     */
+    #[Test]
     public function localizeCategoryOfRelation(): void
     {
         // Create translated page first
@@ -335,10 +278,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('[Translate to Dansk:] Category A', 'Category B'));
     }
 
-    /**
-     * @test
-     * See DataSet/moveContentRecordOfCategoryRelationToDifferentPage.csv
-     */
+    #[Test]
     public function moveContentOfRelationToDifferentPage(): void
     {
         parent::moveContentOfRelationToDifferentPage();
@@ -351,10 +291,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyPage.csv
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesDiscard/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesDiscard/ActionTest.php
index e0c9a2b98436..1e08f762c5af 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesDiscard/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesDiscard/ActionTest.php
@@ -17,22 +17,19 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\ManyToMany\WorkspacesDiscard;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\ManyToMany\AbstractActionWorkspacesTestCase;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addCategoryRelation(): void
     {
         parent::addCategoryRelation();
@@ -40,9 +37,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/addCategoryRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteCategoryRelation(): void
     {
         parent::deleteCategoryRelation();
@@ -50,9 +45,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteCategoryRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeCategoryRelationSorting(): void
     {
         parent::changeCategoryRelationSorting();
@@ -60,9 +53,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changeCategoryRelationSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndAddRelation(): void
     {
         parent::createContentAndAddRelation();
@@ -70,9 +61,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContentNAddRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createCategoryAndAddRelation(): void
     {
         parent::createCategoryAndAddRelation();
@@ -80,9 +69,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createCategoryNAddRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCreateRelation(): void
     {
         parent::createContentAndCreateRelation();
@@ -93,9 +80,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContentNCreateRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createCategoryAndCreateRelation(): void
     {
         parent::createCategoryAndCreateRelation();
@@ -106,9 +91,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createCategoryNCreateRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentWithCategoryAndAddRelation(): void
     {
         parent::createContentWithCategoryAndAddRelation();
@@ -119,9 +102,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContentWCategoryNAddRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createCategoryWithContentAndAddRelation(): void
     {
         parent::createCategoryWithContentAndAddRelation();
@@ -132,9 +113,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createCategoryWContentNAddRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyCategoryOfRelation(): void
     {
         parent::modifyCategoryOfRelation();
@@ -142,9 +121,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyCategoryOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentOfRelation(): void
     {
         parent::modifyContentOfRelation();
@@ -152,9 +129,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyContentOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyBothsOfRelation(): void
     {
         parent::modifyBothsOfRelation();
@@ -165,9 +140,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyBothsOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentOfRelation(): void
     {
         parent::deleteContentOfRelation();
@@ -175,9 +148,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteContentOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteCategoryOfRelation(): void
     {
         parent::deleteCategoryOfRelation();
@@ -185,9 +156,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteCategoryOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentOfRelation(): void
     {
         parent::copyContentOfRelation();
@@ -195,9 +164,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyContentOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentToLanguageOfRelation(): void
     {
         parent::copyContentToLanguageOfRelation();
@@ -205,9 +172,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyContentToLanguageOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyCategoryOfRelation(): void
     {
         parent::copyCategoryOfRelation();
@@ -216,9 +181,9 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
     }
 
     /**
-     * @test
      * @todo: this is a faulty test, because the category should be discarded
      */
+    #[Test]
     public function copyCategoryToLanguageOfRelation(): void
     {
         parent::copyCategoryToLanguageOfRelation();
@@ -226,9 +191,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyCategoryToLanguageOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelation(): void
     {
         parent::localizeContentOfRelation();
@@ -236,9 +199,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLanguageSynchronization(): void
     {
         parent::localizeContentOfRelationWithLanguageSynchronization();
@@ -246,9 +207,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentOfRelationWSynchronization.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLanguageExclude(): void
     {
         parent::localizeContentOfRelationWithLanguageExclude();
@@ -256,11 +215,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentOfRelationWExclude.csv');
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentOfRelationNAddCategoryWSynchronization.csv
-     * Note: The added category still exists, even if we discard the localized content
-     */
+    #[Test]
     public function localizeContentOfRelationAndAddCategoryWithLanguageSynchronization(): void
     {
         parent::localizeContentOfRelationAndAddCategoryWithLanguageSynchronization();
@@ -270,11 +225,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentOfRelationNAddCategoryWSynchronization.csv');
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentChainOfRelationNAddCategoryWSynchronization.csv
-     * Note: The added category still exists, even if we discard the localized content
-     */
+    #[Test]
     public function localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization(): void
     {
         parent::localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization();
@@ -285,9 +236,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentChainOfRelationNAddCategoryWSynchronization.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeCategoryOfRelation(): void
     {
         // Create translated page first
@@ -297,9 +246,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeCategoryOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentOfRelationToDifferentPage(): void
     {
         parent::moveContentOfRelationToDifferentPage();
@@ -307,9 +254,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveContentOfRelationToDifferentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesModify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesModify/ActionTest.php
index f0ec9146baf6..e95111d2e09a 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesModify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesModify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\ManyToMany\WorkspacesModify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\ManyToMany\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -24,18 +25,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addCategoryRelation(): void
     {
         parent::addCategoryRelation();
@@ -51,9 +48,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A', 'Category B', 'Category A.A'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteCategoryRelation(): void
     {
         parent::deleteCategoryRelation();
@@ -72,9 +67,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C', 'Category A.A'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeCategoryRelationSorting(): void
     {
         parent::changeCategoryRelationSorting();
@@ -90,9 +83,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A', 'Category B'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndAddRelation(): void
     {
         parent::createContentAndAddRelation();
@@ -110,9 +101,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createCategoryAndAddRelation(): void
     {
         parent::createCategoryAndAddRelation();
@@ -130,9 +119,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCreateRelation(): void
     {
         parent::createContentAndCreateRelation();
@@ -150,36 +137,28 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createCategoryAndCreateRelation(): void
     {
         parent::createCategoryAndCreateRelation();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createCategoryNCreateRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentWithCategoryAndAddRelation(): void
     {
         parent::createContentWithCategoryAndAddRelation();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContentWCategoryNAddRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createCategoryWithContentAndAddRelation(): void
     {
         parent::createCategoryWithContentAndAddRelation();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createCategoryWContentNAddRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyCategoryOfRelation(): void
     {
         parent::modifyCategoryOfRelation();
@@ -195,9 +174,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Testing #1', 'Category B'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentOfRelation(): void
     {
         parent::modifyContentOfRelation();
@@ -212,9 +189,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyBothsOfRelation(): void
     {
         parent::modifyBothsOfRelation();
@@ -232,9 +207,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentOfRelation(): void
     {
         parent::deleteContentOfRelation();
@@ -249,9 +222,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteCategoryOfRelation(): void
     {
         parent::deleteCategoryOfRelation();
@@ -267,9 +238,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentOfRelation(): void
     {
         parent::copyContentOfRelation();
@@ -285,9 +254,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentToLanguageOfRelation(): void
     {
         parent::copyContentToLanguageOfRelation();
@@ -303,9 +270,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyCategoryOfRelation(): void
     {
         parent::copyCategoryOfRelation();
@@ -321,9 +286,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A', 'Category A (copy 1)'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyCategoryToLanguageOfRelation(): void
     {
         parent::copyCategoryToLanguageOfRelation();
@@ -341,9 +304,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         //    ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A', '[Translate to Dansk:] Category A'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelation(): void
     {
         parent::localizeContentOfRelation();
@@ -359,9 +320,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLanguageSynchronization(): void
     {
         parent::localizeContentOfRelationWithLanguageSynchronization();
@@ -377,9 +336,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization(): void
     {
         parent::localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization();
@@ -396,9 +353,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLanguageExclude(): void
     {
         parent::localizeContentOfRelationWithLanguageExclude();
@@ -415,10 +370,9 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
     }
 
     /**
-     * @test
-     * See DataSet/localizeContentOfRelationNAddCategoryWSynchronization.csv
      * @todo: this test is faulty as it adds a lot of entries
      */
+    #[Test]
     public function localizeContentOfRelationAndAddCategoryWithLanguageSynchronization(): void
     {
         parent::localizeContentOfRelationAndAddCategoryWithLanguageSynchronization();
@@ -435,9 +389,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeCategoryOfRelation(): void
     {
         // Create translated page first
@@ -455,9 +407,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('[Translate to Dansk:] Category A', 'Category B'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentOfRelationToDifferentPage(): void
     {
         parent::moveContentOfRelationToDifferentPage();
@@ -473,9 +423,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesPublish/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesPublish/ActionTest.php
index f99f431e5f4d..21abdb1578c5 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesPublish/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesPublish/ActionTest.php
@@ -17,24 +17,21 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\ManyToMany\WorkspacesPublish;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\ManyToMany\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addCategoryRelation(): void
     {
         parent::addCategoryRelation();
@@ -48,9 +45,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A', 'Category B', 'Category A.A'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteCategoryRelation(): void
     {
         parent::deleteCategoryRelation();
@@ -67,9 +62,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C', 'Category A.A'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeCategoryRelationSorting(): void
     {
         parent::changeCategoryRelationSorting();
@@ -83,9 +76,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A', 'Category B'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndAddRelation(): void
     {
         parent::createContentAndAddRelation();
@@ -101,9 +92,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createCategoryAndAddRelation(): void
     {
         parent::createCategoryAndAddRelation();
@@ -119,9 +108,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCreateRelation(): void
     {
         parent::createContentAndCreateRelation();
@@ -140,9 +127,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createCategoryAndCreateRelation(): void
     {
         parent::createCategoryAndCreateRelation();
@@ -154,9 +139,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createCategoryNCreateRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentWithCategoryAndAddRelation(): void
     {
         parent::createContentWithCategoryAndAddRelation();
@@ -167,9 +150,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContentWCategoryNAddRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createCategoryWithContentAndAddRelation(): void
     {
         parent::createCategoryWithContentAndAddRelation();
@@ -180,9 +161,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createCategoryWContentNAddRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyCategoryOfRelation(): void
     {
         parent::modifyCategoryOfRelation();
@@ -196,9 +175,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Testing #1', 'Category B'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentOfRelation(): void
     {
         parent::modifyContentOfRelation();
@@ -211,9 +188,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyBothsOfRelation(): void
     {
         parent::modifyBothsOfRelation();
@@ -232,9 +207,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentOfRelation(): void
     {
         parent::deleteContentOfRelation();
@@ -247,9 +220,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteCategoryOfRelation(): void
     {
         parent::deleteCategoryOfRelation();
@@ -263,9 +234,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentOfRelation(): void
     {
         parent::copyContentOfRelation();
@@ -279,9 +248,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentToLanguageOfRelation(): void
     {
         parent::copyContentToLanguageOfRelation();
@@ -295,9 +262,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyCategoryOfRelation(): void
     {
         parent::copyCategoryOfRelation();
@@ -311,9 +276,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A', 'Category A (copy 1)'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyCategoryToLanguageOfRelation(): void
     {
         parent::copyCategoryToLanguageOfRelation();
@@ -330,9 +293,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
 
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelation(): void
     {
         parent::localizeContentOfRelation();
@@ -346,9 +307,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLanguageSynchronization(): void
     {
         parent::localizeContentOfRelationWithLanguageSynchronization();
@@ -362,9 +321,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLanguageExclude(): void
     {
         parent::localizeContentOfRelationWithLanguageExclude();
@@ -378,9 +335,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationAndAddCategoryWithLanguageSynchronization(): void
     {
         parent::localizeContentOfRelationAndAddCategoryWithLanguageSynchronization();
@@ -394,9 +349,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization(): void
     {
         parent::localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization();
@@ -412,9 +365,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeCategoryOfRelation(): void
     {
         // Create and publish translated page first
@@ -431,9 +382,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('[Translate to Dansk:] Category A', 'Category B'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentOfRelationToDifferentPage(): void
     {
         parent::moveContentOfRelationToDifferentPage();
@@ -447,9 +396,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesPublishAll/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesPublishAll/ActionTest.php
index 75a7babe98ff..e7d47d025989 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesPublishAll/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/ManyToMany/WorkspacesPublishAll/ActionTest.php
@@ -17,24 +17,21 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\ManyToMany\WorkspacesPublishAll;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\ManyToMany\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addCategoryRelation(): void
     {
         parent::addCategoryRelation();
@@ -48,9 +45,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A', 'Category B', 'Category A.A'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteCategoryRelation(): void
     {
         parent::deleteCategoryRelation();
@@ -67,9 +62,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C', 'Category A.A'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeCategoryRelationSorting(): void
     {
         parent::changeCategoryRelationSorting();
@@ -83,9 +76,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A', 'Category B'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndAddRelation(): void
     {
         parent::createContentAndAddRelation();
@@ -101,9 +92,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createCategoryAndAddRelation(): void
     {
         parent::createCategoryAndAddRelation();
@@ -119,9 +108,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCreateRelation(): void
     {
         parent::createContentAndCreateRelation();
@@ -137,9 +124,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createCategoryAndCreateRelation(): void
     {
         parent::createCategoryAndCreateRelation();
@@ -147,9 +132,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createCategoryNCreateRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentWithCategoryAndAddRelation(): void
     {
         parent::createContentWithCategoryAndAddRelation();
@@ -157,9 +140,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContentWCategoryNAddRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createCategoryWithContentAndAddRelation(): void
     {
         parent::createCategoryWithContentAndAddRelation();
@@ -167,9 +148,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createCategoryWContentNAddRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyCategoryOfRelation(): void
     {
         parent::modifyCategoryOfRelation();
@@ -183,9 +162,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Testing #1', 'Category B'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentOfRelation(): void
     {
         parent::modifyContentOfRelation();
@@ -198,9 +175,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyBothsOfRelation(): void
     {
         parent::modifyBothsOfRelation();
@@ -216,9 +191,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentOfRelation(): void
     {
         parent::deleteContentOfRelation();
@@ -231,9 +204,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteCategoryOfRelation(): void
     {
         parent::deleteCategoryOfRelation();
@@ -247,9 +218,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentOfRelation(): void
     {
         parent::copyContentOfRelation();
@@ -263,9 +232,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentToLanguageOfRelation(): void
     {
         parent::copyContentToLanguageOfRelation();
@@ -279,9 +246,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyCategoryOfRelation(): void
     {
         parent::copyCategoryOfRelation();
@@ -295,9 +260,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A', 'Category A (copy 1)'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyCategoryToLanguageOfRelation(): void
     {
         parent::copyCategoryToLanguageOfRelation();
@@ -313,9 +276,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         // ->setTable(self::TABLE_Category)->setField('title')->setValues('Category A', '[Translate to Dansk:] Category A'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelation(): void
     {
         parent::localizeContentOfRelation();
@@ -329,9 +290,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLanguageSynchronization(): void
     {
         parent::localizeContentOfRelationWithLanguageSynchronization();
@@ -345,9 +304,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLanguageExclude(): void
     {
         parent::localizeContentOfRelationWithLanguageExclude();
@@ -361,9 +318,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationAndAddCategoryWithLanguageSynchronization(): void
     {
         parent::localizeContentOfRelationAndAddCategoryWithLanguageSynchronization();
@@ -377,9 +332,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization(): void
     {
         parent::localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization();
@@ -394,9 +347,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeCategoryOfRelation(): void
     {
         // Create translated page first
@@ -412,9 +363,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('[Translate to Dansk:] Category A', 'Category B'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentOfRelationToDifferentPage(): void
     {
         parent::moveContentOfRelationToDifferentPage();
@@ -428,9 +377,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/Modify/ActionTest.php
index b26365c2e975..7d74957e25d0 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/Modify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/Modify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\Regular\Modify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Domain\Repository\PageRepository;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\Regular\AbstractActionTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
@@ -28,19 +29,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
  */
 final class ActionTest extends AbstractActionTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     * See DataSet/createContentRecords.csv
-     */
+    #[Test]
     public function createContents(): void
     {
         parent::createContents();
@@ -52,10 +48,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1', 'Testing #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/createContentForLanguageAll.csv
-     */
+    #[Test]
     public function createContentForLanguageAll(): void
     {
         // Create translated page first
@@ -71,10 +64,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Language set to all', '[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyContentRecord.csv
-     */
+    #[Test]
     public function modifyContent(): void
     {
         parent::modifyContent();
@@ -86,10 +76,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyTranslatedContent.csv
-     */
+    #[Test]
     public function modifyTranslatedContent(): void
     {
         // Create translated page first
@@ -103,10 +90,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing Translation #3'));
     }
 
-    /**
-     * @test
-     * See DataSet/deleteContentRecord.csv
-     */
+    #[Test]
     public function deleteContent(): void
     {
         parent::deleteContent();
@@ -120,10 +104,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/deleteLocalizedContentNDeleteContent.csv
-     */
+    #[Test]
     public function deleteLocalizedContentAndDeleteContent(): void
     {
         // Create translated page first
@@ -140,10 +121,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyContentRecord.csv
-     */
+    #[Test]
     public function copyContent(): void
     {
         parent::copyContent();
@@ -155,10 +133,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2 (copy 1)'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyContentToLanguage.csv
-     */
+    #[Test]
     public function copyContentToLanguage(): void
     {
         // Create translated page first
@@ -176,10 +151,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #3', '[Translate to Dansk:] Regular Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyContentToLanguageWSynchronization.csv
-     */
+    #[Test]
     public function copyContentToLanguageWithLanguageSynchronization(): void
     {
         // Create translated page first
@@ -197,10 +169,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #3', '[Translate to Dansk:] Regular Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyContentToLanguageWExclude.csv
-     */
+    #[Test]
     public function copyContentToLanguageWithLocalizationExclude(): void
     {
         // Create translated page first
@@ -218,10 +187,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #3', 'Regular Element #2 (copy 1)'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyContentToLanguageFromNonDefaultLanguage.csv
-     */
+    #[Test]
     public function copyContentToLanguageFromNonDefaultLanguage(): void
     {
         // Create translated page first
@@ -240,10 +206,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Deutsch:] [Translate to Dansk:] Regular Element #3'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyContentRecord.csv
-     */
+    #[Test]
     public function copyPasteContent(): void
     {
         parent::copyPasteContent();
@@ -255,10 +218,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentRecord.csv
-     */
+    #[Test]
     public function localizeContent(): void
     {
         // Create translated page first
@@ -273,10 +233,9 @@ final class ActionTest extends AbstractActionTestCase
     }
 
     /**
-     * @test
-     * See DataSet/localizeContentWithEmptyTcaIntegrityColumns.csv
      * @see \TYPO3\CMS\Core\Migrations\TcaMigration::sanitizeControlSectionIntegrity()
      */
+    #[Test]
     public function localizeContentWithEmptyTcaIntegrityColumns(): void
     {
         parent::localizeContentWithEmptyTcaIntegrityColumns();
@@ -288,10 +247,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentWSynchronization.csv
-     */
+    #[Test]
     public function localizeContentWithLanguageSynchronization(): void
     {
         // Create translated page first
@@ -305,10 +261,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentWSynchronizationHNull.csv
-     */
+    #[Test]
     public function localizeContentWithLanguageSynchronizationHavingNullValue(): void
     {
         // Create translated page first
@@ -322,10 +275,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentFromNonDefaultLanguage.csv
-     */
+    #[Test]
     public function localizeContentFromNonDefaultLanguage(): void
     {
         // Create translated page first
@@ -341,10 +291,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1', '[Translate to Deutsch:] [Translate to Dansk:] Regular Element #3'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentFromNonDefaultLanguageWSynchronizationDefault.csv
-     */
+    #[Test]
     public function localizeContentFromNonDefaultLanguageWithLanguageSynchronizationDefault(): void
     {
         // Create translated page first
@@ -360,10 +307,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentFromNonDefaultLanguageWSynchronizationSource.csv
-     */
+    #[Test]
     public function localizeContentFromNonDefaultLanguageWithLanguageSynchronizationSource(): void
     {
         // Create translated page first
@@ -379,18 +323,14 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1', 'Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentFromNonDefaultLanguageWithAllContentElements(): void
     {
         parent::localizeContentFromNonDefaultLanguageWithAllContentElements();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentFromNonDefaultLanguageWithAllContentElements.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentAfterMovedContent(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../DataSet/ImportFreeModeElements.csv');
@@ -398,10 +338,7 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentAfterMovedContent.csv');
     }
 
-    /**
-     * @test
-     * See DataSet/createLocalizedContent.csv
-     */
+    #[Test]
     public function createLocalizedContent(): void
     {
         // Create translated page first
@@ -416,10 +353,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Localized Testing'));
     }
 
-    /**
-     * @test
-     * See DataSet/createLocalizedContentWSynchronization.csv
-     */
+    #[Test]
     public function createLocalizedContentWithLanguageSynchronization(): void
     {
         // Create translated page first
@@ -434,10 +368,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing'));
     }
 
-    /**
-     * @test
-     * See DataSet/createLocalizedContentWExclude.csv
-     */
+    #[Test]
     public function createLocalizedContentWithLocalizationExclude(): void
     {
         // Create translated page first
@@ -452,10 +383,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing', '[Translate to Dansk:] Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/changeContentSorting.csv
-     */
+    #[Test]
     public function changeContentSorting(): void
     {
         parent::changeContentSorting();
@@ -467,10 +395,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/changeContentSortingAfterSelf.csv
-     */
+    #[Test]
     public function changeContentSortingAfterSelf(): void
     {
         parent::changeContentSortingAfterSelf();
@@ -482,10 +407,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/moveContentRecordToDifferentPage.csv
-     */
+    #[Test]
     public function moveContentToDifferentPage(): void
     {
         parent::moveContentToDifferentPage();
@@ -501,10 +423,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/movePasteContentToDifferentPage.csv
-     */
+    #[Test]
     public function movePasteContentToDifferentPage(): void
     {
         parent::movePasteContentToDifferentPage();
@@ -520,10 +439,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/moveContentRecordToDifferentPageAndChangeSorting.csv
-     */
+    #[Test]
     public function moveContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveContentToDifferentPageAndChangeSorting();
@@ -535,14 +451,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     * See DataSet/createPageRecord.csv
-     */
+    #[Test]
     public function createPage(): void
     {
         parent::createPage();
@@ -554,9 +463,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndSubPageAndSubPageContent(): void
     {
         parent::createPageAndSubPageAndSubPageContent();
@@ -568,10 +475,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1 #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/createPageRecordWithSlugOverrideConfiguration.csv
-     */
+    #[Test]
     public function createPageWithSlugOverrideConfiguration(): void
     {
         // set default configuration
@@ -600,10 +504,7 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPageWithSlugOverrideConfiguration.csv');
     }
 
-    /**
-     * @test
-     * See DataSet/createPageNContentWDefaults.csv
-     */
+    #[Test]
     public function createPageAndContentWithTcaDefaults(): void
     {
         parent::createPageAndContentWithTcaDefaults();
@@ -629,10 +530,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyPage.csv
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
@@ -644,10 +542,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/deletePageRecord.csv
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -657,10 +552,7 @@ final class ActionTest extends AbstractActionTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     * See DataSet/copyPage.csv
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
@@ -677,10 +569,8 @@ final class ActionTest extends AbstractActionTestCase
      * Values in l10n_source field are remapped to ids of newly copied records
      * e.g. record 314 has l10n_source = 315 and record 313 has l10n_source = 314
      * also note that 314 is NOT a record in the default language
-     *
-     * @test
-     * See DataSet/copyPageFreeMode.csv
      */
+    #[Test]
     public function copyPageFreeMode(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../DataSet/ImportFreeModeElements.csv');
@@ -693,10 +583,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Target'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageRecord.csv
-     */
+    #[Test]
     public function localizePage(): void
     {
         parent::localizePage();
@@ -708,10 +595,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('[Translate to Dansk:] Relations'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageAndUpdateRecordWithMinorChangesInFullRetrievedRecord.csv
-     */
+    #[Test]
     public function localizePageAndUpdateRecordWithMinorChangesInFullRetrievedRecord(): void
     {
         parent::localizePageAndUpdateRecordWithMinorChangesInFullRetrievedRecord();
@@ -723,10 +607,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeNCopyPage.csv
-     */
+    #[Test]
     public function localizeAndCopyPage(): void
     {
         parent::localizePage();
@@ -739,10 +620,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('[Translate to Dansk:] Relations'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizePageWSynchronization.csv
-     */
+    #[Test]
     public function localizePageWithLanguageSynchronization(): void
     {
         parent::localizePageWithLanguageSynchronization();
@@ -754,10 +632,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeNCopyPageWSynchronization.csv
-     */
+    #[Test]
     public function localizeAndCopyPageWithLanguageSynchronization(): void
     {
         parent::localizePageWithLanguageSynchronization();
@@ -770,9 +645,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeAndModifyTranslationAndCopyPageWithLanguageSynchronization(): void
     {
         parent::localizePageWithLanguageSynchronization();
@@ -782,9 +655,7 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeNModifyNCopyPageWSynchronization.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageAndContentsAndDeletePageLocalization(): void
     {
         // Create localized page and localize content elements first
@@ -792,91 +663,70 @@ final class ActionTest extends AbstractActionTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageAndContentsAndDeletePageLocalization.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeNestedPagesAndContents(): void
     {
         parent::localizeNestedPagesAndContents();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeNestedPagesAndContents.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyFalse(): void
     {
         parent::localizePageHiddenHideAtCopyFalse();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyFalse(): void
     {
         parent::localizePageNotHiddenHideAtCopyFalse();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyDisableHideAtCopyUnset(): void
     {
         parent::localizePageNotHiddenHideAtCopyDisableHideAtCopyUnset();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyNotDisableHideAtCopyUnset.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyDisableHideAtCopyUnset(): void
     {
         parent::localizePageHiddenHideAtCopyDisableHideAtCopyUnset();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyNotDisableHideAtCopyUnset.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyDisableHideAtCopySetToFalse(): void
     {
         parent::localizePageNotHiddenHideAtCopyDisableHideAtCopySetToFalse();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyDisableHideAtCopySetToFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyDisableHideAtCopySetToFalse(): void
     {
         parent::localizePageHiddenHideAtCopyDisableHideAtCopySetToFalse();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyDisableHideAtCopySetToFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyDisableHideAtCopySetToTrue(): void
     {
         parent::localizePageNotHiddenHideAtCopyDisableHideAtCopySetToTrue();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyDisableHideAtCopySetToTrue.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyDisableHideAtCopySetToTrue(): void
     {
         parent::localizePageHiddenHideAtCopyDisableHideAtCopySetToTrue();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyDisableHideAtCopySetToTrue.csv');
     }
 
-    /**
-     * @test
-     * See DataSet/changePageSorting.csv
-     */
+    #[Test]
     public function changePageSorting(): void
     {
         parent::changePageSorting();
@@ -890,10 +740,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/changePageSortingAfterSelf.csv
-     */
+    #[Test]
     public function changePageSortingAfterSelf(): void
     {
         parent::changePageSortingAfterSelf();
@@ -907,10 +754,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/movePageRecordToDifferentPage.csv
-     */
+    #[Test]
     public function movePageToDifferentPage(): void
     {
         parent::movePageToDifferentPage();
@@ -924,28 +768,21 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageToDifferentPageTwice(): void
     {
         parent::movePageToDifferentPageTwice();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedToDifferentPageTwice(): void
     {
         parent::movePageLocalizedToDifferentPageTwice();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     * See DataSet/movePageRecordToDifferentPageAndChangeSorting.csv
-     */
+    #[Test]
     public function movePageToDifferentPageAndChangeSorting(): void
     {
         parent::movePageToDifferentPageAndChangeSorting();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesDiscard/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesDiscard/ActionTest.php
index 7242a0e6c55d..583682040344 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesDiscard/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesDiscard/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\Regular\WorkspacesDiscard;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\Regular\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -24,18 +25,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContents(): void
     {
         parent::createContents();
@@ -47,9 +44,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContents.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCopyContent(): void
     {
         parent::createContentAndCopyContent();
@@ -58,9 +53,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContentAndCopyContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndLocalize(): void
     {
         parent::createContentAndLocalize();
@@ -69,9 +62,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContentAndLocalize.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContent(): void
     {
         parent::modifyContent();
@@ -79,9 +70,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hideContent(): void
     {
         parent::hideContent();
@@ -89,9 +78,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/hideContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hideContentAndMoveToDifferentPage(): void
     {
         parent::hideContent();
@@ -100,9 +87,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/hideContentAndMoveToDifferentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContent(): void
     {
         parent::deleteContent();
@@ -110,9 +95,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteLocalizedContentAndDeleteContent(): void
     {
         // Create translated page first
@@ -122,9 +105,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteLocalizedContentNDeleteContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContent(): void
     {
         parent::copyContent();
@@ -132,9 +113,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentToLanguage(): void
     {
         // Create translated page first
@@ -144,9 +123,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyContentToLanguage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentToLanguageFromNonDefaultLanguage(): void
     {
         // Create translated page first
@@ -157,9 +134,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyContentToLanguageFromNonDefaultLanguage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContent(): void
     {
         // Create translated page first
@@ -169,9 +144,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentAfterMovedContent(): void
     {
         parent::localizeContentAfterMovedContent();
@@ -179,9 +152,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentAfterMovedContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentAfterMovedInLiveContent(): void
     {
         parent::localizeContentAfterMovedInLiveContent();
@@ -189,9 +160,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentAfterMovedInLiveContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentFromNonDefaultLanguage(): void
     {
         // Create translated page first
@@ -202,9 +171,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentFromNonDefaultLanguage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSorting(): void
     {
         parent::changeContentSorting();
@@ -212,9 +179,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changeContentSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSortingAfterSelf(): void
     {
         parent::changeContentSortingAfterSelf();
@@ -222,9 +187,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changeContentSortingAfterSelf.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSortingAndDeleteMovedRecord(): void
     {
         parent::changeContentSortingAndDeleteMovedRecord();
@@ -234,9 +197,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changeContentSortingNDeleteMovedRecord.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSortingAndDeleteLiveRecord(): void
     {
         parent::changeContentSortingAndDeleteLiveRecord();
@@ -246,9 +207,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changeContentSortingNDeleteLiveRecord.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPage(): void
     {
         parent::moveContentToDifferentPage();
@@ -256,9 +215,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveContentToDifferentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveContentToDifferentPageAndChangeSorting();
@@ -268,9 +225,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveContentToDifferentPageNChangeSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPageAndHide(): void
     {
         parent::moveContentToDifferentPageAndHide();
@@ -278,9 +233,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveContentToDifferentPageAndHide.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveLocalizedContentToDifferentPage(): void
     {
         parent::moveLocalizedContentToDifferentPage();
@@ -326,13 +279,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #3'));
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createPage(): void
     {
         parent::createPage();
@@ -340,9 +287,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndSubPageAndSubPageContent(): void
     {
         parent::createPageAndSubPageAndSubPageContent();
@@ -350,9 +295,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPageAndSubPageAndSubPageContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
@@ -360,9 +303,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -370,9 +311,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deletePage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentAndPage(): void
     {
         parent::deleteContentAndPage();
@@ -380,9 +319,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteContentAndPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageAndContentsAndDeletePageLocalization(): void
     {
         // Create localized page and localize content elements first
@@ -392,9 +329,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageAndContentsAndDeletePageLocalization.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeNestedPagesAndContents(): void
     {
         parent::localizeNestedPagesAndContents();
@@ -403,9 +338,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeNestedPagesAndContents.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
@@ -413,9 +346,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPageFreeMode(): void
     {
         parent::copyPageFreeMode();
@@ -423,9 +354,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyPageFreeMode.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePage(): void
     {
         parent::localizePage();
@@ -433,9 +362,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyFalse(): void
     {
         parent::localizePageHiddenHideAtCopyFalse();
@@ -443,9 +370,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyFalse(): void
     {
         parent::localizePageNotHiddenHideAtCopyFalse();
@@ -453,9 +378,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyDisableHideAtCopyUnset(): void
     {
         parent::localizePageNotHiddenHideAtCopyDisableHideAtCopyUnset();
@@ -463,9 +386,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyDisableHideAtCopyUnset.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyDisableHideAtCopyUnset(): void
     {
         parent::localizePageHiddenHideAtCopyDisableHideAtCopyUnset();
@@ -473,9 +394,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyDisableHideAtCopyUnset.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyDisableHideAtCopySetToFalse(): void
     {
         parent::localizePageNotHiddenHideAtCopyDisableHideAtCopySetToFalse();
@@ -483,9 +402,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyDisableHideAtCopySetToFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyDisableHideAtCopySetToFalse(): void
     {
         parent::localizePageHiddenHideAtCopyDisableHideAtCopySetToFalse();
@@ -493,9 +410,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyDisableHideAtCopySetToFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyDisableHideAtCopySetToTrue(): void
     {
         parent::localizePageNotHiddenHideAtCopyDisableHideAtCopySetToTrue();
@@ -503,9 +418,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyDisableHideAtCopySetToTrue.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyDisableHideAtCopySetToTrue(): void
     {
         parent::localizePageHiddenHideAtCopyDisableHideAtCopySetToTrue();
@@ -513,9 +426,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyDisableHideAtCopySetToTrue.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndChangePageSorting(): void
     {
         parent::createPageAndChangePageSorting();
@@ -523,9 +434,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPageAndChangePageSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndMoveCreatedPage(): void
     {
         parent::createPageAndMoveCreatedPage();
@@ -533,9 +442,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPageAndMoveCreatedPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changePageSorting(): void
     {
         parent::changePageSorting();
@@ -543,9 +450,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changePageSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changePageSortingAfterSelf(): void
     {
         parent::changePageSortingAfterSelf();
@@ -553,9 +458,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changePageSortingAfterSelf.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageToDifferentPage(): void
     {
         parent::movePageToDifferentPage();
@@ -563,9 +466,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageToDifferentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageToDifferentPageTwice(): void
     {
         parent::movePageToDifferentPageTwice();
@@ -573,9 +474,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedToDifferentPageTwice(): void
     {
         parent::movePageLocalizedToDifferentPageTwice();
@@ -583,9 +482,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedInLiveToDifferentPageTwice(): void
     {
         parent::movePageLocalizedInLiveToDifferentPageTwice();
@@ -593,9 +490,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedInLiveToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedInLiveWorkspaceChangedToDifferentPageTwice(): void
     {
         parent::movePageLocalizedInLiveWorkspaceChangedToDifferentPageTwice();
@@ -603,9 +498,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedInLiveWorkspaceChangedToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedInLiveWorkspaceDeletedToDifferentPageTwice(): void
     {
         parent::movePageLocalizedInLiveWorkspaceDeletedToDifferentPageTwice();
@@ -613,9 +506,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedInLiveWorkspaceDeletedToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageToDifferentPageAndChangeSorting(): void
     {
         parent::movePageToDifferentPageAndChangeSorting();
@@ -626,10 +517,10 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
     }
 
     /**
-     * @test
      * @see https://forge.typo3.org/issues/33104
      * @see https://forge.typo3.org/issues/55573
      */
+    #[Test]
     public function movePageToDifferentPageAndCreatePageAfterMovedPage(): void
     {
         parent::movePageToDifferentPageAndCreatePageAfterMovedPage();
@@ -642,10 +533,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
     /*************************************
      * Copying page contents and sub-pages
      *************************************/
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCopyDraftPage(): void
     {
         parent::createContentAndCopyDraftPage();
@@ -656,9 +544,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContentAndCopyDraftPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndCopyDraftParentPage(): void
     {
         parent::createPageAndCopyDraftParentPage();
@@ -668,9 +554,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPageAndCopyDraftParentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createNestedPagesAndCopyDraftParentPage(): void
     {
         parent::createNestedPagesAndCopyDraftParentPage();
@@ -679,9 +563,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createNestedPagesAndCopyDraftParentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPlaceholdersAndDeleteDraftParentPage(): void
     {
         parent::createPlaceholdersAndDeleteDraftParentPage();
@@ -691,9 +573,8 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
 
     /**
      * Test does not make sense in Modify, Publish and PublishAll
-     *
-     * @test
      */
+    #[Test]
     public function deletingDefaultLanguageElementDiscardsConnectedLocalizedElement(): void
     {
         // Switch to live workspace and localize page in live
@@ -718,9 +599,8 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
      * translated to language 2 again. Both records should be discarded when discarding live element.
      *
      * Test does not make sense in Modify, Publish and PublishAll.
-     *
-     * @test
      */
+    #[Test]
     public function deletingDefaultLanguageElementDiscardsConnectedLocalizedElementChain(): void
     {
         // Switch to live workspace and localize page in live
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesModify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesModify/ActionTest.php
index f98fc85b2ac0..643543bbc553 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesModify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesModify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\Regular\WorkspacesModify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\Regular\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -24,18 +25,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContents(): void
     {
         parent::createContents();
@@ -50,9 +47,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1', 'Testing #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCopyContent(): void
     {
         parent::createContentAndCopyContent();
@@ -67,9 +62,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1', 'Testing #1 (copy 1)'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndLocalize(): void
     {
         parent::createContentAndLocalize();
@@ -84,9 +77,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContent(): void
     {
         parent::modifyContent();
@@ -101,9 +92,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hideContent(): void
     {
         parent::hideContent();
@@ -118,9 +107,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hideContentAndMoveToDifferentPage(): void
     {
         parent::hideContent();
@@ -145,9 +132,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContent(): void
     {
         parent::deleteContent();
@@ -164,9 +149,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteLocalizedContentAndDeleteContent(): void
     {
         // Create translated page first
@@ -185,9 +168,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContent(): void
     {
         parent::copyContent();
@@ -202,9 +183,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2 (copy 1)'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentToLanguage(): void
     {
         // Create translated page first
@@ -225,9 +204,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #3', '[Translate to Dansk:] Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentToLanguageFromNonDefaultLanguage(): void
     {
         // Create translated page first
@@ -249,9 +226,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Deutsch:] [Translate to Dansk:] Regular Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContent(): void
     {
         // Create translated page first
@@ -268,18 +243,14 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentAfterMovedContent(): void
     {
         parent::localizeContentAfterMovedContent();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentAfterMovedContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentAfterMovedInLiveContent(): void
     {
         parent::localizeContentAfterMovedInLiveContent();
@@ -287,9 +258,9 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
     }
 
     /**
-     * @test
      * @see \TYPO3\CMS\Core\Migrations\TcaMigration::sanitizeControlSectionIntegrity()
      */
+    #[Test]
     public function localizeContentWithEmptyTcaIntegrityColumns(): void
     {
         parent::localizeContentWithEmptyTcaIntegrityColumns();
@@ -303,9 +274,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentWithHideAtCopy(): void
     {
         // Create translated page first
@@ -322,9 +291,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentFromNonDefaultLanguage(): void
     {
         // Create translated page first
@@ -343,19 +310,14 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1', '[Translate to Deutsch:] [Translate to Dansk:] Regular Element #3'));
     }
 
-    /**
-     * @test
-     * Test does not make sense for Publish, PublishAll and Discard
-     */
+    #[Test]
     public function localizeContentFromNonDefaultLanguageWithAllContentElements(): void
     {
         parent::localizeContentFromNonDefaultLanguageWithAllContentElements();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentFromNonDefaultLanguageWithAllContentElements.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSorting(): void
     {
         parent::changeContentSorting();
@@ -370,9 +332,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSortingAfterSelf(): void
     {
         parent::changeContentSortingAfterSelf();
@@ -388,9 +348,9 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
     }
 
     /**
-     * @test
      * @todo: Publish and PublishAll for this are missing - TF throws an exception on publish due to deleted state
      */
+    #[Test]
     public function changeContentSortingAndDeleteMovedRecord(): void
     {
         parent::changeContentSortingAndDeleteMovedRecord();
@@ -405,9 +365,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSortingAndDeleteLiveRecord(): void
     {
         parent::changeContentSortingAndDeleteLiveRecord();
@@ -424,9 +382,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPage(): void
     {
         parent::moveContentToDifferentPage();
@@ -448,9 +404,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveContentToDifferentPageAndChangeSorting();
@@ -465,9 +419,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPageAndHide(): void
     {
         parent::moveContentToDifferentPageAndHide();
@@ -482,9 +434,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveLocalizedContentToDifferentPage(): void
     {
         parent::moveLocalizedContentToDifferentPage();
@@ -525,13 +475,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #3'));
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createPage(): void
     {
         parent::createPage();
@@ -546,9 +490,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndSubPageAndSubPageContent(): void
     {
         parent::createPageAndSubPageAndSubPageContent();
@@ -563,9 +505,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1 #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndContentWithTcaDefaults(): void
     {
         parent::createPageAndContentWithTcaDefaults();
@@ -594,9 +534,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
@@ -611,9 +549,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -626,9 +562,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentAndPage(): void
     {
         parent::deleteContentAndPage();
@@ -641,10 +575,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     * Publish tests missing since TF throws exception if publishing deleted records
-     */
+    #[Test]
     public function localizePageAndContentsAndDeletePageLocalization(): void
     {
         // Create localized page and localize content elements first
@@ -658,18 +589,14 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeNestedPagesAndContents(): void
     {
         parent::localizeNestedPagesAndContents();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeNestedPagesAndContents.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
@@ -684,9 +611,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Relations'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPageFreeMode(): void
     {
         parent::copyPageFreeMode();
@@ -703,9 +628,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #10'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePage(): void
     {
         parent::localizePage();
@@ -720,99 +643,77 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('[Translate to Dansk:] Relations'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyFalse(): void
     {
         parent::localizePageHiddenHideAtCopyFalse();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyFalse(): void
     {
         parent::localizePageNotHiddenHideAtCopyFalse();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyDisableHideAtCopyUnset(): void
     {
         parent::localizePageNotHiddenHideAtCopyDisableHideAtCopyUnset();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyDisableHideAtCopyUnset.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyDisableHideAtCopyUnset(): void
     {
         parent::localizePageHiddenHideAtCopyDisableHideAtCopyUnset();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyDisableHideAtCopyUnset.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyDisableHideAtCopySetToFalse(): void
     {
         parent::localizePageNotHiddenHideAtCopyDisableHideAtCopySetToFalse();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyDisableHideAtCopySetToFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyDisableHideAtCopySetToFalse(): void
     {
         parent::localizePageHiddenHideAtCopyDisableHideAtCopySetToFalse();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyDisableHideAtCopySetToFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyDisableHideAtCopySetToTrue(): void
     {
         parent::localizePageNotHiddenHideAtCopyDisableHideAtCopySetToTrue();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyDisableHideAtCopySetToTrue.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyDisableHideAtCopySetToTrue(): void
     {
         parent::localizePageHiddenHideAtCopyDisableHideAtCopySetToTrue();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyDisableHideAtCopySetToTrue.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndChangePageSorting(): void
     {
         parent::createPageAndChangePageSorting();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPageAndChangePageSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndMoveCreatedPage(): void
     {
         parent::createPageAndMoveCreatedPage();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPageAndMoveCreatedPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changePageSorting(): void
     {
         parent::changePageSorting();
@@ -829,9 +730,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changePageSortingAfterSelf(): void
     {
         parent::changePageSortingAfterSelf();
@@ -848,9 +747,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageToDifferentPage(): void
     {
         parent::movePageToDifferentPage();
@@ -867,54 +764,42 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageToDifferentPageTwice(): void
     {
         parent::movePageToDifferentPageTwice();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedToDifferentPageTwice(): void
     {
         parent::movePageLocalizedToDifferentPageTwice();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedInLiveToDifferentPageTwice(): void
     {
         parent::movePageLocalizedInLiveToDifferentPageTwice();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedInLiveToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedInLiveWorkspaceChangedToDifferentPageTwice(): void
     {
         parent::movePageLocalizedInLiveWorkspaceChangedToDifferentPageTwice();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedInLiveWorkspaceChangedToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedInLiveWorkspaceDeletedToDifferentPageTwice(): void
     {
         parent::movePageLocalizedInLiveWorkspaceDeletedToDifferentPageTwice();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedInLiveWorkspaceDeletedToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageToDifferentPageAndChangeSorting(): void
     {
         parent::movePageToDifferentPageAndChangeSorting();
@@ -940,10 +825,10 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
     }
 
     /**
-     * @test
      * @see https://forge.typo3.org/issues/33104
      * @see https://forge.typo3.org/issues/55573
      */
+    #[Test]
     public function movePageToDifferentPageAndCreatePageAfterMovedPage(): void
     {
         parent::movePageToDifferentPageAndCreatePageAfterMovedPage();
@@ -962,10 +847,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
     /*************************************
      * Copying page contents and sub-pages
      *************************************/
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCopyDraftPage(): void
     {
         parent::createContentAndCopyDraftPage();
@@ -982,10 +864,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(static::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * Test does not make sense for Publish, PublishAll and Discard
-     */
+    #[Test]
     public function createContentAndCopyLivePage(): void
     {
         parent::createContentAndCopyLivePage();
@@ -1004,9 +883,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(static::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndCopyDraftParentPage(): void
     {
         parent::createPageAndCopyDraftParentPage();
@@ -1023,10 +900,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(static::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * Test does not make sense for Publish, PublishAll and Discard
-     */
+    #[Test]
     public function createPageAndCopyLiveParentPage(): void
     {
         parent::createPageAndCopyLiveParentPage();
@@ -1045,10 +919,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(static::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * Skipping test in Publish but it is available in PublishAll
-     */
+    #[Test]
     public function createNestedPagesAndCopyDraftParentPage(): void
     {
         parent::createNestedPagesAndCopyDraftParentPage();
@@ -1065,10 +936,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(static::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * Test does not make sense for Publish, PublishAll and Discard
-     */
+    #[Test]
     public function createNestedPagesAndCopyLiveParentPage(): void
     {
         parent::createNestedPagesAndCopyLiveParentPage();
@@ -1087,10 +955,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(static::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * Skipped test in Publish, PublishAll and Discard: It's only interesting if the copy operation copies the deleted record
-     */
+    #[Test]
     public function deleteContentAndCopyDraftPage(): void
     {
         parent::deleteContentAndCopyDraftPage();
@@ -1107,10 +972,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     * Skipped test in Publish, PublishAll and Discard: It's only interesting if the copy operation copies the deleted record
-     */
+    #[Test]
     public function deleteContentAndCopyLivePage(): void
     {
         parent::deleteContentAndCopyLivePage();
@@ -1129,10 +991,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     * Test skipped in publish and discard, but exists in PublishAll
-     */
+    #[Test]
     public function changeContentSortingAndCopyDraftPage(): void
     {
         parent::changeContentSortingAndCopyDraftPage();
@@ -1149,10 +1008,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1'));
     }
 
-    /**
-     * @test
-     * Test does not make sense for Publish, PublishAll and Discard
-     */
+    #[Test]
     public function changeContentSortingAndCopyLivePage(): void
     {
         parent::changeContentSortingAndCopyLivePage();
@@ -1171,10 +1027,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1'));
     }
 
-    /**
-     * @test
-     * Skipped test in Publish, PublishAll and Discard: It's only interesting if the move operation does sane things
-     */
+    #[Test]
     public function moveContentAndCopyDraftPage(): void
     {
         parent::moveContentAndCopyDraftPage();
@@ -1193,10 +1046,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #0'));
     }
 
-    /**
-     * @test
-     * Test does not make sense for Publish, PublishAll and Discard
-     */
+    #[Test]
     public function moveContentAndCopyLivePage(): void
     {
         parent::moveContentAndCopyLivePage();
@@ -1219,29 +1069,21 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #0'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPlaceholdersAndDeleteDraftParentPage(): void
     {
         parent::createPlaceholdersAndDeleteDraftParentPage();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPlaceholdersAndDeleteDraftParentPage.csv');
     }
 
-    /**
-     * @test
-     * Test does not make much sense in Publish and Discard and is skipped there
-     */
+    #[Test]
     public function createPlaceholdersAndDeleteLiveParentPage(): void
     {
         parent::createPlaceholdersAndDeleteLiveParentPage();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPlaceholdersAndDeleteLiveParentPage.csv');
     }
 
-    /**
-     * @test
-     * Test does not make sense in Publish, PublishAll and Discard scenarios and is skipped there
-     */
+    #[Test]
     public function createLocalizedNotHiddenWorkspaceContentHiddenInLive(): void
     {
         // Create translated page first
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesPublish/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesPublish/ActionTest.php
index 638f2a1a18c1..13d189ed03eb 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesPublish/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesPublish/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\Regular\WorkspacesPublish;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\Regular\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -24,19 +25,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     * See DataSet/createContentRecords.csv
-     */
+    #[Test]
     public function createContents(): void
     {
         parent::createContents();
@@ -53,9 +49,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1', 'Testing #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCopyContent(): void
     {
         parent::createContentAndCopyContent();
@@ -69,10 +63,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1', 'Testing #1 (copy 1)'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyContentRecord.csv
-     */
+    #[Test]
     public function modifyContent(): void
     {
         parent::modifyContent();
@@ -85,9 +76,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hideContent(): void
     {
         parent::hideContent();
@@ -103,9 +92,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hideContentAndMoveToDifferentPage(): void
     {
         parent::hideContent();
@@ -131,9 +118,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContent(): void
     {
         parent::deleteContent();
@@ -148,9 +133,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteLocalizedContentAndDeleteContent(): void
     {
         // this test will not rely on a translated page, because it only tests the act of publishing.
@@ -170,9 +153,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #3', '[Translate to Dansk:] Regular Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContent(): void
     {
         parent::copyContent();
@@ -185,9 +166,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2 (copy 1)'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentToLanguage(): void
     {
         // Create and publish translated page first
@@ -207,9 +186,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #3', '[Translate to Dansk:] Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentToLanguageFromNonDefaultLanguage(): void
     {
         // Create and publish translated page first
@@ -229,9 +206,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Deutsch:] [Translate to Dansk:] Regular Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContent(): void
     {
         // Create and publish translated page first
@@ -247,9 +222,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentAfterMovedContent(): void
     {
         parent::localizeContentAfterMovedContent();
@@ -257,9 +230,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentAfterMovedContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentAfterMovedInLiveContent(): void
     {
         parent::localizeContentAfterMovedInLiveContent();
@@ -267,9 +238,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentAfterMovedInLiveContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentFromNonDefaultLanguage(): void
     {
         // Create and publish translated page first
@@ -285,9 +254,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1', '[Translate to Deutsch:] [Translate to Dansk:] Regular Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSorting(): void
     {
         parent::changeContentSorting();
@@ -300,9 +267,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSortingAfterSelf(): void
     {
         parent::changeContentSortingAfterSelf();
@@ -318,9 +283,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPage(): void
     {
         parent::moveContentToDifferentPage();
@@ -337,9 +300,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveContentToDifferentPageAndChangeSorting();
@@ -354,9 +315,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPageAndHide(): void
     {
         parent::moveContentToDifferentPageAndHide();
@@ -372,9 +331,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveLocalizedContentToDifferentPage(): void
     {
         parent::moveLocalizedContentToDifferentPage();
@@ -428,13 +385,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #3'));
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createPage(): void
     {
         parent::createPage();
@@ -447,9 +398,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndSubPageAndSubPageContent(): void
     {
         parent::createPageAndSubPageAndSubPageContent();
@@ -466,9 +415,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1 #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
@@ -481,9 +428,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -496,9 +441,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentAndPage(): void
     {
         parent::deleteContentAndPage();
@@ -511,9 +454,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeNestedPagesAndContents(): void
     {
         parent::localizeNestedPagesAndContents();
@@ -522,9 +463,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeNestedPagesAndContents.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
@@ -542,9 +481,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Relations'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPageFreeMode(): void
     {
         parent::copyPageFreeMode();
@@ -564,9 +501,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #10'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePage(): void
     {
         parent::localizePage();
@@ -579,9 +514,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('[Translate to Dansk:] Relations'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyFalse(): void
     {
         parent::localizePageHiddenHideAtCopyFalse();
@@ -589,9 +522,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyFalse(): void
     {
         parent::localizePageNotHiddenHideAtCopyFalse();
@@ -599,9 +530,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyDisableHideAtCopyUnset(): void
     {
         parent::localizePageNotHiddenHideAtCopyDisableHideAtCopyUnset();
@@ -609,9 +538,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyDisableHideAtCopyUnset.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyDisableHideAtCopyUnset(): void
     {
         parent::localizePageHiddenHideAtCopyDisableHideAtCopyUnset();
@@ -619,9 +546,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyDisableHideAtCopyUnset.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyDisableHideAtCopySetToFalse(): void
     {
         parent::localizePageNotHiddenHideAtCopyDisableHideAtCopySetToFalse();
@@ -629,9 +554,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyDisableHideAtCopySetToFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyDisableHideAtCopySetToFalse(): void
     {
         parent::localizePageHiddenHideAtCopyDisableHideAtCopySetToFalse();
@@ -639,9 +562,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyDisableHideAtCopySetToFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyDisableHideAtCopySetToTrue(): void
     {
         parent::localizePageNotHiddenHideAtCopyDisableHideAtCopySetToTrue();
@@ -649,9 +570,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyDisableHideAtCopySetToTrue.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyDisableHideAtCopySetToTrue(): void
     {
         parent::localizePageHiddenHideAtCopyDisableHideAtCopySetToTrue();
@@ -659,9 +578,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyDisableHideAtCopySetToTrue.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndChangePageSorting(): void
     {
         parent::createPageAndChangePageSorting();
@@ -669,9 +586,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPageAndChangePageSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndMoveCreatedPage(): void
     {
         parent::createPageAndMoveCreatedPage();
@@ -679,9 +594,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPageAndMoveCreatedPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changePageSorting(): void
     {
         parent::changePageSorting();
@@ -696,9 +609,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changePageSortingAfterSelf(): void
     {
         parent::changePageSortingAfterSelf();
@@ -713,9 +624,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageToDifferentPage(): void
     {
         parent::movePageToDifferentPage();
@@ -730,9 +639,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageToDifferentPageTwice(): void
     {
         parent::movePageToDifferentPageTwice();
@@ -740,9 +647,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedToDifferentPageTwice(): void
     {
         parent::movePageLocalizedToDifferentPageTwice();
@@ -750,9 +655,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedInLiveToDifferentPageTwice(): void
     {
         parent::movePageLocalizedInLiveToDifferentPageTwice();
@@ -760,9 +663,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedInLiveToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedInLiveWorkspaceChangedToDifferentPageTwice(): void
     {
         parent::movePageLocalizedInLiveWorkspaceChangedToDifferentPageTwice();
@@ -770,9 +671,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedInLiveWorkspaceChangedToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedInLiveWorkspaceDeletedToDifferentPageTwice(): void
     {
         parent::movePageLocalizedInLiveWorkspaceDeletedToDifferentPageTwice();
@@ -780,9 +679,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedInLiveWorkspaceDeletedToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageToDifferentPageAndChangeSorting(): void
     {
         parent::movePageToDifferentPageAndChangeSorting();
@@ -805,10 +702,10 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
     }
 
     /**
-     * @test
      * @see https://forge.typo3.org/issues/33104
      * @see https://forge.typo3.org/issues/55573
      */
+    #[Test]
     public function movePageToDifferentPageAndCreatePageAfterMovedPage(): void
     {
         parent::movePageToDifferentPageAndCreatePageAfterMovedPage();
@@ -824,9 +721,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Target', 'Testing #1', 'DataHandlerTest'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSortingAndCopyDraftPage(): void
     {
         parent::changeContentSortingAndCopyDraftPage();
@@ -834,9 +729,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changeContentSortingAndCopyDraftPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCopyDraftPage(): void
     {
         parent::createContentAndCopyDraftPage();
@@ -855,9 +748,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(static::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndLocalize(): void
     {
         parent::createContentAndLocalize();
@@ -875,9 +766,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndCopyDraftParentPage(): void
     {
         parent::createPageAndCopyDraftParentPage();
@@ -887,9 +776,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPageAndCopyDraftParentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPlaceholdersAndDeleteDraftParentPage(): void
     {
         parent::createPlaceholdersAndDeleteDraftParentPage();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesPublishAll/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesPublishAll/ActionTest.php
index d9dfb9098e0d..06ed993bf32c 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesPublishAll/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/Regular/WorkspacesPublishAll/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\Regular\WorkspacesPublishAll;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\Regular\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -24,19 +25,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     * See DataSet/createContentRecords.csv
-     */
+    #[Test]
     public function createContents(): void
     {
         parent::createContents();
@@ -49,9 +45,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1', 'Testing #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCopyContent(): void
     {
         parent::createContentAndCopyContent();
@@ -64,10 +58,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1', 'Testing #1 (copy 1)'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyContentRecord.csv
-     */
+    #[Test]
     public function modifyContent(): void
     {
         parent::modifyContent();
@@ -80,9 +71,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hideContent(): void
     {
         parent::hideContent();
@@ -98,9 +87,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hideContentAndMoveToDifferentPage(): void
     {
         parent::hideContent();
@@ -126,9 +113,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContent(): void
     {
         parent::deleteContent();
@@ -143,9 +128,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteLocalizedContentAndDeleteContent(): void
     {
         // Create translated page first
@@ -162,9 +145,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContent(): void
     {
         parent::copyContent();
@@ -177,9 +158,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2 (copy 1)'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentToLanguage(): void
     {
         // Create translated page first
@@ -198,9 +177,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #3', '[Translate to Dansk:] Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentToLanguageFromNonDefaultLanguage(): void
     {
         // Create translated page first
@@ -219,9 +196,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Deutsch:] [Translate to Dansk:] Regular Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContent(): void
     {
         // Create translated page first
@@ -236,9 +211,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #1', '[Translate to Dansk:] Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentAfterMovedContent(): void
     {
         parent::localizeContentAfterMovedContent();
@@ -246,9 +219,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentAfterMovedContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentAfterMovedInLiveContent(): void
     {
         parent::localizeContentAfterMovedInLiveContent();
@@ -256,9 +227,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentAfterMovedInLiveContent.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentFromNonDefaultLanguage(): void
     {
         // Create translated page first
@@ -273,9 +242,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1', '[Translate to Deutsch:] [Translate to Dansk:] Regular Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSorting(): void
     {
         parent::changeContentSorting();
@@ -288,9 +255,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSortingAfterSelf(): void
     {
         parent::changeContentSortingAfterSelf();
@@ -303,9 +268,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPage(): void
     {
         parent::moveContentToDifferentPage();
@@ -322,9 +285,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPageAndChangeSorting(): void
     {
         parent::moveContentToDifferentPageAndChangeSorting();
@@ -337,9 +298,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentToDifferentPageAndHide(): void
     {
         parent::moveContentToDifferentPageAndHide();
@@ -355,9 +314,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveLocalizedContentToDifferentPage(): void
     {
         parent::moveLocalizedContentToDifferentPage();
@@ -397,13 +354,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Regular Element #3'));
     }
 
-    /**
-     * Page records
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function createPage(): void
     {
         parent::createPage();
@@ -416,9 +367,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndSubPageAndSubPageContent(): void
     {
         parent::createPageAndSubPageAndSubPageContent();
@@ -431,9 +380,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1 #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyPage(): void
     {
         parent::modifyPage();
@@ -446,9 +393,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletePage(): void
     {
         parent::deletePage();
@@ -461,9 +406,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentAndPage(): void
     {
         parent::deleteContentAndPage();
@@ -476,9 +419,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageAndContentsAndDeletePageLocalization(): void
     {
         // Create localized page and localize content elements first
@@ -493,9 +434,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         self::assertEquals(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeNestedPagesAndContents(): void
     {
         parent::localizeNestedPagesAndContents();
@@ -503,9 +442,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeNestedPagesAndContents.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPage(): void
     {
         parent::copyPage();
@@ -518,9 +455,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Relations'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyPageFreeMode(): void
     {
         parent::copyPageFreeMode();
@@ -535,9 +470,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #10'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePage(): void
     {
         parent::localizePage();
@@ -550,9 +483,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('[Translate to Dansk:] Relations'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyFalse(): void
     {
         parent::localizePageHiddenHideAtCopyFalse();
@@ -560,9 +491,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyFalse(): void
     {
         parent::localizePageNotHiddenHideAtCopyFalse();
@@ -570,9 +499,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyDisableHideAtCopyUnset(): void
     {
         parent::localizePageNotHiddenHideAtCopyDisableHideAtCopyUnset();
@@ -580,9 +507,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyDisableHideAtCopyUnset.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyDisableHideAtCopyUnset(): void
     {
         parent::localizePageHiddenHideAtCopyDisableHideAtCopyUnset();
@@ -590,9 +515,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyDisableHideAtCopyUnset.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyDisableHideAtCopySetToFalse(): void
     {
         parent::localizePageNotHiddenHideAtCopyDisableHideAtCopySetToFalse();
@@ -600,9 +523,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyDisableHideAtCopySetToFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyDisableHideAtCopySetToFalse(): void
     {
         parent::localizePageHiddenHideAtCopyDisableHideAtCopySetToFalse();
@@ -610,9 +531,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyDisableHideAtCopySetToFalse.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageNotHiddenHideAtCopyDisableHideAtCopySetToTrue(): void
     {
         parent::localizePageNotHiddenHideAtCopyDisableHideAtCopySetToTrue();
@@ -620,9 +539,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageNotHiddenHideAtCopyDisableHideAtCopySetToTrue.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizePageHiddenHideAtCopyDisableHideAtCopySetToTrue(): void
     {
         parent::localizePageHiddenHideAtCopyDisableHideAtCopySetToTrue();
@@ -630,11 +547,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizePageHiddenHideAtCopyDisableHideAtCopySetToTrue.csv');
     }
 
-    /**
-     * @test
-     * This test creates a page on pid=88 (unlike other tests) and moves the new draft page on that exact level, in order to only modify the "sorting"
-     * and not the "pid" setting.
-     */
+    #[Test]
     public function createPageAndChangePageSorting(): void
     {
         parent::createPageAndChangePageSorting();
@@ -642,10 +555,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPageAndChangePageSorting.csv');
     }
 
-    /**
-     * @test
-     * This change creates a page on pid=89 and moves the page one level up (= we check the pid value of both placeholder + versioned record).
-     */
+    #[Test]
     public function createPageAndMoveCreatedPage(): void
     {
         parent::createPageAndMoveCreatedPage();
@@ -653,9 +563,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPageAndMoveCreatedPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changePageSorting(): void
     {
         parent::changePageSorting();
@@ -670,9 +578,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changePageSortingAfterSelf(): void
     {
         parent::changePageSortingAfterSelf();
@@ -687,9 +593,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageToDifferentPage(): void
     {
         parent::movePageToDifferentPage();
@@ -704,9 +608,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Regular Element #1', 'Regular Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageToDifferentPageTwice(): void
     {
         parent::movePageToDifferentPageTwice();
@@ -714,9 +616,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedToDifferentPageTwice(): void
     {
         parent::movePageLocalizedToDifferentPageTwice();
@@ -724,9 +624,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedInLiveToDifferentPageTwice(): void
     {
         parent::movePageLocalizedInLiveToDifferentPageTwice();
@@ -734,9 +632,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedInLiveToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedInLiveWorkspaceChangedToDifferentPageTwice(): void
     {
         parent::movePageLocalizedInLiveWorkspaceChangedToDifferentPageTwice();
@@ -744,9 +640,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedInLiveWorkspaceChangedToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageLocalizedInLiveWorkspaceDeletedToDifferentPageTwice(): void
     {
         parent::movePageLocalizedInLiveWorkspaceDeletedToDifferentPageTwice();
@@ -754,9 +648,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/movePageLocalizedInLiveWorkspaceDeletedToDifferentPageTwice.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movePageToDifferentPageAndChangeSorting(): void
     {
         parent::movePageToDifferentPageAndChangeSorting();
@@ -777,10 +669,10 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
     }
 
     /**
-     * @test
      * @see https://forge.typo3.org/issues/33104
      * @see https://forge.typo3.org/issues/55573
      */
+    #[Test]
     public function movePageToDifferentPageAndCreatePageAfterMovedPage(): void
     {
         parent::movePageToDifferentPageAndCreatePageAfterMovedPage();
@@ -794,9 +686,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Page)->setField('title')->setValues('Target', 'Testing #1', 'DataHandlerTest'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCopyDraftPage(): void
     {
         parent::createContentAndCopyDraftPage();
@@ -812,9 +702,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(static::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPageAndCopyDraftParentPage(): void
     {
         parent::createPageAndCopyDraftParentPage();
@@ -822,9 +710,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPageAndCopyDraftParentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createNestedPagesAndCopyDraftParentPage(): void
     {
         parent::createNestedPagesAndCopyDraftParentPage();
@@ -832,9 +718,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createNestedPagesAndCopyDraftParentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndLocalize(): void
     {
         parent::createContentAndLocalize();
@@ -850,9 +734,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('[Translate to Dansk:] Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeContentSortingAndCopyDraftPage(): void
     {
         parent::changeContentSortingAndCopyDraftPage();
@@ -860,9 +742,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changeContentSortingAndCopyDraftPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPlaceholdersAndDeleteDraftParentPage(): void
     {
         parent::createPlaceholdersAndDeleteDraftParentPage();
@@ -870,9 +750,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createPlaceholdersAndDeleteDraftParentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createPlaceholdersAndDeleteLiveParentPage(): void
     {
         parent::createPlaceholdersAndDeleteLiveParentPage();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/Select/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/Select/Modify/ActionTest.php
index 089e73c60a60..9d13652aa53f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/Select/Modify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/Select/Modify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\Select\Modify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\Select\AbstractActionTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
@@ -26,19 +27,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
  */
 final class ActionTest extends AbstractActionTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     * See DataSet/addElementRelation.csv
-     */
+    #[Test]
     public function addElementRelation(): void
     {
         parent::addElementRelation();
@@ -51,10 +47,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     * See DataSet/deleteElementRelation.csv
-     */
+    #[Test]
     public function deleteElementRelation(): void
     {
         parent::deleteElementRelation();
@@ -70,10 +63,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     * See DataSet/changeElementSorting.csv
-     */
+    #[Test]
     public function changeElementSorting(): void
     {
         parent::changeElementSorting();
@@ -86,10 +76,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/changeElementRelationSorting.csv
-     */
+    #[Test]
     public function changeElementRelationSorting(): void
     {
         parent::changeElementRelationSorting();
@@ -102,10 +89,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/createContentNAddRelation.csv
-     */
+    #[Test]
     public function createContentAndAddElementRelation(): void
     {
         parent::createContentAndAddElementRelation();
@@ -120,10 +104,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/createContentNCreateRelation.csv
-     */
+    #[Test]
     public function createContentAndCreateElementRelation(): void
     {
         parent::createContentAndCreateElementRelation();
@@ -138,10 +119,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyElementOfRelation.csv
-     */
+    #[Test]
     public function modifyElementOfRelation(): void
     {
         parent::modifyElementOfRelation();
@@ -154,10 +132,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyContentOfRelation.csv
-     */
+    #[Test]
     public function modifyContentOfRelation(): void
     {
         parent::modifyContentOfRelation();
@@ -169,10 +144,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/modifyBothSidesOfRelation.csv
-     */
+    #[Test]
     public function modifyBothSidesOfRelation(): void
     {
         parent::modifyBothSidesOfRelation();
@@ -187,10 +159,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/deleteContentOfRelation.csv
-     */
+    #[Test]
     public function deleteContentOfRelation(): void
     {
         parent::deleteContentOfRelation();
@@ -202,10 +171,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/deleteElementOfRelation.csv
-     */
+    #[Test]
     public function deleteElementOfRelation(): void
     {
         parent::deleteElementOfRelation();
@@ -218,10 +184,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyContentOfRelation.csv
-     */
+    #[Test]
     public function copyContentOfRelation(): void
     {
         parent::copyContentOfRelation();
@@ -234,10 +197,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyElementOfRelation.csv
-     */
+    #[Test]
     public function copyElementOfRelation(): void
     {
         parent::copyElementOfRelation();
@@ -254,10 +214,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1 (copy 1)'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyContentToLanguageOfRelation.csv
-     */
+    #[Test]
     public function copyContentToLanguageOfRelation(): void
     {
         parent::copyContentToLanguageOfRelation();
@@ -270,10 +227,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     * See DataSet/copyElementToLanguageOfRelation.csv
-     */
+    #[Test]
     public function copyElementToLanguageOfRelation(): void
     {
         parent::copyElementToLanguageOfRelation();
@@ -288,10 +242,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeContentOfRelation.csv
-     */
+    #[Test]
     public function localizeContentOfRelation(): void
     {
         parent::localizeContentOfRelation();
@@ -304,10 +255,7 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     * See DataSet/localizeElementOfRelation.csv
-     */
+    #[Test]
     public function localizeElementOfRelation(): void
     {
         // Create translated page first
@@ -322,19 +270,14 @@ final class ActionTest extends AbstractActionTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('[Translate to Dansk:] Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLocalizeReferencesAtParentLocalization()
     {
         parent::localizeContentOfRelationWithLocalizeReferencesAtParentLocalization();
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentOfRelationWLocalizeReferencesAtParentLocalization.csv');
     }
 
-    /**
-     * @test
-     * See DataSet/moveContentOfRelationToDifferentPage.csv
-     */
+    #[Test]
     public function moveContentOfRelationToDifferentPage(): void
     {
         parent::moveContentOfRelationToDifferentPage();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesDiscard/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesDiscard/ActionTest.php
index f6a8390281c1..353bab89860a 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesDiscard/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesDiscard/ActionTest.php
@@ -17,22 +17,19 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\Select\WorkspacesDiscard;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\Select\AbstractActionWorkspacesTestCase;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addElementRelation(): void
     {
         parent::addElementRelation();
@@ -40,9 +37,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/addElementRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementRelation(): void
     {
         parent::deleteElementRelation();
@@ -50,9 +45,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteElementRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementSorting(): void
     {
         parent::changeElementSorting();
@@ -60,9 +53,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changeElementSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementRelationSorting(): void
     {
         parent::changeElementRelationSorting();
@@ -70,9 +61,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/changeElementRelationSorting.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndAddElementRelation(): void
     {
         parent::createContentAndAddElementRelation();
@@ -80,9 +69,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContentNAddRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCreateElementRelation(): void
     {
         parent::createContentAndCreateElementRelation();
@@ -93,9 +80,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/createContentNCreateRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyElementOfRelation(): void
     {
         parent::modifyElementOfRelation();
@@ -103,9 +88,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyElementOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentOfRelation(): void
     {
         parent::modifyContentOfRelation();
@@ -113,9 +96,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyContentOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyBothSidesOfRelation(): void
     {
         parent::modifyBothSidesOfRelation();
@@ -126,9 +107,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/modifyBothSidesOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentOfRelation(): void
     {
         parent::deleteContentOfRelation();
@@ -136,9 +115,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteContentOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementOfRelation(): void
     {
         parent::deleteElementOfRelation();
@@ -146,9 +123,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deleteElementOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentOfRelation(): void
     {
         parent::copyContentOfRelation();
@@ -156,9 +131,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyContentOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyElementOfRelation(): void
     {
         parent::copyElementOfRelation();
@@ -166,9 +139,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/copyElementOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelation(): void
     {
         parent::localizeContentOfRelation();
@@ -176,9 +147,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeContentOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeElementOfRelation(): void
     {
         // Create translated page first
@@ -188,9 +157,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/localizeElementOfRelation.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentOfRelationToDifferentPage(): void
     {
         parent::moveContentOfRelationToDifferentPage();
@@ -198,9 +165,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/moveContentOfRelationToDifferentPage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLocalizeReferencesAtParentLocalization()
     {
         parent::localizeContentOfRelationWithLocalizeReferencesAtParentLocalization();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesModify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesModify/ActionTest.php
index 1f5bd43a0f18..a969badb9b2a 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesModify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesModify/ActionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\Select\WorkspacesModify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\Select\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -24,18 +25,14 @@ use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addElementRelation(): void
     {
         parent::addElementRelation();
@@ -51,9 +48,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementRelation(): void
     {
         parent::deleteElementRelation();
@@ -72,9 +67,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementSorting(): void
     {
         parent::changeElementSorting();
@@ -90,9 +83,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementRelationSorting(): void
     {
         parent::changeElementRelationSorting();
@@ -108,9 +99,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndAddElementRelation(): void
     {
         parent::createContentAndAddElementRelation();
@@ -128,9 +117,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCreateElementRelation(): void
     {
         parent::createContentAndCreateElementRelation();
@@ -148,9 +135,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyElementOfRelation(): void
     {
         parent::modifyElementOfRelation();
@@ -166,9 +151,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentOfRelation(): void
     {
         parent::modifyContentOfRelation();
@@ -183,9 +166,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyBothSidesOfRelation(): void
     {
         parent::modifyBothSidesOfRelation();
@@ -203,9 +184,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentOfRelation(): void
     {
         parent::deleteContentOfRelation();
@@ -220,9 +199,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementOfRelation(): void
     {
         parent::deleteElementOfRelation();
@@ -238,9 +215,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentOfRelation(): void
     {
         parent::copyContentOfRelation();
@@ -257,9 +232,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyElementOfRelation(): void
     {
         parent::copyElementOfRelation();
@@ -279,9 +252,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1 (copy 1)'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelation(): void
     {
         parent::localizeContentOfRelation();
@@ -297,9 +268,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeElementOfRelation(): void
     {
         // Create translated page first
@@ -317,9 +286,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('[Translate to Dansk:] Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentOfRelationToDifferentPage(): void
     {
         parent::moveContentOfRelationToDifferentPage();
@@ -335,9 +302,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLocalizeReferencesAtParentLocalization()
     {
         parent::localizeContentOfRelationWithLocalizeReferencesAtParentLocalization();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesPublish/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesPublish/ActionTest.php
index 74f76c8cff38..8256877dddc0 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesPublish/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesPublish/ActionTest.php
@@ -17,24 +17,21 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\Select\WorkspacesPublish;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\Select\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addElementRelation(): void
     {
         parent::addElementRelation();
@@ -48,9 +45,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementRelation(): void
     {
         parent::deleteElementRelation();
@@ -67,9 +62,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementSorting(): void
     {
         parent::changeElementSorting();
@@ -83,9 +76,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementRelationSorting(): void
     {
         parent::changeElementRelationSorting();
@@ -99,9 +90,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndAddElementRelation(): void
     {
         parent::createContentAndAddElementRelation();
@@ -117,9 +106,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCreateElementRelation(): void
     {
         parent::createContentAndCreateElementRelation();
@@ -138,9 +125,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyElementOfRelation(): void
     {
         parent::modifyElementOfRelation();
@@ -154,9 +139,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentOfRelation(): void
     {
         parent::modifyContentOfRelation();
@@ -169,9 +152,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyBothSidesOfRelation(): void
     {
         parent::modifyBothSidesOfRelation();
@@ -190,9 +171,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentOfRelation(): void
     {
         parent::deleteContentOfRelation();
@@ -205,9 +184,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementOfRelation(): void
     {
         parent::deleteElementOfRelation();
@@ -221,9 +198,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentOfRelation(): void
     {
         parent::copyContentOfRelation();
@@ -238,9 +213,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyElementOfRelation(): void
     {
         parent::copyElementOfRelation();
@@ -258,9 +231,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1 (copy 1)'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelation(): void
     {
         parent::localizeContentOfRelation();
@@ -274,9 +245,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeElementOfRelation(): void
     {
         // Create and publish translated page first
@@ -293,9 +262,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('[Translate to Dansk:] Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentOfRelationToDifferentPage(): void
     {
         parent::moveContentOfRelationToDifferentPage();
@@ -309,9 +276,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLocalizeReferencesAtParentLocalization()
     {
         parent::localizeContentOfRelationWithLocalizeReferencesAtParentLocalization();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesPublishAll/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesPublishAll/ActionTest.php
index 723f47dca30b..34f201e6add8 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesPublishAll/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/Select/WorkspacesPublishAll/ActionTest.php
@@ -17,24 +17,21 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\Select\WorkspacesPublishAll;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\Select\AbstractActionWorkspacesTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex(): void
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addElementRelation(): void
     {
         parent::addElementRelation();
@@ -48,9 +45,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementRelation(): void
     {
         parent::deleteElementRelation();
@@ -67,9 +62,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementSorting(): void
     {
         parent::changeElementSorting();
@@ -83,9 +76,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeElementRelationSorting(): void
     {
         parent::changeElementRelationSorting();
@@ -99,9 +90,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndAddElementRelation(): void
     {
         parent::createContentAndAddElementRelation();
@@ -117,9 +106,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createContentAndCreateElementRelation(): void
     {
         parent::createContentAndCreateElementRelation();
@@ -135,9 +122,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyElementOfRelation(): void
     {
         parent::modifyElementOfRelation();
@@ -151,9 +136,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Testing #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyContentOfRelation(): void
     {
         parent::modifyContentOfRelation();
@@ -166,9 +149,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyBothSidesOfRelation(): void
     {
         parent::modifyBothSidesOfRelation();
@@ -184,9 +165,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteContentOfRelation(): void
     {
         parent::deleteContentOfRelation();
@@ -199,9 +178,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Content)->setField('header')->setValues('Testing #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteElementOfRelation(): void
     {
         parent::deleteElementOfRelation();
@@ -215,9 +192,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyContentOfRelation(): void
     {
         parent::copyContentOfRelation();
@@ -232,9 +207,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyElementOfRelation(): void
     {
         parent::copyElementOfRelation();
@@ -252,9 +225,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #1 (copy 1)'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelation(): void
     {
         parent::localizeContentOfRelation();
@@ -268,9 +239,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeElementOfRelation(): void
     {
         // Create translated page first
@@ -286,9 +255,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('[Translate to Dansk:] Element #1', 'Element #2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveContentOfRelationToDifferentPage(): void
     {
         parent::moveContentOfRelationToDifferentPage();
@@ -302,9 +269,7 @@ final class ActionTest extends AbstractActionWorkspacesTestCase
             ->setTable(self::TABLE_Element)->setField('title')->setValues('Element #2', 'Element #3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeContentOfRelationWithLocalizeReferencesAtParentLocalization()
     {
         parent::localizeContentOfRelationWithLocalizeReferencesAtParentLocalization();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/Modify/ActionTest.php
index 07d42030f6c8..c7f777ef13ca 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/Modify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/Modify/ActionTest.php
@@ -17,22 +17,19 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\SelectFlex\Modify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\SelectFlex\AbstractActionTestCase;
 
 final class ActionTest extends AbstractActionTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex()
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addElementRelation()
     {
         parent::addElementRelation();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesDiscard/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesDiscard/ActionTest.php
index 08a37e2b00ca..0562fa7b7545 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesDiscard/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesDiscard/ActionTest.php
@@ -17,22 +17,19 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\SelectFlex\WorkspacesDiscard;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\SelectFlex\AbstractActionWorkspacesTestCase;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex()
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addElementRelation()
     {
         parent::addElementRelation();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesModify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesModify/ActionTest.php
index bfdaee5f2fbb..4d7d844481f9 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesModify/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesModify/ActionTest.php
@@ -17,22 +17,19 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\SelectFlex\WorkspacesModify;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\SelectFlex\AbstractActionWorkspacesTestCase;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex()
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addElementRelation()
     {
         parent::addElementRelation();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesPublish/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesPublish/ActionTest.php
index 19afd9def3f3..a958be283df8 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesPublish/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesPublish/ActionTest.php
@@ -17,22 +17,19 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\SelectFlex\WorkspacesPublish;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\SelectFlex\AbstractActionWorkspacesTestCase;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex()
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addElementRelation()
     {
         parent::addElementRelation();
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesPublishAll/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesPublishAll/ActionTest.php
index eb4ec0d8d92b..1d2b4c6fd629 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesPublishAll/ActionTest.php
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/SelectFlex/WorkspacesPublishAll/ActionTest.php
@@ -17,22 +17,19 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DataScenarios\SelectFlex\WorkspacesPublishAll;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataScenarios\SelectFlex\AbstractActionWorkspacesTestCase;
 
 final class ActionTest extends AbstractActionWorkspacesTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyCleanReferenceIndex()
     {
         // The test verifies the imported data set has a clean reference index by the check in tearDown()
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addElementRelation()
     {
         parent::addElementRelation();
diff --git a/typo3/sysext/core/Tests/Functional/Database/ConnectionTest.php b/typo3/sysext/core/Tests/Functional/Database/ConnectionTest.php
index 11d90b36903d..070596d03e2c 100644
--- a/typo3/sysext/core/Tests/Functional/Database/ConnectionTest.php
+++ b/typo3/sysext/core/Tests/Functional/Database/ConnectionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Database;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Schema\SchemaMigrator;
 use TYPO3\CMS\Core\Database\Schema\SqlReader;
@@ -34,7 +35,7 @@ final class ConnectionTest extends FunctionalTestCase
         $subject->install($creationStatements);
     }
 
-    /** @test */
+    #[Test]
     public function datetimeInstanceCanBePersistedToDatabaseWithoutSpecifyingType(): void
     {
         $value = new \DateTime('2023-11-23T11:49:00+01:00');
@@ -45,7 +46,7 @@ final class ConnectionTest extends FunctionalTestCase
         ]);
     }
 
-    /** @test */
+    #[Test]
     public function datetimeInstanceCanBePersistedToDatabaseIfTypeIsExplicitlySpecified(): void
     {
         $value = new \DateTime('2023-11-23T11:49:00+01:00');
@@ -58,7 +59,7 @@ final class ConnectionTest extends FunctionalTestCase
         ]);
     }
 
-    /** @test */
+    #[Test]
     public function datetimeImmutableInstanceCanBePersistedToDatabaseWithoutSpecifyingType(): void
     {
         $value = new \DateTimeImmutable('2023-11-23T11:49:00+01:00');
@@ -69,7 +70,7 @@ final class ConnectionTest extends FunctionalTestCase
         ]);
     }
 
-    /** @test */
+    #[Test]
     public function datetimeImmutableInstanceCanBePersistedToDatabaseIfTypeIsExplicitlySpecified(): void
     {
         $value = new \DateTimeImmutable('2023-11-23T11:49:00+01:00');
diff --git a/typo3/sysext/core/Tests/Functional/Database/Query/Expression/ExpressionBuilderTest.php b/typo3/sysext/core/Tests/Functional/Database/Query/Expression/ExpressionBuilderTest.php
index 27d00ca5072a..3040cc415137 100644
--- a/typo3/sysext/core/Tests/Functional/Database/Query/Expression/ExpressionBuilderTest.php
+++ b/typo3/sysext/core/Tests/Functional/Database/Query/Expression/ExpressionBuilderTest.php
@@ -18,6 +18,8 @@ declare(strict_types=1);
 namespace TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression;
 
 use Doctrine\DBAL\Platforms\SqlitePlatform;
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -27,9 +29,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         'typo3/sysext/core/Tests/Functional/Database/Fixtures/Extensions/test_expressionbuilder',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inSetReturnsExpectedDataSetsWithColumn(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -98,9 +98,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inSetReturnsExpectedDataSets(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -135,9 +133,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inSetReturnsExpectedDataSetsWithInts(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -172,9 +168,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inSetReturnsExpectedDataSetsIfValueContainsLikeWildcard(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -209,9 +203,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inSetReturnsExpectedDataSetsIfValueContainsBracket(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -246,9 +238,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inSetReturnsExpectedDataSetsIfValueContainsClosingBracket(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -283,9 +273,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inSetReturnsExpectedDataSetsIfValueContainsOpeningAndClosingBracket(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -320,9 +308,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inSetReturnsExpectedDataSetsIfValueContainsBracketsAroundWord(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -357,9 +343,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inSetReturnsExpectedDataSetsIfValueContainsBracketsAroundLikeWildcard(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -394,14 +378,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals($expected, $result);
     }
 
-    /**
-     * notInSet tests, as they reverse the tests from above, only the count() logic is used to avoid too many
-     * result arrays to be defined.
-     */
-
-    /**
-     * @test
-     */
+    #[Test]
     public function notInSetReturnsExpectedDataSetsWithColumn(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -532,9 +509,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notInSetReturnsExpectedDataSets(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -558,9 +533,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals(4, $queryBuilder->executeQuery()->fetchOne());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notInSetReturnsExpectedDataSetsWithInts(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -574,9 +547,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals(36, $queryBuilder->executeQuery()->fetchOne());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notInSetReturnsExpectedDataSetsIfValueContainsLikeWildcard(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -590,9 +561,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals(36, $queryBuilder->executeQuery()->fetchOne());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notInSetReturnsExpectedDataSetsIfValueContainsBracket(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -606,9 +575,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals(36, $queryBuilder->executeQuery()->fetchOne());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notInSetReturnsExpectedDataSetsIfValueContainsClosingBracket(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -622,9 +589,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals(36, $queryBuilder->executeQuery()->fetchOne());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notInSetReturnsExpectedDataSetsIfValueContainsOpeningAndClosingBracket(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -638,9 +603,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals(36, $queryBuilder->executeQuery()->fetchOne());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notInSetReturnsExpectedDataSetsIfValueContainsBracketsAroundWord(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -654,9 +617,7 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertEquals(36, $queryBuilder->executeQuery()->fetchOne());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notInSetReturnsExpectedDataSetsIfValueContainsBracketsAroundLikeWildcard(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
@@ -741,12 +702,12 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         ];
     }
 
+    #[DataProvider('likeReturnsExpectedDataSetsDataProvider')]
+    #[Test]
     /**
-     * @test
-     * @dataProvider likeReturnsExpectedDataSetsDataProvider
      * Note: SQLite does not properly work with non-ascii letters as search word for case-insensitive
      *       matching, UPPER() and LOWER() have the same issue, it only works with ascii letters.
-     *       See: https://www.sqlite.org/src/doc/trunk/ext/icu/README.txt
+     *       See: https://www.sqlite.org/src/doc/trunk/ext/icu/README.txt')]
      */
     public function likeReturnsExpectedDataSets(string $searchWord, array $expectedRows, array $excludePlatforms): void
     {
@@ -843,10 +804,8 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider likeWithWildcardValueCanBeMatchedDataProvider
-     */
+    #[DataProvider('likeWithWildcardValueCanBeMatchedDataProvider')]
+    #[Test]
     public function likeWithWildcardValueCanBeMatched(string $searchWord, array $expectedRows, array $excludePlatforms): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderLikeAndNotLike.csv');
@@ -908,10 +867,8 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider notLikeWithWildcardValueCanBeMatchedDataProvider
-     */
+    #[DataProvider('notLikeWithWildcardValueCanBeMatchedDataProvider')]
+    #[Test]
     public function notLikeWithWildcardValueCanBeMatched(string $searchWord, array $expectedRows, array $excludePlatforms): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderLikeAndNotLike.csv');
@@ -938,12 +895,12 @@ final class ExpressionBuilderTest extends FunctionalTestCase
         self::assertSame($expectedRows, $rows);
     }
 
+    #[DataProvider('notLikeReturnsExpectedDataSetsDataProvider')]
+    #[Test]
     /**
-     * @test
-     * @dataProvider notLikeReturnsExpectedDataSetsDataProvider
      * Note: SQLite does not properly work with non-ascii letters as search word for case-insensitive
      *       matching, UPPER() and LOWER() have the same issue, it only works with ascii letters.
-     *       See: https://www.sqlite.org/src/doc/trunk/ext/icu/README.txt
+     *       See: https://www.sqlite.org/src/doc/trunk/ext/icu/README.txt')]
      */
     public function notLikeReturnsExpectedDataSets(string $searchWord, array $expectedRows, array $excludePlatforms): void
     {
diff --git a/typo3/sysext/core/Tests/Functional/Database/Query/QueryBuilder/NamedPlaceholderPreparedStatementTest.php b/typo3/sysext/core/Tests/Functional/Database/Query/QueryBuilder/NamedPlaceholderPreparedStatementTest.php
index 9fa4907c4d04..e5f536a8e0a8 100644
--- a/typo3/sysext/core/Tests/Functional/Database/Query/QueryBuilder/NamedPlaceholderPreparedStatementTest.php
+++ b/typo3/sysext/core/Tests/Functional/Database/Query/QueryBuilder/NamedPlaceholderPreparedStatementTest.php
@@ -18,6 +18,7 @@ declare(strict_types=1);
 namespace TYPO3\CMS\Core\Tests\Functional\Database\Query\QueryBuilder;
 
 use Doctrine\DBAL\ParameterType;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Query\NamedParameterNotSupportedForPreparedStatementException;
 use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
@@ -32,9 +33,7 @@ final class NamedPlaceholderPreparedStatementTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/Fixtures/DataSet/queryBuilder_preparedStatement.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function throwsNamedParameterNotSupportedForPreparedStatementExceptionIfNamedPlacholderAreSetOnPrepare(): void
     {
         $this->expectExceptionObject(
diff --git a/typo3/sysext/core/Tests/Functional/Database/Query/QueryBuilder/PositionPlaceholderPreparedStatementTest.php b/typo3/sysext/core/Tests/Functional/Database/Query/QueryBuilder/PositionPlaceholderPreparedStatementTest.php
index fe6a79bea53a..a1251c7201b1 100644
--- a/typo3/sysext/core/Tests/Functional/Database/Query/QueryBuilder/PositionPlaceholderPreparedStatementTest.php
+++ b/typo3/sysext/core/Tests/Functional/Database/Query/QueryBuilder/PositionPlaceholderPreparedStatementTest.php
@@ -19,6 +19,8 @@ namespace TYPO3\CMS\Core\Tests\Functional\Database\Query\QueryBuilder;
 
 use Doctrine\DBAL\ParameterType;
 use Doctrine\DBAL\Statement;
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Cache\CacheManager;
 use TYPO3\CMS\Core\Database\Connection;
 use TYPO3\CMS\Core\Database\ConnectionPool;
@@ -36,9 +38,7 @@ final class PositionPlaceholderPreparedStatementTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/Fixtures/DataSet/queryBuilder_preparedStatement.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canBeInstantiated(): void
     {
         $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
@@ -48,9 +48,7 @@ final class PositionPlaceholderPreparedStatementTest extends FunctionalTestCase
         self::assertInstanceOf(QueryBuilder::class, $queryBuilder);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function preparedStatementWithPositionPlaceholderAndBindValueWorks(): void
     {
         $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
@@ -90,9 +88,7 @@ final class PositionPlaceholderPreparedStatementTest extends FunctionalTestCase
         self::assertSame(22, (int)($rows2[1]['uid'] ?? 0));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function preparedStatementWithPositionPlaceholderAndBindValueWithWileLoopWorks(): void
     {
         $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
@@ -139,9 +135,7 @@ final class PositionPlaceholderPreparedStatementTest extends FunctionalTestCase
         self::assertSame(22, (int)($rows2[1]['uid'] ?? 0));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function preparedStatementWithoutRetrievingFullResultSetAndWithoutFreeingPriorResultSetWorks(): void
     {
         $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
@@ -176,9 +170,7 @@ final class PositionPlaceholderPreparedStatementTest extends FunctionalTestCase
         self::assertSame(21, (int)($result2->fetchAssociative()['uid'] ?? 0));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function preparedStatementWorksIfRetrievedThroughRuntimeCacheAndPriorResultSetNotFreedAfterIncompleteDataRetrieval(): void
     {
         $runtimeCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('runtime');
@@ -236,10 +228,8 @@ final class PositionPlaceholderPreparedStatementTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider invalidParameterTypesForPreparedStatements
-     */
+    #[DataProvider('invalidParameterTypesForPreparedStatements')]
+    #[Test]
     public function preparedStatementThrowsExceptionForInvalidParameterType(int $arrayParameterType, string $arrayParameterName, array $arrayValues): void
     {
         // expected exception
diff --git a/typo3/sysext/core/Tests/Functional/Database/ReferenceIndexTest.php b/typo3/sysext/core/Tests/Functional/Database/ReferenceIndexTest.php
index ea5b9662db19..cc4dc6f8bf65 100644
--- a/typo3/sysext/core/Tests/Functional/Database/ReferenceIndexTest.php
+++ b/typo3/sysext/core/Tests/Functional/Database/ReferenceIndexTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Database;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ReferenceIndex;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -26,9 +27,7 @@ final class ReferenceIndexTest extends FunctionalTestCase
         'typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_irre_foreignfield',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function updateIndexRemovesRecordsOfNotExistingWorkspaces(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/ReferenceIndex/UpdateIndexRemoveNonExistingWorkspaceImport.csv');
diff --git a/typo3/sysext/core/Tests/Functional/Database/ReferenceIndexWorkspaceLoadedTest.php b/typo3/sysext/core/Tests/Functional/Database/ReferenceIndexWorkspaceLoadedTest.php
index 78abf4930a9d..ffced0945023 100644
--- a/typo3/sysext/core/Tests/Functional/Database/ReferenceIndexWorkspaceLoadedTest.php
+++ b/typo3/sysext/core/Tests/Functional/Database/ReferenceIndexWorkspaceLoadedTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Database;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ReferenceIndex;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -30,9 +31,7 @@ final class ReferenceIndexWorkspaceLoadedTest extends FunctionalTestCase
         'typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_irre_foreignfield',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function updateIndexRemovesRecordsOfNotExistingWorkspaces(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/ReferenceIndex/WorkspaceLoadedUpdateIndexRemoveNonExistingWorkspaceImport.csv');
@@ -41,9 +40,7 @@ final class ReferenceIndexWorkspaceLoadedTest extends FunctionalTestCase
         $this->assertCSVDataSet(__DIR__ . '/Fixtures/ReferenceIndex/WorkspaceLoadedUpdateIndexRemoveNonExistingWorkspaceResult.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function updateIndexAddsRowsForLocalSideMmHavingForeignWorkspaceRecord(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/ReferenceIndex/WorkspaceLoadedUpdateIndexAddsRowsForLocalSideMmHavingForeignWorkspaceRecordImport.csv');
diff --git a/typo3/sysext/core/Tests/Functional/Database/Schema/SchemaMigratorTest.php b/typo3/sysext/core/Tests/Functional/Database/Schema/SchemaMigratorTest.php
index bb104325f2ef..156e824e2540 100644
--- a/typo3/sysext/core/Tests/Functional/Database/Schema/SchemaMigratorTest.php
+++ b/typo3/sysext/core/Tests/Functional/Database/Schema/SchemaMigratorTest.php
@@ -21,6 +21,8 @@ use Doctrine\DBAL\Schema\AbstractSchemaManager;
 use Doctrine\DBAL\Schema\Table;
 use Doctrine\DBAL\Types\BigIntType;
 use Doctrine\DBAL\Types\TextType;
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Schema\SchemaMigrator;
 use TYPO3\CMS\Core\Database\Schema\SqlReader;
@@ -45,7 +47,7 @@ final class SchemaMigratorTest extends FunctionalTestCase
     protected $schemaManager;
 
     /**
-     * @var \TYPO3\CMS\Core\Database\Schema\SchemaMigrator
+     * @var SchemaMigrator
      */
     protected $subject;
 
@@ -85,9 +87,7 @@ final class SchemaMigratorTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createNewTable(): void
     {
         if ($this->schemaManager->tablesExist([$this->tableName])) {
@@ -105,9 +105,7 @@ final class SchemaMigratorTest extends FunctionalTestCase
         self::assertCount(6, $this->getTableDetails()->getColumns());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createNewTableIfNotExists(): void
     {
         $statements = $this->readFixtureFile('ifNotExists');
@@ -121,9 +119,7 @@ final class SchemaMigratorTest extends FunctionalTestCase
         self::assertTrue($this->schemaManager->tablesExist(['another_test_table']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addNewColumns(): void
     {
         $statements = $this->readFixtureFile('addColumnsToTable');
@@ -139,9 +135,7 @@ final class SchemaMigratorTest extends FunctionalTestCase
         self::assertTrue($this->getTableDetails()->hasColumn('description'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeExistingColumn(): void
     {
         $statements = $this->readFixtureFile('changeExistingColumn');
@@ -164,10 +158,9 @@ final class SchemaMigratorTest extends FunctionalTestCase
      * table and throws "Cannot add a NOT NULL column with default value NULL". It's
      * currently unclear if core should handle that by changing the alter table
      * statement on the fly.
-     *
-     * @test
-     * @group not-sqlite
      */
+    #[Group('not-sqlite')]
+    #[Test]
     public function notNullWithoutDefaultValue(): void
     {
         $statements = $this->readFixtureFile('notNullWithoutDefaultValue');
@@ -181,9 +174,7 @@ final class SchemaMigratorTest extends FunctionalTestCase
         self::assertTrue($this->getTableDetails()->getColumn('aTestField')->getNotnull());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function defaultNullWithoutNotNull(): void
     {
         $statements = $this->readFixtureFile('defaultNullWithoutNotNull');
@@ -198,9 +189,7 @@ final class SchemaMigratorTest extends FunctionalTestCase
         self::assertNull($this->getTableDetails()->getColumn('aTestField')->getDefault());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renameUnusedField(): void
     {
         $statements = $this->readFixtureFile('unusedColumn');
@@ -215,9 +204,7 @@ final class SchemaMigratorTest extends FunctionalTestCase
         self::assertTrue($this->getTableDetails()->hasColumn('zzz_deleted_hidden'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renameUnusedTable(): void
     {
         $statements = $this->readFixtureFile('unusedTable');
@@ -235,10 +222,9 @@ final class SchemaMigratorTest extends FunctionalTestCase
     /**
      * Disabled on sqlite: It seems the platform is unable to drop columns for
      * currently unknown reasons.
-     *
-     * @test
-     * @group not-sqlite
      */
+    #[Group('not-sqlite')]
+    #[Test]
     public function dropUnusedField(): void
     {
         $connection = $this->connectionPool->getConnectionForTable($this->tableName);
@@ -262,9 +248,7 @@ final class SchemaMigratorTest extends FunctionalTestCase
         self::assertFalse($this->getTableDetails()->hasColumn('zzz_deleted_testfield'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function dropUnusedTable(): void
     {
         $this->schemaManager->renameTable($this->tableName, 'zzz_deleted_' . $this->tableName);
@@ -282,11 +266,9 @@ final class SchemaMigratorTest extends FunctionalTestCase
         self::assertNotContains('zzz_deleted_' . $this->tableName, $this->schemaManager->listTableNames());
     }
 
-    /**
-     * @test
-     * @group not-postgres
-     * @group not-sqlite
-     */
+    #[Group('not-postgres')]
+    #[Group('not-sqlite')]
+    #[Test]
     public function installPerformsOnlyAddAndCreateOperations(): void
     {
         $statements = $this->readFixtureFile('addCreateChange');
@@ -303,9 +285,8 @@ final class SchemaMigratorTest extends FunctionalTestCase
      * Disabled on sqlite: The platform seems to have issues with indexes
      * for currently unknown reasons. If that is sorted out, this test can
      * probably be enabled.
-     *
-     * @test
      */
+    #[Test]
     public function installDoesNotAddIndexOnChangedColumn(): void
     {
         $statements = $this->readFixtureFile('addIndexOnChangedColumn');
@@ -315,9 +296,7 @@ final class SchemaMigratorTest extends FunctionalTestCase
         self::assertFalse($this->getTableDetails()->hasIndex('title'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function changeExistingIndex(): void
     {
         // recreate the table with the indexes applied
@@ -355,11 +334,9 @@ final class SchemaMigratorTest extends FunctionalTestCase
         self::assertEquals($expectedColumnsOfChangedIndex, $indexesAfterChange[$parentIndex[0]]->getColumns());
     }
 
-    /**
-     * @test
-     * @group not-postgres
-     * @group not-sqlite
-     */
+    #[Group('not-postgres')]
+    #[Group('not-sqlite')]
+    #[Test]
     public function installCanPerformChangeOperations(): void
     {
         $statements = $this->readFixtureFile('addCreateChange');
@@ -372,11 +349,9 @@ final class SchemaMigratorTest extends FunctionalTestCase
         self::assertInstanceOf(BigIntType::class, $this->getTableDetails()->getColumn('pid')->getType());
     }
 
-    /**
-     * @test
-     * @group not-postgres
-     * @group not-sqlite
-     */
+    #[Group('not-postgres')]
+    #[Group('not-sqlite')]
+    #[Test]
     public function importStaticDataInsertsRecords(): void
     {
         $sqlCode = file_get_contents(implode(DIRECTORY_SEPARATOR, [__DIR__, '..', 'Fixtures', 'importStaticData.sql']));
@@ -387,9 +362,7 @@ final class SchemaMigratorTest extends FunctionalTestCase
         self::assertEquals(2, $connection->count('*', $this->tableName, []));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importStaticDataIgnoresTableDefinitions(): void
     {
         $sqlCode = file_get_contents(implode(DIRECTORY_SEPARATOR, [__DIR__, '..', 'Fixtures', 'importStaticData.sql']));
@@ -399,11 +372,9 @@ final class SchemaMigratorTest extends FunctionalTestCase
         self::assertNotContains('another_test_table', $this->schemaManager->listTableNames());
     }
 
-    /**
-     * @test
-     * @group not-postgres
-     * @group not-sqlite
-     */
+    #[Group('not-postgres')]
+    #[Group('not-sqlite')]
+    #[Test]
     public function changeTableEngine(): void
     {
         $statements = $this->readFixtureFile('alterTableEngine');
diff --git a/typo3/sysext/core/Tests/Functional/DependencyInjection/AsCommandAttributeTest.php b/typo3/sysext/core/Tests/Functional/DependencyInjection/AsCommandAttributeTest.php
index 37f6e330370c..d9802c37984c 100644
--- a/typo3/sysext/core/Tests/Functional/DependencyInjection/AsCommandAttributeTest.php
+++ b/typo3/sysext/core/Tests/Functional/DependencyInjection/AsCommandAttributeTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\DependencyInjection;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Console\CommandRegistry;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Tests\TestDi\Command\AliasTestCommand;
@@ -29,9 +30,7 @@ final class AsCommandAttributeTest extends FunctionalTestCase
         'typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_di',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function asCommandRegisteredToCommandRegistry(): void
     {
         $commandRegistry = $this->get(CommandRegistry::class);
@@ -43,9 +42,7 @@ final class AsCommandAttributeTest extends FunctionalTestCase
         self::assertInstanceOf(HiddenTestCommand::class, $commandRegistry->get('testdi:ascommand:hidden'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function asCommandHiddenAttributeIsRespected(): void
     {
         $commandRegistry = $this->get(CommandRegistry::class);
@@ -55,9 +52,7 @@ final class AsCommandAttributeTest extends FunctionalTestCase
         self::assertArrayNotHasKey('testdi:ascommand:hidden', $visibleList);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function asCommandAliasAttributeIsRespected(): void
     {
         $commandRegistry = $this->get(CommandRegistry::class);
@@ -76,9 +71,7 @@ final class AsCommandAttributeTest extends FunctionalTestCase
         self::assertArrayNotHasKey('testdi:ascommand:alias-sub2', $visibleList);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function asCommandSetsDescription(): void
     {
         $commandRegistry = $this->get(CommandRegistry::class);
diff --git a/typo3/sysext/core/Tests/Functional/Domain/Access/RecordAccessVoterTest.php b/typo3/sysext/core/Tests/Functional/Domain/Access/RecordAccessVoterTest.php
index 9732b3a032b1..8d95fd1754c7 100644
--- a/typo3/sysext/core/Tests/Functional/Domain/Access/RecordAccessVoterTest.php
+++ b/typo3/sysext/core/Tests/Functional/Domain/Access/RecordAccessVoterTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Domain\Access;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\UserAspect;
@@ -99,10 +101,8 @@ final class RecordAccessVoterTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider accessGrantedTestDataProvider
-     */
+    #[DataProvider('accessGrantedTestDataProvider')]
+    #[Test]
     public function accessGrantedTest(string $table, array $record, bool $access): void
     {
         $GLOBALS['SIM_ACCESS_TIME'] = 42;
@@ -111,9 +111,7 @@ final class RecordAccessVoterTest extends FunctionalTestCase
         self::assertEquals($access, $this->subject->accessGranted($table, $record, $context));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function accessGrantedRespectsVisibilityAspect(): void
     {
         // Page is available even if the "disabled" flag is set
@@ -166,10 +164,8 @@ final class RecordAccessVoterTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider groupAccessGrantedTestDataProvider
-     */
+    #[DataProvider('groupAccessGrantedTestDataProvider')]
+    #[Test]
     public function groupAccessGrantedTest(string $table, array $record, bool $access): void
     {
         $context = new Context([
@@ -179,9 +175,7 @@ final class RecordAccessVoterTest extends FunctionalTestCase
         self::assertEquals($access, $this->subject->groupAccessGranted($table, $record, $context));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function accessGrantedForPageInRootLineReturnsTrueForDisabledExtendToSubpages(): void
     {
         self::assertTrue($this->subject->accessGrantedForPageInRootLine(['uid ' => 1, 'hidden' => 1], new Context()));
diff --git a/typo3/sysext/core/Tests/Functional/Domain/Repository/PageRepositoryTest.php b/typo3/sysext/core/Tests/Functional/Domain/Repository/PageRepositoryTest.php
index ed13d18ebabe..4b9c9cfb8843 100644
--- a/typo3/sysext/core/Tests/Functional/Domain/Repository/PageRepositoryTest.php
+++ b/typo3/sysext/core/Tests/Functional/Domain/Repository/PageRepositoryTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Domain\Repository;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\LanguageAspect;
@@ -39,9 +41,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/pages.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getMenuSingleUidRoot(): void
     {
         $subject = new PageRepository();
@@ -52,9 +52,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertCount(3, $rows);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getMenuSingleUidSubpage(): void
     {
         $subject = new PageRepository();
@@ -64,9 +62,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertCount(2, $rows);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getMenuMultipleUid(): void
     {
         $subject = new PageRepository();
@@ -78,9 +74,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertCount(4, $rows);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getMenuPageOverlay(): void
     {
         $subject = new PageRepository(new Context([
@@ -95,9 +89,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertCount(4, $rows);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getMenuWithMountPoint(): void
     {
         $subject = new PageRepository();
@@ -108,9 +100,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertCount(2, $rows);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getMenuPageOverlayWithMountPoint(): void
     {
         $subject = new PageRepository(new Context([
@@ -124,9 +114,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertCount(2, $rows);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPageOverlayById(): void
     {
         $subject = new PageRepository();
@@ -137,9 +125,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPageOverlayByIdWithoutTranslation(): void
     {
         $subject = new PageRepository();
@@ -148,9 +134,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertCount(0, $row);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPageOverlayByRow(): void
     {
         $subject = new PageRepository();
@@ -163,9 +147,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPageOverlayByRowWithoutTranslation(): void
     {
         $subject = new PageRepository();
@@ -176,9 +158,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertEquals('Dummy 1-4', $row['title']);//original title
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPagesOverlayByIdSingle(): void
     {
         $subject = new PageRepository(new Context([
@@ -196,9 +176,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPagesOverlayByIdMultiple(): void
     {
         $subject = new PageRepository(new Context([
@@ -223,9 +201,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPagesOverlayByIdMultipleSomeNotOverlaid(): void
     {
         $subject = new PageRepository(new Context([
@@ -246,9 +222,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertEquals('Attrappe 1-2-5', $row['title']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPagesOverlayByRowSingle(): void
     {
         $subject = new PageRepository();
@@ -270,9 +244,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertEquals(new Page($origRow), $row['_TRANSLATION_SOURCE']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function groupRestrictedPageCanBeOverlaid(): void
     {
         $subject = new PageRepository();
@@ -293,9 +265,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertEquals(1, $row['_PAGES_OVERLAY_LANGUAGE']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPagesOverlayByRowMultiple(): void
     {
         $subject = new PageRepository();
@@ -326,9 +296,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertEquals(new Page($orig2), $row['_TRANSLATION_SOURCE']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPagesOverlayByRowMultipleSomeNotOverlaid(): void
     {
         $subject = new PageRepository();
@@ -364,9 +332,8 @@ final class PageRepositoryTest extends FunctionalTestCase
 
     /**
      * Tests whether the getPage Hook is called correctly.
-     *
-     * @test
      */
+    #[Test]
     public function isGetPageHookCalled(): void
     {
         // Create a hook mock object
@@ -386,9 +353,7 @@ final class PageRepositoryTest extends FunctionalTestCase
     // Tests concerning mountpoints
     ////////////////////////////////
     ///
-    /**
-     * @test
-     */
+    #[Test]
     public function getMountPointInfoForDefaultLanguage(): void
     {
         $subject = new PageRepository();
@@ -396,9 +361,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertEquals('1001-1003', $mountPointInfo['MPvar']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getMountPointInfoForTranslation(): void
     {
         $mpVar = '1001-1003';
@@ -415,10 +378,7 @@ final class PageRepositoryTest extends FunctionalTestCase
     ////////////////////////////////
     // Tests concerning workspaces
     ////////////////////////////////
-
-    /**
-     * @test
-     */
+    #[Test]
     public function previewShowsPagesFromLiveAndCurrentWorkspace(): void
     {
         // initialization
@@ -436,9 +396,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertEquals(VersionState::NEW_PLACEHOLDER, $pageRec['t3ver_state']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getWorkspaceVersionReturnsTheCorrectMethod(): void
     {
         // initialization
@@ -460,10 +418,7 @@ final class PageRepositoryTest extends FunctionalTestCase
     ////////////////////////////////
     // Tests concerning versioning
     ////////////////////////////////
-
-    /**
-     * @test
-     */
+    #[Test]
     public function enableFieldsHidesVersionedRecordsAndPlaceholders(): void
     {
         $table = StringUtility::getUniqueId('aTable');
@@ -490,9 +445,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function enableFieldsDoesNotHidePlaceholdersInPreview(): void
     {
         $table = StringUtility::getUniqueId('aTable');
@@ -521,9 +474,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function enableFieldsDoesFilterToCurrentAndLiveWorkspaceForRecordsInPreview(): void
     {
         $table = StringUtility::getUniqueId('aTable');
@@ -567,9 +518,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertFalse(isset($row['_PAGES_OVERLAY_LANGUAGE']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPageIdsRecursiveTest(): void
     {
         // do not use cache_treelist
@@ -597,9 +546,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertEquals([1000, 1001], $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDescendantPageIdsRecursiveTest(): void
     {
         // do not use cache_treelist
@@ -630,9 +577,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertEquals([2, 5, 6, 7, 3, 8, 9, 4, 10], $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getLanguageOverlayResolvesContentWithNullInValues(): void
     {
         $context = new Context();
@@ -665,10 +610,10 @@ final class PageRepositoryTest extends FunctionalTestCase
     }
 
     /**
-     * @test
      * @param array<string, int> $input
-     * @dataProvider invalidRowForVersionOLDataProvider
      */
+    #[DataProvider('invalidRowForVersionOLDataProvider')]
+    #[Test]
     public function versionOLForAnInvalidRowUnchangedRowData(array $input): void
     {
         $context = new Context();
diff --git a/typo3/sysext/core/Tests/Functional/Error/ErrorHandlerTest.php b/typo3/sysext/core/Tests/Functional/Error/ErrorHandlerTest.php
index cf42f98b09e0..408010f0f181 100644
--- a/typo3/sysext/core/Tests/Functional/Error/ErrorHandlerTest.php
+++ b/typo3/sysext/core/Tests/Functional/Error/ErrorHandlerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Error;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Error\ErrorHandler;
 use TYPO3\CMS\Core\Log\Logger;
 use TYPO3\CMS\Core\Log\LogManager;
@@ -40,9 +41,7 @@ final class ErrorHandlerTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleErrorFetchesDeprecations(): void
     {
         trigger_error(
@@ -68,9 +67,8 @@ final class ErrorHandlerTest extends FunctionalTestCase
      * \TYPO3\CMS\Core\Error\ErrorHandler::handleError via call_user_func. This leads to
      * \TYPO3\CMS\Core\Error\ErrorHandler::handleError handling errors it was not registered for. Thus, there needs to
      * be a check if \TYPO3\CMS\Core\Error\ErrorHandler should handle the incoming error.
-     *
-     * @test
      */
+    #[Test]
     public function handleErrorOnlyHandlesRegisteredErrorLevels(): void
     {
         // Make sure the core error handler does not return due to error_reporting being 0
diff --git a/typo3/sysext/core/Tests/Functional/ExpressionLanguage/ResolverTest.php b/typo3/sysext/core/Tests/Functional/ExpressionLanguage/ResolverTest.php
index 70f0adcc93e4..ee50d2699bb2 100644
--- a/typo3/sysext/core/Tests/Functional/ExpressionLanguage/ResolverTest.php
+++ b/typo3/sysext/core/Tests/Functional/ExpressionLanguage/ResolverTest.php
@@ -17,15 +17,14 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\ExpressionLanguage;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\ExpressionLanguage\Resolver;
 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class ResolverTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function evaluateWithTyposcriptAndTsfeEvaluatesCorrectly(): void
     {
         $frontendControllerMock = $this
@@ -41,9 +40,7 @@ final class ResolverTest extends FunctionalTestCase
         self::assertTrue($resolver->evaluate('getTSFE()?.id == 123'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function evaluateWithTyposcriptWithoutTsfeEvaluatesCorrectly(): void
     {
         $resolver = new Resolver('typoscript', []);
diff --git a/typo3/sysext/core/Tests/Functional/Html/DefaultSanitizerBuilderTest.php b/typo3/sysext/core/Tests/Functional/Html/DefaultSanitizerBuilderTest.php
index 9800249a85ee..27776a46d772 100644
--- a/typo3/sysext/core/Tests/Functional/Html/DefaultSanitizerBuilderTest.php
+++ b/typo3/sysext/core/Tests/Functional/Html/DefaultSanitizerBuilderTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Html;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Log\LogLevel;
 use TYPO3\CMS\Core\Html\DefaultSanitizerBuilder;
 use TYPO3\CMS\Core\Html\SanitizerBuilderFactory;
@@ -160,10 +162,8 @@ final class DefaultSanitizerBuilderTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider isSanitizedDataProvider
-     */
+    #[DataProvider('isSanitizedDataProvider')]
+    #[Test]
     public function isSanitized(string $payload, string $expectation): void
     {
         $factory = new SanitizerBuilderFactory();
@@ -172,9 +172,7 @@ final class DefaultSanitizerBuilderTest extends FunctionalTestCase
         self::assertSame($expectation, $sanitizer->sanitize($payload));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function behaviorIsCachedInMemory(): void
     {
         $default = new DefaultSanitizerBuilder();
@@ -204,9 +202,7 @@ final class DefaultSanitizerBuilderTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function incidentIsLogged(): void
     {
         $trace = bin2hex(random_bytes(8));
diff --git a/typo3/sysext/core/Tests/Functional/Imaging/IconFactoryTest.php b/typo3/sysext/core/Tests/Functional/Imaging/IconFactoryTest.php
index c45ea3977809..d2633c8177d2 100644
--- a/typo3/sysext/core/Tests/Functional/Imaging/IconFactoryTest.php
+++ b/typo3/sysext/core/Tests/Functional/Imaging/IconFactoryTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Imaging;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider;
@@ -73,9 +75,7 @@ final class IconFactoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getIconReturnsIconWithCorrectMarkupWrapperIfRegisteredIconIdentifierIsUsed(): void
     {
         self::assertStringContainsString(
@@ -84,9 +84,7 @@ final class IconFactoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getIconByIdentifierReturnsIconWithCorrectMarkupIfRegisteredIconIdentifierIsUsed(): void
     {
         self::assertStringContainsString(
@@ -95,10 +93,8 @@ final class IconFactoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider differentSizesDataProvider
-     */
+    #[DataProvider('differentSizesDataProvider')]
+    #[Test]
     public function getIconByIdentifierAndSizeReturnsIconWithCorrectMarkupIfRegisteredIconIdentifierIsUsed($size): void
     {
         self::assertStringContainsString(
@@ -107,10 +103,8 @@ final class IconFactoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider differentSizesDataProvider
-     */
+    #[DataProvider('differentSizesDataProvider')]
+    #[Test]
     public function getIconByIdentifierAndSizeAndWithOverlayReturnsIconWithCorrectOverlayMarkupIfRegisteredIconIdentifierIsUsed($size): void
     {
         self::assertStringContainsString(
@@ -119,9 +113,7 @@ final class IconFactoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getIconReturnsNotFoundIconWithCorrectMarkupIfUnregisteredIdentifierIsUsed(): void
     {
         self::assertStringContainsString(
@@ -130,10 +122,8 @@ final class IconFactoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider differentSizesDataProvider
-     */
+    #[DataProvider('differentSizesDataProvider')]
+    #[Test]
     public function getIconByIdentifierAndSizeReturnsNotFoundIconWithCorrectMarkupIfUnregisteredIdentifierIsUsed(array $size): void
     {
         self::assertStringContainsString(
@@ -142,9 +132,7 @@ final class IconFactoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getIconReturnsCorrectMarkupIfIconIsRegisteredAsSpinningIcon(): void
     {
         $iconRegistry = $this->get(IconRegistry::class);
@@ -162,10 +150,8 @@ final class IconFactoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider differentSizesDataProvider
-     */
+    #[DataProvider('differentSizesDataProvider')]
+    #[Test]
     public function getIconByIdentifierAndSizeAndOverlayReturnsNotFoundIconWithCorrectMarkupIfUnregisteredIdentifierIsUsed(array $size): void
     {
         self::assertStringContainsString(
@@ -174,9 +160,7 @@ final class IconFactoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getIconThrowsExceptionIfInvalidSizeIsGiven(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -186,12 +170,10 @@ final class IconFactoryTest extends FunctionalTestCase
     //
     // Tests for getIconForFileExtension
     //
-
     /**
      * Tests the return of an icon for a file without extension
-     *
-     * @test
      */
+    #[Test]
     public function getIconForFileWithNoFileTypeReturnsDefaultFileIcon(): void
     {
         self::assertStringContainsString(
@@ -202,9 +184,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the return of an icon for an unknown file type
-     *
-     * @test
      */
+    #[Test]
     public function getIconForFileWithUnknownFileTypeReturnsDefaultFileIcon(): void
     {
         self::assertStringContainsString(
@@ -215,9 +196,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the return of an icon for a file with extension pdf
-     *
-     * @test
      */
+    #[Test]
     public function getIconForFileWithFileTypePdfReturnsPdfIcon(): void
     {
         self::assertStringContainsString(
@@ -228,9 +208,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the return of an icon for a file with extension png
-     *
-     * @test
      */
+    #[Test]
     public function getIconForFileWithFileTypePngReturnsPngIcon(): void
     {
         self::assertStringContainsString(
@@ -239,9 +218,7 @@ final class IconFactoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getIconForResourceReturnsCorrectMarkupForFileResources(): void
     {
         $resourceMock = $this->createMock(File::class);
@@ -260,9 +237,8 @@ final class IconFactoryTest extends FunctionalTestCase
     //////////////////////////////////////////////
     /**
      * Tests the returns of no file
-     *
-     * @test
      */
+    #[Test]
     public function getIconForResourceWithFileWithoutExtensionTypeReturnsOtherIcon(): void
     {
         $fileObject = $this->getTestSubjectFileObject('');
@@ -272,9 +248,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the returns of unknown file
-     *
-     * @test
      */
+    #[Test]
     public function getIconForResourceWithUnknownFileTypeReturnsOtherIcon(): void
     {
         $fileObject = $this->getTestSubjectFileObject('foo');
@@ -284,9 +259,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the returns of file pdf
-     *
-     * @test
      */
+    #[Test]
     public function getIconForResourceWithPdfReturnsPdfIcon(): void
     {
         $fileObject = $this->getTestSubjectFileObject('pdf');
@@ -296,9 +270,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the returns of file pdf with known mime-type
-     *
-     * @test
      */
+    #[Test]
     public function getIconForResourceWithMimeTypeApplicationPdfReturnsPdfIcon(): void
     {
         $fileObject = $this->getTestSubjectFileObject('pdf', 'application/pdf');
@@ -308,9 +281,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the returns of file with custom image mime-type
-     *
-     * @test
      */
+    #[Test]
     public function getIconForResourceWithCustomImageMimeTypeReturnsImageIcon(): void
     {
         $fileObject = $this->getTestSubjectFileObject('custom', 'image/my-custom-extension');
@@ -320,9 +292,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the returns of file png
-     *
-     * @test
      */
+    #[Test]
     public function getIconForResourceWithPngFileReturnsIcon(): void
     {
         $fileObject = $this->getTestSubjectFileObject('png', 'image/png');
@@ -332,9 +303,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the returns of normal folder
-     *
-     * @test
      */
+    #[Test]
     public function getIconForResourceWithFolderReturnsFolderIcon(): void
     {
         $folderObject = $this->getTestSubjectFolderObject('/test');
@@ -344,9 +314,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the returns of open folder
-     *
-     * @test
      */
+    #[Test]
     public function getIconForResourceWithOpenFolderReturnsOpenFolderIcon(): void
     {
         $folderObject = $this->getTestSubjectFolderObject('/test');
@@ -356,9 +325,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the returns of root folder
-     *
-     * @test
      */
+    #[Test]
     public function getIconForResourceWithRootFolderReturnsRootFolderIcon(): void
     {
         $folderObject = $this->getTestSubjectFolderObject('/');
@@ -368,9 +336,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the returns of mount root
-     *
-     * @test
      */
+    #[Test]
     public function getIconForResourceWithMountRootReturnsMountFolderIcon(): void
     {
         $folderObject = $this->getTestSubjectFolderObject('/mount');
@@ -381,12 +348,10 @@ final class IconFactoryTest extends FunctionalTestCase
     //
     // Test for getIconForRecord
     //
-
     /**
      * Tests the returns of NULL table + empty array
-     *
-     * @test
      */
+    #[Test]
     public function getIconForRecordWithNullTableReturnsMissingIcon(): void
     {
         $GLOBALS['TCA']['']['ctrl'] = [];
@@ -398,9 +363,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the returns of tt_content + empty record
-     *
-     * @test
      */
+    #[Test]
     public function getIconForRecordWithEmptyRecordReturnsNormalIcon(): void
     {
         $GLOBALS['TCA'] = [
@@ -419,9 +383,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the returns of tt_content + mock record
-     *
-     * @test
      */
+    #[Test]
     public function getIconForRecordWithMockRecordReturnsNormalIcon(): void
     {
         $GLOBALS['TCA'] = [
@@ -441,9 +404,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the returns of tt_content + mock record of type 'list' (aka plugin)
-     *
-     * @test
      */
+    #[Test]
     public function getIconForRecordWithMockRecordOfTypePluginReturnsDefaultPluginIcon(): void
     {
         $GLOBALS['TCA'] = [
@@ -466,9 +428,8 @@ final class IconFactoryTest extends FunctionalTestCase
     /**
      * Tests the returns of tt_content + mock record of type 'list' (aka plugin) with a dedicated icon for the
      * plugin (registered in ExtensionUtility::registerPlugin)
-     *
-     * @test
      */
+    #[Test]
     public function getIconForRecordWithMockRecordOfTypePluginReturnsConfiguredPluginIcon(): void
     {
         $GLOBALS['TCA'] = [
@@ -504,9 +465,8 @@ final class IconFactoryTest extends FunctionalTestCase
 
     /**
      * Tests the returns of tt_content + mock record with hidden flag
-     *
-     * @test
      */
+    #[Test]
     public function getIconForRecordWithMockRecordWithHiddenFlagReturnsNormalIconAndOverlay(): void
     {
         $GLOBALS['TCA'] = [
@@ -600,10 +560,8 @@ final class IconFactoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getIconForRecordDefaultsToBasePageIconForCustomPageTypesIfTheyDontDefineOwnIconsDataProvider
-     */
+    #[DataProvider('getIconForRecordDefaultsToBasePageIconForCustomPageTypesIfTheyDontDefineOwnIconsDataProvider')]
+    #[Test]
     public function getIconForRecordDefaultsToBasePageIconForCustomPageTypesIfTheyDontDefineOwnIcons(array $record, string $expected): void
     {
         $result = $this->subject->getIconForRecord('pages', $record)->render();
diff --git a/typo3/sysext/core/Tests/Functional/Imaging/ImageMagickFileTest.php b/typo3/sysext/core/Tests/Functional/Imaging/ImageMagickFileTest.php
index 68669d7b0043..3c47e82626aa 100644
--- a/typo3/sysext/core/Tests/Functional/Imaging/ImageMagickFileTest.php
+++ b/typo3/sysext/core/Tests/Functional/Imaging/ImageMagickFileTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Imaging;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Exception;
 use TYPO3\CMS\Core\Imaging\ImageMagickFile;
 use TYPO3\CMS\Core\Type\File\FileInfo;
@@ -35,10 +37,8 @@ final class ImageMagickFileTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider framesAreConsideredDataProvider
-     */
+    #[DataProvider('framesAreConsideredDataProvider')]
+    #[Test]
     public function framesAreConsidered(string $fileName, ?int $frame, string $expectation): void
     {
         $expectation = $this->substituteVariables($expectation);
@@ -65,10 +65,8 @@ final class ImageMagickFileTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider resultIsEscapedDataProvider
-     */
+    #[DataProvider('resultIsEscapedDataProvider')]
+    #[Test]
     public function resultIsEscaped(string $fileName, ?int $frame, string $expectation): void
     {
         $expectation = $this->substituteVariables($expectation);
@@ -102,10 +100,8 @@ final class ImageMagickFileTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider fileStatementIsResolvedDataProvider
-     */
+    #[DataProvider('fileStatementIsResolvedDataProvider')]
+    #[Test]
     public function fileStatementIsResolved(string $fileName, string $expectation): void
     {
         $expectation = $this->substituteVariables($expectation);
@@ -138,10 +134,8 @@ final class ImageMagickFileTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider fileStatementIsResolvedForEnforcedMimeTypeDataProvider
-     */
+    #[DataProvider('fileStatementIsResolvedForEnforcedMimeTypeDataProvider')]
+    #[Test]
     public function fileStatementIsResolvedForEnforcedMimeType(string $fileName, string $expectation, string $mimeType): void
     {
         $this->simulateNextFileInfoInvocation($mimeType);
@@ -159,10 +153,8 @@ final class ImageMagickFileTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider fileStatementIsResolvedForConfiguredMimeTypeDataProvider
-     */
+    #[DataProvider('fileStatementIsResolvedForConfiguredMimeTypeDataProvider')]
+    #[Test]
     public function fileStatementIsResolvedForConfiguredMimeType(string $fileName, string $expectation): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['fileExtensionToMimeType']['g3'] = 'image/g3fax';
@@ -188,10 +180,8 @@ final class ImageMagickFileTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider fileStatementIsDeniedDataProvider
-     */
+    #[DataProvider('fileStatementIsDeniedDataProvider')]
+    #[Test]
     public function fileStatementIsDenied(string $fileName, ?string $mimeType = null): void
     {
         $this->expectException(Exception::class);
@@ -213,10 +203,8 @@ final class ImageMagickFileTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider fileStatementIsDeniedForConfiguredMimeTypeDataProvider
-     */
+    #[DataProvider('fileStatementIsDeniedForConfiguredMimeTypeDataProvider')]
+    #[Test]
     public function fileStatementIsDeniedForConfiguredMimeType(string $fileName): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['fileExtensionToMimeType']['ps'] = 'image/x-see-no-evil';
diff --git a/typo3/sysext/core/Tests/Functional/Localization/LanguageServiceTest.php b/typo3/sysext/core/Tests/Functional/Localization/LanguageServiceTest.php
index f9574a3ea0fd..0c7d2760f49c 100644
--- a/typo3/sysext/core/Tests/Functional/Localization/LanguageServiceTest.php
+++ b/typo3/sysext/core/Tests/Functional/Localization/LanguageServiceTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Localization;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Cache\Backend\NullBackend;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -51,10 +53,8 @@ final class LanguageServiceTest extends FunctionalTestCase
     private const LANGUAGE_FILE_CORE_OVERRIDE = 'EXT:test_localization/Resources/Private/Language/locallang_common_override.xlf';
     private const LANGUAGE_FILE_CORE_OVERRIDE_FR = 'EXT:test_localization/Resources/Private/Language/fr.locallang_common_override.xlf';
 
-    /**
-     * @test
-     * @dataProvider splitLabelTestDataProvider
-     */
+    #[DataProvider('splitLabelTestDataProvider')]
+    #[Test]
     public function splitLabelTest(string $input, string $expected): void
     {
         $subject = $this->get(LanguageServiceFactory::class)->create('default');
@@ -130,10 +130,8 @@ final class LanguageServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     * @dataProvider ensureVariousLocalizationScenariosWorkDataProvider
-     */
+    #[DataProvider('ensureVariousLocalizationScenariosWorkDataProvider')]
+    #[Test]
     public function ensureVariousLocalizationScenariosWork(string $locale, array $expectedLabels): void
     {
         $this->ensureLocalizationScenarioWorks($locale, self::LANGUAGE_FILE, $expectedLabels);
@@ -167,10 +165,8 @@ final class LanguageServiceTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider ensureVariousLocalizationOverrideScenariosWorkDataProvider
-     */
+    #[DataProvider('ensureVariousLocalizationOverrideScenariosWorkDataProvider')]
+    #[Test]
     public function ensureVariousLocalizationOverrideScenariosWork(string $locale, array $expectedLabels): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'][self::LANGUAGE_FILE][] = self::LANGUAGE_FILE_OVERRIDE;
@@ -208,10 +204,8 @@ final class LanguageServiceTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider ensureVariousLocalizationOverrideScenariosForCoreExtensionWorkDataProvider
-     */
+    #[DataProvider('ensureVariousLocalizationOverrideScenariosForCoreExtensionWorkDataProvider')]
+    #[Test]
     public function ensureVariousLocalizationOverrideScenariosForCoreExtensionWork(string $locale, array $expectedLabels): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'][self::LANGUAGE_FILE_CORE][] = self::LANGUAGE_FILE_CORE_OVERRIDE;
@@ -240,10 +234,8 @@ final class LanguageServiceTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider ensureMultiLanguageTranslationInSameContextWorkDataProvider
-     */
+    #[DataProvider('ensureMultiLanguageTranslationInSameContextWorkDataProvider')]
+    #[Test]
     public function ensureMultiLanguageTranslationInSameContextWork(array $expectedLabelSet): void
     {
         foreach ($expectedLabelSet as $locale => $expectedLabels) {
diff --git a/typo3/sysext/core/Tests/Functional/Localization/TcaSystemLanguageCollectorTest.php b/typo3/sysext/core/Tests/Functional/Localization/TcaSystemLanguageCollectorTest.php
index 3326bee2fce6..c358b627b28a 100644
--- a/typo3/sysext/core/Tests/Functional/Localization/TcaSystemLanguageCollectorTest.php
+++ b/typo3/sysext/core/Tests/Functional/Localization/TcaSystemLanguageCollectorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Localization;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Localization\Locales;
 use TYPO3\CMS\Core\Localization\TcaSystemLanguageCollector;
@@ -35,9 +36,7 @@ final class TcaSystemLanguageCollectorTest extends FunctionalTestCase
         $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->createFromUserPreferences($user);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function populateAvailableSiteLanguagesTest(): void
     {
         $siteFinderMock = $this->createMock(SiteFinder::class);
@@ -92,9 +91,7 @@ final class TcaSystemLanguageCollectorTest extends FunctionalTestCase
         self::assertSame($expectedItems, $fieldInformation['items']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function populateAvailableSiteLanguagesWithoutSiteTest(): void
     {
         $expectedItems = [
diff --git a/typo3/sysext/core/Tests/Functional/Log/LoggerAwareChannelTest.php b/typo3/sysext/core/Tests/Functional/Log/LoggerAwareChannelTest.php
index 8d42bb38863c..1d32d5feb8a6 100644
--- a/typo3/sysext/core/Tests/Functional/Log/LoggerAwareChannelTest.php
+++ b/typo3/sysext/core/Tests/Functional/Log/LoggerAwareChannelTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Log;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Log\LogLevel;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Log\LogRecord;
@@ -58,9 +59,7 @@ final class LoggerAwareChannelTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function classLevelChannelAttributeIsRead(): void
     {
         $container = $this->getContainer();
@@ -72,9 +71,7 @@ final class LoggerAwareChannelTest extends FunctionalTestCase
         self::assertSame('beep beep', DummyWriter::$logs[0]->getMessage());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function constructorChannelAttributeIsRead(): void
     {
         $container = $this->getContainer();
diff --git a/typo3/sysext/core/Tests/Functional/Log/Writer/DatabaseWriterTest.php b/typo3/sysext/core/Tests/Functional/Log/Writer/DatabaseWriterTest.php
index 967419dc28e8..5151071f2ba5 100644
--- a/typo3/sysext/core/Tests/Functional/Log/Writer/DatabaseWriterTest.php
+++ b/typo3/sysext/core/Tests/Functional/Log/Writer/DatabaseWriterTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Log\Writer;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Log\LogLevel;
 use TYPO3\CMS\Core\Log\LogRecord;
@@ -25,9 +26,7 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class DatabaseWriterTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function writeLogInsertsLogRecordWithGivenProperties(): void
     {
         $logRecordData = [
diff --git a/typo3/sysext/core/Tests/Functional/Mail/FluidEmailTest.php b/typo3/sysext/core/Tests/Functional/Mail/FluidEmailTest.php
index fa99a19b3ae9..244c7a77a8e8 100644
--- a/typo3/sysext/core/Tests/Functional/Mail/FluidEmailTest.php
+++ b/typo3/sysext/core/Tests/Functional/Mail/FluidEmailTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Mail;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Mail\FluidEmail;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -28,9 +29,7 @@ final class FluidEmailTest extends FunctionalTestCase
         'typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_fluid_email',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function settingFormatWithTextOnlyGeneratesTextEmail(): void
     {
         $subject = new FluidEmail();
@@ -47,9 +46,7 @@ final class FluidEmailTest extends FunctionalTestCase
         self::assertNotEmpty($subject->getTextBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function settingFormatWithHtmlOnlyGeneratesHtmlEmail(): void
     {
         $subject = new FluidEmail();
@@ -66,9 +63,7 @@ final class FluidEmailTest extends FunctionalTestCase
         self::assertEmpty($subject->getTextBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function settingFormatWithTextAndHtmlGeneratesTwoBodies(): void
     {
         $subject = new FluidEmail();
@@ -85,9 +80,7 @@ final class FluidEmailTest extends FunctionalTestCase
         self::assertNotEmpty($subject->getTextBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function settingNoFormatGeneratesTwoBodies(): void
     {
         $subject = new FluidEmail();
@@ -103,9 +96,7 @@ final class FluidEmailTest extends FunctionalTestCase
         self::assertNotEmpty($subject->getTextBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function forcingHtmlBodyGenerationWorks(): void
     {
         $subject = new FluidEmail();
@@ -133,9 +124,7 @@ final class FluidEmailTest extends FunctionalTestCase
         self::assertStringContainsString('&lt;strong&gt;from&lt;/strong&gt;', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function forcingTextBodyGenerationWorks(): void
     {
         $subject = new FluidEmail();
@@ -164,9 +153,7 @@ final class FluidEmailTest extends FunctionalTestCase
         self::assertStringContainsString('Plain content from Functional test', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewAssignValuesResetsGeneratedHtmlBody(): void
     {
         $subject = new FluidEmail();
@@ -199,9 +186,7 @@ final class FluidEmailTest extends FunctionalTestCase
         self::assertStringContainsString('Reassigned Plain content ', $result2);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewAssignValuesResetsGeneratedTextBody(): void
     {
         $subject = new FluidEmail();
@@ -236,9 +221,7 @@ final class FluidEmailTest extends FunctionalTestCase
         self::assertStringContainsString('Reassigned Plain content ', $result2);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewAssignMultiValuesResetsGeneratedHtmlBody(): void
     {
         $subject = new FluidEmail();
@@ -274,9 +257,7 @@ final class FluidEmailTest extends FunctionalTestCase
         self::assertStringContainsString('Reassigned Plain content ', $result2);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewAssignMultiValuesResetsGeneratedTextBody(): void
     {
         $subject = new FluidEmail();
@@ -308,9 +289,7 @@ final class FluidEmailTest extends FunctionalTestCase
         self::assertStringContainsString('Reassigned Plain content ', $result2);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function bodiesAreNotRecreatedOnMultipleEnsureValidityCalls(): void
     {
         $subject = new class () extends FluidEmail {
@@ -336,9 +315,7 @@ final class FluidEmailTest extends FunctionalTestCase
         self::assertEquals(2, $subject->countRenderContentCalled);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function bodiesAreRecreatedOnMultipleEnsureValidityCallsWithAssignUsedInBetween(): void
     {
         $subject = new class () extends FluidEmail {
@@ -374,9 +351,7 @@ final class FluidEmailTest extends FunctionalTestCase
         self::assertStringContainsString('Reassigned plain content from Functional test', $resultHtml);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function bodiesAreRecreatedOnMultipleEnsureValidityCallsWithAssignMultipleUsedInBetween(): void
     {
         $subject = new class () extends FluidEmail {
@@ -412,9 +387,7 @@ final class FluidEmailTest extends FunctionalTestCase
         self::assertStringContainsString('Reassigned plain content from Functional test', $resultHtml);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function bodiesAreNotRecreatedOnMultipleEnsureValidityCallsWithSetSubjectInBetween(): void
     {
         $subject = new class () extends FluidEmail {
@@ -448,9 +421,7 @@ final class FluidEmailTest extends FunctionalTestCase
         self::assertEquals('Overridden subject', $subject->getSubject());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function bodiesAreNotRecreatedOnMultipleEnsureValidityCallsWithAssignedValuesButManualSetTextAndHtml(): void
     {
         $subject = new class () extends FluidEmail {
diff --git a/typo3/sysext/core/Tests/Functional/Mail/MailerTest.php b/typo3/sysext/core/Tests/Functional/Mail/MailerTest.php
index 8677f6fbc0df..5e59b96df039 100644
--- a/typo3/sysext/core/Tests/Functional/Mail/MailerTest.php
+++ b/typo3/sysext/core/Tests/Functional/Mail/MailerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Mail;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\DependencyInjection\Container;
 use Symfony\Component\Mailer\Envelope;
@@ -32,9 +33,7 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class MailerTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function mailerEventsAreTriggered(): void
     {
         $afterMailerInitializedEvent = null;
diff --git a/typo3/sysext/core/Tests/Functional/Messaging/FlashMessageQueueTest.php b/typo3/sysext/core/Tests/Functional/Messaging/FlashMessageQueueTest.php
index 55c48dd201e0..55d53d5ee97b 100644
--- a/typo3/sysext/core/Tests/Functional/Messaging/FlashMessageQueueTest.php
+++ b/typo3/sysext/core/Tests/Functional/Messaging/FlashMessageQueueTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Messaging;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
 use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
 use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
@@ -24,9 +25,7 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class FlashMessageQueueTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function getAllMessagesContainsEnqueuedMessage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -37,9 +36,7 @@ final class FlashMessageQueueTest extends FunctionalTestCase
         self::assertEquals([$flashMessage], $flashMessageQueue->getAllMessages());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function messagesCanBeFilteredBySeverity(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -61,9 +58,7 @@ final class FlashMessageQueueTest extends FunctionalTestCase
         self::assertEquals($messages[0], $flashMessage);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getAllMessagesAndFlushContainsEnqueuedMessage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -74,9 +69,7 @@ final class FlashMessageQueueTest extends FunctionalTestCase
         self::assertEquals([$flashMessage], $flashMessageQueue->getAllMessagesAndFlush());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getAllMessagesAndFlushClearsSessionStack(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -88,9 +81,7 @@ final class FlashMessageQueueTest extends FunctionalTestCase
         self::assertEquals([], $flashMessageQueue->getAllMessagesAndFlush());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getMessagesAndFlushCanFilterBySeverity(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -115,9 +106,7 @@ final class FlashMessageQueueTest extends FunctionalTestCase
         self::assertEquals([$messages[1]], array_values($flashMessageQueue->getAllMessages()));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getAllMessagesReturnsSessionFlashMessageAndTransientFlashMessage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -131,9 +120,7 @@ final class FlashMessageQueueTest extends FunctionalTestCase
         self::assertCount(2, $flashMessageQueue->getAllMessages());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function clearClearsTheQueue(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -145,9 +132,7 @@ final class FlashMessageQueueTest extends FunctionalTestCase
         self::assertCount(0, $flashMessageQueue);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function toArrayOnlyRespectsTransientFlashMessages(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/core/Tests/Functional/MetaDataHandling/PluginsTest.php b/typo3/sysext/core/Tests/Functional/MetaDataHandling/PluginsTest.php
index 60319eb2bce3..0d4d450f6f1a 100644
--- a/typo3/sysext/core/Tests/Functional/MetaDataHandling/PluginsTest.php
+++ b/typo3/sysext/core/Tests/Functional/MetaDataHandling/PluginsTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\MetaDataHandling;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 
@@ -54,10 +56,8 @@ final class PluginsTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider ensurePageSetupIsOkDataProvider
-     */
+    #[DataProvider('ensurePageSetupIsOkDataProvider')]
+    #[Test]
     public function ensurePageSetupIsOk(int $pageId, bool $expectPluginOutput): void
     {
         $this->setUpFrontendRootPage(1, ['typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_meta/Configuration/TypoScript/page' . $pageId . '.typoscript']);
@@ -90,10 +90,9 @@ final class PluginsTest extends AbstractTestCase
     /**
      * This test ensures that the meta data and title of the page are the same
      * even if the pages is delivered cached or uncached.
-     *
-     * @test
-     * @dataProvider ensureMetaDataAreCorrectDataProvider
      */
+    #[DataProvider('ensureMetaDataAreCorrectDataProvider')]
+    #[Test]
     public function ensureMetaDataAreCorrect(int $pageId, string $expectedTitle, string $expectedMetaOgTitle): void
     {
         $this->setUpFrontendRootPage(1, ['typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_meta/Configuration/TypoScript/page' . $pageId . '.typoscript']);
diff --git a/typo3/sysext/core/Tests/Functional/Package/PackageStatesTest.php b/typo3/sysext/core/Tests/Functional/Package/PackageStatesTest.php
index 31bb07d6214f..fb92761ef2c8 100644
--- a/typo3/sysext/core/Tests/Functional/Package/PackageStatesTest.php
+++ b/typo3/sysext/core/Tests/Functional/Package/PackageStatesTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Package;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Cache\Backend\NullBackend;
 use TYPO3\CMS\Core\Package\PackageManager;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -93,9 +94,8 @@ final class PackageStatesTest extends FunctionalTestCase
      * The "sorting constraints" are a combination of static prioritized packages, the
      * corresponding dependencies from `ext_emconf.php` and finally as a fall-back,
      * an alphabetic order - which just ensures that the sequence stays the same.
-     *
-     * @test
      */
+    #[Test]
     public function activePackagesAreOrderedByPrioritizedPackageKeysOrPackageDependenciesOrAlphabetically(): void
     {
         $packageManager = $this->get(PackageManager::class);
diff --git a/typo3/sysext/core/Tests/Functional/Page/JavaScriptRendererTest.php b/typo3/sysext/core/Tests/Functional/Page/JavaScriptRendererTest.php
index 31813f3c894e..776736907b3e 100644
--- a/typo3/sysext/core/Tests/Functional/Page/JavaScriptRendererTest.php
+++ b/typo3/sysext/core/Tests/Functional/Page/JavaScriptRendererTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Page;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction;
 use TYPO3\CMS\Core\Page\JavaScriptRenderer;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -25,9 +26,8 @@ final class JavaScriptRendererTest extends FunctionalTestCase
 {
     /**
      * Ensures closing comment block cannot be injected.
-     *
-     * @test
      */
+    #[Test]
     public function textContentIsEncoded(): void
     {
         $subject = JavaScriptRenderer::create('anything.js');
diff --git a/typo3/sysext/core/Tests/Functional/Page/PageRendererTest.php b/typo3/sysext/core/Tests/Functional/Page/PageRendererTest.php
index 1ef43bb08c75..b609305294e0 100644
--- a/typo3/sysext/core/Tests/Functional/Page/PageRendererTest.php
+++ b/typo3/sysext/core/Tests/Functional/Page/PageRendererTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Page;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\ResponseFactoryInterface;
 use Psr\Http\Message\StreamFactoryInterface;
 use Psr\Log\NullLogger;
@@ -59,9 +61,7 @@ final class PageRendererTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageRendererRendersInsertsMainContentStringsInOutput(): void
     {
         $GLOBALS['TYPO3_REQUEST'] = (new ServerRequest('https://www.example.com/'))
@@ -199,10 +199,8 @@ final class PageRendererTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider pageRendererRendersFooterValuesDataProvider
-     */
+    #[DataProvider('pageRendererRendersFooterValuesDataProvider')]
+    #[Test]
     public function pageRendererRendersFooterValues(int $requestType): void
     {
         $GLOBALS['TYPO3_REQUEST'] = (new ServerRequest('https://www.example.com/'))
@@ -286,9 +284,7 @@ final class PageRendererTest extends FunctionalTestCase
         self::assertStringContainsString($expectedInlineSettingsReturnValue, $renderedString);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageRendererRendersNomoduleJavascript(): void
     {
         $GLOBALS['TYPO3_REQUEST'] = (new ServerRequest('https://www.example.com/'))
@@ -370,9 +366,7 @@ final class PageRendererTest extends FunctionalTestCase
         self::assertStringContainsString($expectedJsFooter, $renderedString);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageRendererRendersDataAttributeInScriptTags(): void
     {
         $GLOBALS['TYPO3_REQUEST'] = (new ServerRequest('https://www.example.com/'))
@@ -430,9 +424,7 @@ final class PageRendererTest extends FunctionalTestCase
         self::assertStringContainsString($expectedJsFooter, $renderedString);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageRendererMergesRequireJsPackagesOnConsecutiveCalls(): void
     {
         $sessionBackend = $this->createMock(SessionBackendInterface::class);
@@ -484,9 +476,7 @@ final class PageRendererTest extends FunctionalTestCase
         self::assertStringContainsString($expectedConfiguration, $renderedString);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageRendererRendersDataAttributeInCssTags(): void
     {
         $GLOBALS['TYPO3_REQUEST'] = (new ServerRequest('https://www.example.com/'))
diff --git a/typo3/sysext/core/Tests/Functional/PasswordPolicy/PasswordPolicyValidatorTest.php b/typo3/sysext/core/Tests/Functional/PasswordPolicy/PasswordPolicyValidatorTest.php
index bfa369842973..93d21c9d0b81 100644
--- a/typo3/sysext/core/Tests/Functional/PasswordPolicy/PasswordPolicyValidatorTest.php
+++ b/typo3/sysext/core/Tests/Functional/PasswordPolicy/PasswordPolicyValidatorTest.php
@@ -17,9 +17,11 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\PasswordPolicy;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Localization\LanguageService;
 use TYPO3\CMS\Core\PasswordPolicy\PasswordPolicyAction;
 use TYPO3\CMS\Core\PasswordPolicy\PasswordPolicyValidator;
+use TYPO3\CMS\Core\PasswordPolicy\Validator\CorePasswordValidator;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -39,9 +41,7 @@ final class PasswordPolicyValidatorTest extends FunctionalTestCase
             ->getMock();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function passwordPolicyValidatorIsEnabledWhenPasswordPolicyIsConfigured(): void
     {
         $this->setDefaultPasswordPolicy();
@@ -56,9 +56,7 @@ final class PasswordPolicyValidatorTest extends FunctionalTestCase
         self::assertTrue($passwordPolicyValidator->isEnabled());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function passwordPolicyValidatorIsDisabledWhenNoValidatorsInPasswordPolicy(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['passwordPolicies'] = [];
@@ -73,9 +71,7 @@ final class PasswordPolicyValidatorTest extends FunctionalTestCase
         self::assertFalse($passwordPolicyValidator->isEnabled());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function passwordPolicyValidatorIsDisabledForUnknownPasswordPolicyIdentifier(): void
     {
         $this->setDefaultPasswordPolicy();
@@ -90,9 +86,7 @@ final class PasswordPolicyValidatorTest extends FunctionalTestCase
         self::assertFalse($passwordPolicyValidator->isEnabled());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function passwordPolicyValidatorReturnsExpectedAmountOfPasswordPolicyRequirements(): void
     {
         $this->setDefaultPasswordPolicy();
@@ -107,9 +101,7 @@ final class PasswordPolicyValidatorTest extends FunctionalTestCase
         self::assertCount(5, $passwordPolicyValidator->getRequirements());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function passwordPolicyValidatorDoesNotAcceptPasswordNotCompliantToPolicy(): void
     {
         $this->setDefaultPasswordPolicy();
@@ -125,9 +117,7 @@ final class PasswordPolicyValidatorTest extends FunctionalTestCase
         self::assertCount(4, $passwordPolicyValidator->getValidationErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function passwordPolicyValidatorHasExpectedAmountOfValidationErrorsForInvalidPassword(): void
     {
         $this->setDefaultPasswordPolicy();
@@ -148,7 +138,7 @@ final class PasswordPolicyValidatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['passwordPolicies'] = [
             'default' => [
                 'validators' => [
-                    \TYPO3\CMS\Core\PasswordPolicy\Validator\CorePasswordValidator::class => [
+                    CorePasswordValidator::class => [
                         'options' => [
                             'minimumLength' => 8,
                             'upperCaseCharacterRequired' => true,
diff --git a/typo3/sysext/core/Tests/Functional/PasswordPolicy/Validator/NotCurrentPasswordValidatorTest.php b/typo3/sysext/core/Tests/Functional/PasswordPolicy/Validator/NotCurrentPasswordValidatorTest.php
index c73de0f46c95..8f1eab923e6d 100644
--- a/typo3/sysext/core/Tests/Functional/PasswordPolicy/Validator/NotCurrentPasswordValidatorTest.php
+++ b/typo3/sysext/core/Tests/Functional/PasswordPolicy/Validator/NotCurrentPasswordValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\PasswordPolicy\Validator;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory;
 use TYPO3\CMS\Core\Localization\LanguageService;
 use TYPO3\CMS\Core\PasswordPolicy\Validator\Dto\ContextData;
@@ -40,9 +41,7 @@ final class NotCurrentPasswordValidatorTest extends FunctionalTestCase
             ->getMock();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validatorReturnsFalseIfPasswordIsEqualToCurrentPasswordForBackendUser(): void
     {
         $knownPasswordHash = GeneralUtility::makeInstance(PasswordHashFactory::class)
@@ -55,9 +54,7 @@ final class NotCurrentPasswordValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate('password', $contextData));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validatorThrowsExpectedExceptionIfNoUnsupportedLoginMode(): void
     {
         $this->expectException(\RuntimeException::class);
@@ -68,9 +65,7 @@ final class NotCurrentPasswordValidatorTest extends FunctionalTestCase
         $validator->validate('password', $contextData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validatorReturnsFalseIfPasswordIsEqualToCurrentPasswordForFrontendUser(): void
     {
         $knownPasswordHash = GeneralUtility::makeInstance(PasswordHashFactory::class)
diff --git a/typo3/sysext/core/Tests/Functional/RateLimiter/RateLimiterFactoryTest.php b/typo3/sysext/core/Tests/Functional/RateLimiter/RateLimiterFactoryTest.php
index ee0749fe230d..e44b543aa9d8 100644
--- a/typo3/sysext/core/Tests/Functional/RateLimiter/RateLimiterFactoryTest.php
+++ b/typo3/sysext/core/Tests/Functional/RateLimiter/RateLimiterFactoryTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\RateLimiter;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\RateLimiter\RateLimit;
 use TYPO3\CMS\Core\Authentication\AbstractUserAuthentication;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -57,10 +59,8 @@ final class RateLimiterFactoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider loginRateLimiterLimitsRequestsDataProvider
-     */
+    #[DataProvider('loginRateLimiterLimitsRequestsDataProvider')]
+    #[Test]
     public function loginRateLimiterReturnsExpectedResults(string $loginType, int $loginRateLimit, int $tokens, bool $expected): void
     {
         $GLOBALS['TYPO3_CONF_VARS'][$loginType]['loginRateLimit'] = $loginRateLimit;
@@ -81,9 +81,7 @@ final class RateLimiterFactoryTest extends FunctionalTestCase
         self::assertInstanceOf(RateLimit::class, $rateLimit);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function loginRateLimiterRespectsIpExcludeList(): void
     {
         $loginType = 'BE';
diff --git a/typo3/sysext/core/Tests/Functional/RegistryTest.php b/typo3/sysext/core/Tests/Functional/RegistryTest.php
index 7fb96a1df39b..498484c8ad89 100644
--- a/typo3/sysext/core/Tests/Functional/RegistryTest.php
+++ b/typo3/sysext/core/Tests/Functional/RegistryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\Connection;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Registry;
@@ -24,25 +25,19 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class RegistryTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsNullIfEntryIsNotInDatabase(): void
     {
         self::assertNull((new Registry())->get('myExtension', 'myKey'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsDefaultValueIfEntryIsNotInDatabase(): void
     {
         self::assertSame('myDefault', (new Registry())->get('myExtension', 'myKey', 'myDefault'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsEntryFromDatabase(): void
     {
         (new ConnectionPool())->getConnectionForTable('sys_registry')
@@ -60,9 +55,7 @@ final class RegistryTest extends FunctionalTestCase
         self::assertSame('myValue', (new Registry())->get('myExtension', 'myKey'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setInsertsEntryInDatabase(): void
     {
         (new Registry())->set('myExtension', 'myKey', 'myValue');
@@ -76,9 +69,7 @@ final class RegistryTest extends FunctionalTestCase
         self::assertSame('myValue', unserialize($valueInDatabase['entry_value']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setOverridesExistingEntryInDatabase(): void
     {
         (new ConnectionPool())->getConnectionForTable('sys_registry')
@@ -104,9 +95,7 @@ final class RegistryTest extends FunctionalTestCase
         self::assertSame('myNewValue', unserialize($valueInDatabase['entry_value']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeDeletesEntryInDatabaseButLeavesOthers(): void
     {
         $connection = (new ConnectionPool())->getConnectionForTable('sys_registry');
@@ -130,9 +119,7 @@ final class RegistryTest extends FunctionalTestCase
         self::assertSame(1, $connection->count('*', 'sys_registry', ['entry_namespace' => 'ns2', 'entry_key' => 'k1']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeAllByNamespaceDeletesEntryInDatabaseAndLeavesOthers(): void
     {
         $connection = (new ConnectionPool())->getConnectionForTable('sys_registry');
@@ -156,9 +143,7 @@ final class RegistryTest extends FunctionalTestCase
         self::assertSame(1, $connection->count('*', 'sys_registry', ['entry_namespace' => 'ns2', 'entry_key' => 'k1']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canGetSetEntry(): void
     {
         $registry = new Registry();
@@ -166,9 +151,7 @@ final class RegistryTest extends FunctionalTestCase
         self::assertSame('value1', $registry->get('ns1', 'key1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReturnsNewValueIfValueHasBeenSetMultipleTimes(): void
     {
         $registry = new Registry();
@@ -177,9 +160,7 @@ final class RegistryTest extends FunctionalTestCase
         self::assertSame('value2', $registry->get('ns1', 'key1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canNotGetRemovedEntry(): void
     {
         $registry = new Registry();
@@ -188,9 +169,7 @@ final class RegistryTest extends FunctionalTestCase
         self::assertNull($registry->get('ns1', 'key1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canNotGetRemovedAllByNamespaceEntry(): void
     {
         $registry = new Registry();
diff --git a/typo3/sysext/core/Tests/Functional/Resource/DefaultUploadFolderResolverTest.php b/typo3/sysext/core/Tests/Functional/Resource/DefaultUploadFolderResolverTest.php
index 733ea18b44a6..5f95e4217815 100644
--- a/typo3/sysext/core/Tests/Functional/Resource/DefaultUploadFolderResolverTest.php
+++ b/typo3/sysext/core/Tests/Functional/Resource/DefaultUploadFolderResolverTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Resource;
 
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Core\EventDispatcher\ListenerProvider;
 use TYPO3\CMS\Core\Resource\DefaultUploadFolderResolver;
@@ -40,9 +41,7 @@ final class DefaultUploadFolderResolverTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveWithUserAndPageConfigTest(): void
     {
         GeneralUtility::mkdir($this->instancePath . '/fileadmin/page_upload/');
@@ -56,9 +55,7 @@ final class DefaultUploadFolderResolverTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveWithUserConfigTest(): void
     {
         GeneralUtility::mkdir($this->instancePath . '/fileadmin/admin_upload/');
@@ -72,9 +69,7 @@ final class DefaultUploadFolderResolverTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveWithoutConfigTest(): void
     {
         $backendUser = $this->setUpBackendUser(2);
@@ -87,9 +82,7 @@ final class DefaultUploadFolderResolverTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDefaultUploadFolderForUserTest(): void
     {
         GeneralUtility::mkdir($this->instancePath . '/fileadmin/admin_upload/');
@@ -100,9 +93,7 @@ final class DefaultUploadFolderResolverTest extends FunctionalTestCase
         self::assertEquals('1:/admin_upload/', $subject->getDefaultUploadFolderForUser($backendUser)->getCombinedIdentifier());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDefaultUploadFolderForUserWithoutConfigTest(): void
     {
         $backendUser = $this->setUpBackendUser(2);
@@ -112,9 +103,7 @@ final class DefaultUploadFolderResolverTest extends FunctionalTestCase
         self::assertNull($subject->getDefaultUploadFolderForUser($backendUser));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDefaultUploadFolderForUserWithoutExistingFolderTest(): void
     {
         $backendUser = $this->setUpBackendUser(1);
@@ -124,9 +113,7 @@ final class DefaultUploadFolderResolverTest extends FunctionalTestCase
         self::assertNull($subject->getDefaultUploadFolderForUser($backendUser));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDefaultUploadFolderForPageTest(): void
     {
         GeneralUtility::mkdir($this->instancePath . '/fileadmin/page_upload/');
@@ -136,9 +123,7 @@ final class DefaultUploadFolderResolverTest extends FunctionalTestCase
         self::assertEquals('1:/page_upload/', $subject->getDefaultUploadFolderForPage(1)->getCombinedIdentifier());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDefaultUploadFolderForPageWithoutExistingFolderTest(): void
     {
         $subject = GeneralUtility::makeInstance(DefaultUploadFolderResolver::class);
@@ -146,9 +131,7 @@ final class DefaultUploadFolderResolverTest extends FunctionalTestCase
         self::assertNull($subject->getDefaultUploadFolderForPage(1));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function afterDefaultUploadFolderWasResolvedEventIsDispatched(): void
     {
         GeneralUtility::mkdir($this->instancePath . '/fileadmin/admin_upload/');
@@ -172,9 +155,7 @@ final class DefaultUploadFolderResolverTest extends FunctionalTestCase
         self::assertEquals($result, $afterDefaultUploadFolderWasResolvedEvent->getUploadFolder());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function afterDefaultUploadFolderWasResolvedEventChangedResult(): void
     {
         GeneralUtility::mkdir($this->instancePath . '/fileadmin/admin_upload/');
diff --git a/typo3/sysext/core/Tests/Functional/Resource/Driver/LocalDriverTest.php b/typo3/sysext/core/Tests/Functional/Resource/Driver/LocalDriverTest.php
index 61fc16db60ba..6e3fb4746216 100644
--- a/typo3/sysext/core/Tests/Functional/Resource/Driver/LocalDriverTest.php
+++ b/typo3/sysext/core/Tests/Functional/Resource/Driver/LocalDriverTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Resource\Driver;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Resource\Driver\LocalDriver;
 use TYPO3\CMS\Core\Resource\Exception\ExistingTargetFileNameException;
@@ -59,9 +61,7 @@ final class LocalDriverTest extends FunctionalTestCase
         return $subject;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function calculatedBasePathRelativeIsSane(): void
     {
         // This would cause problems if you fill "/fileadmin/" into the base path field of a sys_file_storage record and select "relative" as path type
@@ -74,9 +74,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertStringNotContainsString('//', $basePath);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function calculatedBasePathAbsoluteIsSane(): void
     {
         // This test checks if "/../" are properly filtered out (i.e. from "Base path" field of sys_file_storage)
@@ -147,10 +145,8 @@ final class LocalDriverTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider publicUrlIsCalculatedCorrectlyWithDifferentBasePathsAndBasUrisDataProvider
-     */
+    #[DataProvider('publicUrlIsCalculatedCorrectlyWithDifferentBasePathsAndBasUrisDataProvider')]
+    #[Test]
     public function publicUrlIsCalculatedCorrectlyWithDifferentBasePathsAndBasUris(string $basePath, string $baseUri, string $fileName, bool $expectedIsPublic, ?string $expectedPublicUrl): void
     {
         $projectPath = $this->baseDirectory . '/app';
@@ -182,9 +178,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertSame($expectedPublicUrl, $subject->getPublicUrl($fileName));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createFolderRecursiveSanitizesFilename(): void
     {
         $driverConfiguration = [
@@ -201,9 +195,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertFileExists($this->baseDirectory . '/sanitized/sanitized');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function determineBaseUrlUrlEncodesUriParts(): void
     {
         $subject = $this->getAccessibleMock(LocalDriver::class, ['hasCapability'], [], '', false);
@@ -219,27 +211,21 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals(rawurlencode('un encö') . '/' . rawurlencode('ded %path') . '/', $baseUri);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getDefaultFolderReturnsFolderForUserUploadPath(): void
     {
         $subject = $this->getDefaultInitializedSubject();
         self::assertEquals('/user_upload/', $subject->getDefaultFolder());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function defaultLevelFolderFolderIsCreatedIfItDoesntExist(): void
     {
         $subject = $this->getDefaultInitializedSubject();
         self::assertFileExists($this->baseDirectory . '/' . $subject->getDefaultFolder());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFolderInFolderReturnsCorrectFolderObject(): void
     {
         mkdir($this->baseDirectory . '/someDir');
@@ -248,9 +234,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals('/someDir/someSubdir/', $subject->getFolderInFolder('someSubdir', '/someDir/'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createFolderCreatesFolderOnDisk(): void
     {
         mkdir($this->baseDirectory . '/some');
@@ -260,9 +244,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertFileExists($this->baseDirectory . '/some/folder/path');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createFolderReturnsFolderObject(): void
     {
         mkdir($this->baseDirectory . '/some');
@@ -286,10 +268,8 @@ final class LocalDriverTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider createFolderSanitizesFolderNameBeforeCreationDataProvider
-     */
+    #[DataProvider('createFolderSanitizesFolderNameBeforeCreationDataProvider')]
+    #[Test]
     public function createFolderSanitizesFolderNameBeforeCreation(string $newFolderName, string $expectedFolderName): void
     {
         mkdir($this->baseDirectory . '/some');
@@ -299,9 +279,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertFileExists($this->baseDirectory . '/some/folder/' . $expectedFolderName);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function basePathIsNormalizedWithTrailingSlash(): void
     {
         $driverConfiguration = [
@@ -312,9 +290,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals('/', substr($subject->_call('getAbsoluteBasePath'), -1));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function noSecondSlashIsAddedIfBasePathAlreadyHasTrailingSlash(): void
     {
         $driverConfiguration = [
@@ -371,10 +347,8 @@ final class LocalDriverTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getSpecificFileInformationDataProvider
-     */
+    #[DataProvider('getSpecificFileInformationDataProvider')]
+    #[Test]
     public function getSpecificFileInformationReturnsRequestedFileInformation(string|int $expectedValue, string $property): void
     {
         copy(__DIR__ . '/Fixtures/Dummy.html', $this->baseDirectory . '/Dummy.html');
@@ -386,9 +360,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertSame($expectedValue, $subject->getSpecificFileInformation($this->baseDirectory . '/Dummy.html', '/', $property));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getAbsolutePathReturnsCorrectPath(): void
     {
         mkdir($this->baseDirectory . '/someFolder');
@@ -401,9 +373,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals($this->baseDirectory . '/someFolder/file1.ext', $subject->_call('getAbsolutePath', '/someFolder/file1.ext'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addFileMovesFileToCorrectLocation(): void
     {
         mkdir($this->baseDirectory . '/targetFolder');
@@ -414,9 +384,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertFileExists($this->baseDirectory . '/targetFolder/file');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addFileUsesFilenameIfGiven(): void
     {
         mkdir($this->baseDirectory . '/targetFolder');
@@ -427,9 +395,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertFileExists($this->baseDirectory . '/targetFolder/targetFile');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addFileFailsIfFileIsInDriverStorage(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -441,9 +407,7 @@ final class LocalDriverTest extends FunctionalTestCase
         $subject->addFile($this->baseDirectory . '/targetFolder/file', '/targetFolder/', 'file');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addFileReturnsFileIdentifier(): void
     {
         mkdir($this->baseDirectory . '/targetFolder');
@@ -454,9 +418,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals('/targetFolder/file', $fileIdentifier);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function existenceChecksWorkForFilesAndFolders(): void
     {
         mkdir($this->baseDirectory . '/folder');
@@ -468,9 +430,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertFalse($subject->folderExists('/nonexistingFolder/'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function existenceChecksInFolderWorkForFilesAndFolders(): void
     {
         mkdir($this->baseDirectory . '/subfolder');
@@ -483,9 +443,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertFalse($subject->folderExistsInFolder('nonexistingFolder', '/subfolder/'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPublicUrlReturnsCorrectUriForConfiguredBaseUri(): void
     {
         $baseUri = 'https://example.org/foobar/' . StringUtility::getUniqueId('uri_');
@@ -509,10 +467,8 @@ final class LocalDriverTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getPublicUrlReturnsValidUrlContainingSpecialCharactersDataProvider
-     */
+    #[DataProvider('getPublicUrlReturnsValidUrlContainingSpecialCharactersDataProvider')]
+    #[Test]
     public function getPublicUrlReturnsValidUrlContainingSpecialCharacters(string $fileIdentifier): void
     {
         $baseUri = 'https://example.org/foobar/' . StringUtility::getUniqueId('uri_');
@@ -526,9 +482,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertTrue(GeneralUtility::isValidUrl($publicUrl));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fileContentsCanBeWrittenAndRead(): void
     {
         $fileContents = 'asdf';
@@ -540,9 +494,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals($newFileContents, $subject->getFileContents('/file.ext'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setFileContentsReturnsNumberOfBytesWrittenToFile(): void
     {
         $fileContents = 'asdf';
@@ -553,9 +505,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals(strlen($newFileContents), $bytesWritten);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function newFilesCanBeCreated(): void
     {
         $subject = $this->getDefaultInitializedSubject();
@@ -564,9 +514,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertTrue($subject->fileExists('/testfile.txt'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createdFilesAreEmpty(): void
     {
         $subject = $this->getDefaultInitializedSubject();
@@ -576,9 +524,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals(0, strlen($fileData));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createFileFixesPermissionsOnCreatedFile(): void
     {
         if (Environment::isWindows()) {
@@ -593,9 +539,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals((int)$testPattern, (int)(decoct(fileperms($this->baseDirectory . '/someDir/testfile.txt') & 0777)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFileReturnsCorrectIdentifier(): void
     {
         copy(__DIR__ . '/Fixtures/Dummy.html', $this->baseDirectory . '/Dummy.html');
@@ -607,9 +551,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals('/LocalDriverFilenameFilter.php', $fileInfo['identifier']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFileThrowsExceptionIfFileDoesNotExist(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -618,9 +560,7 @@ final class LocalDriverTest extends FunctionalTestCase
         $subject->getFileInfoByIdentifier('/some/file/at/a/random/path');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFilesInFolderReturnsEmptyArrayForEmptyDirectory(): void
     {
         $subject = $this->getDefaultInitializedSubject();
@@ -628,9 +568,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEmpty($fileList);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFileListReturnsAllFilesInDirectory(): void
     {
         mkdir($this->baseDirectory . '/aDir');
@@ -641,9 +579,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals(['/file1', '/file2'], array_keys($fileList));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFileListReturnsAllFilesInSubdirectoryIfRecursiveParameterIsSet(): void
     {
         mkdir($this->baseDirectory . '/aDir');
@@ -657,9 +593,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals(['/file1', '/file2', '/aDir/file3', '/aDir/subDir/file4'], array_keys($fileList));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFileListFailsIfDirectoryDoesNotExist(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -669,9 +603,7 @@ final class LocalDriverTest extends FunctionalTestCase
         $subject->getFilesInFolder('somedir/');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFileInFolderCallsConfiguredCallbackFunctionWithGivenItemName(): void
     {
         file_put_contents($this->baseDirectory . '/file2', 'fdsa');
@@ -702,9 +634,7 @@ final class LocalDriverTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFileListFiltersItemsWithGivenFilterMethods(): void
     {
         file_put_contents($this->baseDirectory . '/fileA', 'asdfg');
@@ -720,9 +650,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertNotContains('/fileA', array_keys($fileList));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFolderListReturnsAllDirectoriesInDirectory(): void
     {
         mkdir($this->baseDirectory . '/dir1');
@@ -733,9 +661,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals(['/dir1/', '/dir2/'], array_keys($fileList));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFolderListReturnsHiddenFoldersByDefault(): void
     {
         mkdir($this->baseDirectory . '/.someHiddenDir');
@@ -748,9 +674,8 @@ final class LocalDriverTest extends FunctionalTestCase
 
     /**
      * Checks if the folder names '.' and '..' are ignored when listing subdirectories
-     *
-     * @test
      */
+    #[Test]
     public function getFolderListLeavesOutNavigationalEntries(): void
     {
         $subject = $this->getDefaultInitializedSubject();
@@ -758,9 +683,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEmpty($fileList);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFolderListFiltersItemsWithGivenFilterMethods(): void
     {
         mkdir($this->baseDirectory . '/folderA');
@@ -776,9 +699,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertNotContains('/folderA/', array_values($folderList));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFolderListFailsIfDirectoryDoesNotExist(): void
     {
         file_put_contents($this->baseDirectory . 'somefile', '');
@@ -788,9 +709,7 @@ final class LocalDriverTest extends FunctionalTestCase
         $subject->getFoldersInFolder('somedir/');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hashReturnsCorrectHashes(): void
     {
         $expectedMd5Hash = '8c67dbaf0ba22f2e7fbc26413b86051b';
@@ -801,9 +720,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals($expectedMd5Hash, $subject->hash('/hashFile', 'md5'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hashingWithUnsupportedAlgorithmFails(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -813,9 +730,7 @@ final class LocalDriverTest extends FunctionalTestCase
         $subject->hash('/hashFile', StringUtility::getUniqueId('uri_'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFileForLocalProcessingCreatesCopyOfFileByDefault(): void
     {
         mkdir($this->baseDirectory . '/someDir');
@@ -829,9 +744,7 @@ final class LocalDriverTest extends FunctionalTestCase
         $subject->getFileForLocalProcessing('/someDir/someFile');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFileForLocalProcessingReturnsOriginalFilepathForReadonlyAccess(): void
     {
         mkdir($this->baseDirectory . '/someDir');
@@ -841,9 +754,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals($filePath, $this->baseDirectory . '/someDir/someFile');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function filesCanBeCopiedToATemporaryPath(): void
     {
         mkdir($this->baseDirectory . '/someDir');
@@ -858,9 +769,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals('asdfgh', file_get_contents($filePath));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function permissionsAreCorrectlyRetrievedForAllowedFile(): void
     {
         file_put_contents($this->baseDirectory . '/someFile', '');
@@ -869,9 +778,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals(['r' => true, 'w' => true], $subject->getPermissions('/someFile'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function permissionsAreCorrectlyRetrievedForAllowedFolder(): void
     {
         mkdir($this->baseDirectory . '/someFolder');
@@ -880,9 +787,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals(['r' => true, 'w' => true], $subject->getPermissions('/someFolder'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isWithinRecognizesFilesWithinFolderAndInOtherFolders(): void
     {
         $subject = $this->getDefaultInitializedSubject();
@@ -891,9 +796,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertFalse($subject->isWithin('/someFolder/', '/someFolderWithALongName/test.jpg'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isWithinAcceptsFileAndFolderObjectsAsContent(): void
     {
         $subject = $this->getDefaultInitializedSubject();
@@ -901,9 +804,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertTrue($subject->isWithin('/someFolder/', '/someFolder/subfolder/'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function filesCanBeCopiedWithinStorage(): void
     {
         $fileContents = StringUtility::getUniqueId('content_');
@@ -914,9 +815,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertFileEquals($this->baseDirectory . '/someFile', $this->baseDirectory . '/targetFolder/someFile');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function filesCanBeMovedWithinStorage(): void
     {
         $fileContents = StringUtility::getUniqueId('content_');
@@ -929,9 +828,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals('/targetFolder/file', $newIdentifier);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fileMetadataIsChangedAfterMovingFile(): void
     {
         $fileContents = StringUtility::getUniqueId('content_');
@@ -943,9 +840,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals($newIdentifier, $fileMetadata['identifier']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renamingFilesChangesFilenameOnDiskInRootFolder(): void
     {
         file_put_contents($this->baseDirectory . '/file', '');
@@ -958,9 +853,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals('/newFile', $newIdentifier);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renamingFilesChangesFilenameOnDiskInSubFolder(): void
     {
         mkdir($this->baseDirectory . '/targetFolder');
@@ -974,9 +867,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals('/targetFolder/newFile', $newIdentifier);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renamingFilesFailsIfTargetFileExists(): void
     {
         $this->expectException(ExistingTargetFileNameException::class);
@@ -988,9 +879,7 @@ final class LocalDriverTest extends FunctionalTestCase
         $subject->renameFile('/targetFolder/file', 'newFile');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renamingFoldersChangesFolderNameOnDiskInRootFolder(): void
     {
         mkdir($this->baseDirectory . '/someFolder');
@@ -1003,9 +892,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals('/newFolder/', $mapping['/someFolder/']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renamingFoldersChangesFolderNameOnDiskInSubFolder(): void
     {
         mkdir($this->baseDirectory . '/subFolder');
@@ -1019,9 +906,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals('/subFolder/newFolder/', $mapping['/subFolder/someFolder/']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renameFolderReturnsCorrectMappingInformationForAllFiles(): void
     {
         mkdir($this->baseDirectory . '/sourceFolder');
@@ -1037,9 +922,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals('/newFolder/subFolder/', $mappingInformation['/sourceFolder/subFolder/']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renameFolderRevertsRenamingIfFilenameMapCannotBeCreated(): void
     {
         $this->expectException(\RuntimeException::class);
@@ -1060,9 +943,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertFileExists($this->baseDirectory . '/sourceFolder/file');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isFolderEmptyReturnsTrueForEmptyFolder(): LocalDriver
     {
         mkdir($this->baseDirectory . '/emptyFolder');
@@ -1071,9 +952,7 @@ final class LocalDriverTest extends FunctionalTestCase
         return $subject;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isFolderEmptyReturnsFalseIfFolderHasFile(): void
     {
         mkdir($this->baseDirectory . '/folderWithFile');
@@ -1082,9 +961,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertFalse($subject->isFolderEmpty('/folderWithFile/'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function isFolderEmptyReturnsFalseIfFolderHasSubfolder(): void
     {
         mkdir($this->baseDirectory . '/folderWithSubFolder');
@@ -1093,9 +970,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertFalse($subject->isFolderEmpty('/folderWithSubFolder/'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function foldersCanBeMovedWithinStorage(): void
     {
         $fileContents = StringUtility::getUniqueId('content_');
@@ -1109,9 +984,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertFileDoesNotExist($this->baseDirectory . '/sourceFolder');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function moveFolderWithinStorageReturnsCorrectMappingInformationForAllFiles(): void
     {
         mkdir($this->baseDirectory . '/targetFolder');
@@ -1126,9 +999,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals('/targetFolder/sourceFolder/subFolder/', $mappingInformation['/sourceFolder/subFolder/']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function folderCanBeRenamedWhenMoving(): void
     {
         mkdir($this->baseDirectory . '/sourceFolder');
@@ -1139,9 +1010,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertFileExists($this->baseDirectory . '/targetFolder/newFolder/');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyFolderWithinStorageCopiesSingleFileToNewFolderName(): void
     {
         mkdir($this->baseDirectory . '/sourceFolder');
@@ -1152,9 +1021,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertTrue(is_file($this->baseDirectory . '/targetFolder/newFolderName/file'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyFolderWithinStorageCopiesSingleSubFolderToNewFolderName(): void
     {
         mkdir($this->baseDirectory . '/sourceFolder');
@@ -1165,9 +1032,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertDirectoryExists($this->baseDirectory . '/targetFolder/newFolderName/subFolder');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyFolderWithinStorageCopiesFileInSingleSubFolderToNewFolderName(): void
     {
         mkdir($this->baseDirectory . '/sourceFolder');
@@ -1227,10 +1092,8 @@ final class LocalDriverTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider sanitizeFileNameUTF8FilesystemDataProvider
-     */
+    #[DataProvider('sanitizeFileNameUTF8FilesystemDataProvider')]
+    #[Test]
     public function sanitizeFileNameUTF8Filesystem(string $fileName, string $expectedResult): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem'] = 1;
@@ -1341,10 +1204,8 @@ final class LocalDriverTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider sanitizeFileNameNonUTF8FilesystemDataProvider
-     */
+    #[DataProvider('sanitizeFileNameNonUTF8FilesystemDataProvider')]
+    #[Test]
     public function sanitizeFileNameNonUTF8Filesystem(string $fileName, string $charset, string $expectedResult): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem'] = 0;
@@ -1352,9 +1213,7 @@ final class LocalDriverTest extends FunctionalTestCase
         self::assertEquals($expectedResult, $subject->sanitizeFileName($fileName, $charset));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function sanitizeFileNameThrowsExceptionOnInvalidFileName(): void
     {
         $this->expectException(InvalidFileNameException::class);
@@ -1364,9 +1223,7 @@ final class LocalDriverTest extends FunctionalTestCase
         $subject->sanitizeFileName('');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function applyFilterMethodsToDirectoryItemCallsFilterMethodIfClosure(): void
     {
         $this->expectException(\Exception::class);
diff --git a/typo3/sysext/core/Tests/Functional/Resource/FileReferenceTest.php b/typo3/sysext/core/Tests/Functional/Resource/FileReferenceTest.php
index 378ca18fe29f..aa6df8a7688a 100644
--- a/typo3/sysext/core/Tests/Functional/Resource/FileReferenceTest.php
+++ b/typo3/sysext/core/Tests/Functional/Resource/FileReferenceTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Resource;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Resource\FileReference;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -30,9 +31,7 @@ final class FileReferenceTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/Fixtures/FileReference.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fileReferenceCanBeDeleted(): void
     {
         $fileReference = GeneralUtility::makeInstance(FileReference::class, ['uid' => 1, 'uid_local' => 1]);
diff --git a/typo3/sysext/core/Tests/Functional/Resource/OnlineMedia/Processing/PreviewProcessingTest.php b/typo3/sysext/core/Tests/Functional/Resource/OnlineMedia/Processing/PreviewProcessingTest.php
index 07dacd7dbc26..80889923bee0 100644
--- a/typo3/sysext/core/Tests/Functional/Resource/OnlineMedia/Processing/PreviewProcessingTest.php
+++ b/typo3/sysext/core/Tests/Functional/Resource/OnlineMedia/Processing/PreviewProcessingTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Resource\OnlineMedia\Processing;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Core\EventDispatcher\ListenerProvider;
@@ -32,9 +33,7 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class PreviewProcessingTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function afterVideoPreviewFetchedEventIsTriggered(): void
     {
         $afterVideoPreviewFetchedEvent = null;
diff --git a/typo3/sysext/core/Tests/Functional/Resource/ProcessedFileTest.php b/typo3/sysext/core/Tests/Functional/Resource/ProcessedFileTest.php
index 6ac7ad9ae622..d544e8249d84 100644
--- a/typo3/sysext/core/Tests/Functional/Resource/ProcessedFileTest.php
+++ b/typo3/sysext/core/Tests/Functional/Resource/ProcessedFileTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Resource;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Resource\ProcessedFile;
 use TYPO3\CMS\Core\Resource\ResourceFactory;
@@ -42,9 +43,7 @@ final class ProcessedFileTest extends FunctionalTestCase
         Bootstrap::initializeLanguageObject();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function processedFileArrayCanBeSerialized(): void
     {
         $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
diff --git a/typo3/sysext/core/Tests/Functional/Resource/ResourceCompressorTest.php b/typo3/sysext/core/Tests/Functional/Resource/ResourceCompressorTest.php
index 287d6985fc36..fb3f1d3462c9 100644
--- a/typo3/sysext/core/Tests/Functional/Resource/ResourceCompressorTest.php
+++ b/typo3/sysext/core/Tests/Functional/Resource/ResourceCompressorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Resource;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Resource\ResourceCompressor;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -33,9 +35,7 @@ final class ResourceCompressorTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function initializeCreatesTargetDirectory(): void
     {
         $subject = $this->getAccessibleMock(ResourceCompressor::class, null);
@@ -43,9 +43,7 @@ final class ResourceCompressorTest extends FunctionalTestCase
         self::assertFileExists($this->instancePath . '/typo3temp/assets/compressed');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function initializeCreatesHtaccessFileIfSet(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['generateApacheHtaccess'] = true;
@@ -55,9 +53,7 @@ final class ResourceCompressorTest extends FunctionalTestCase
         self::assertStringEqualsFile($htaccessPath, $subject->_get('htaccessTemplate'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function initializeDoesNotCreateHtaccessFileIfSetToFalse(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['generateApacheHtaccess'] = false;
@@ -67,9 +63,7 @@ final class ResourceCompressorTest extends FunctionalTestCase
         self::assertFileDoesNotExist($htaccessPath);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function concatenateCssFiles(): void
     {
         $files = [
@@ -122,10 +116,9 @@ final class ResourceCompressorTest extends FunctionalTestCase
 
     /**
      * Tests optimizing a CSS asset group.
-     *
-     * @test
-     * @dataProvider compressCssFileContentDataProvider
      */
+    #[DataProvider('compressCssFileContentDataProvider')]
+    #[Test]
     public function compressCssFileContent(string $cssFile, string $expected): void
     {
         $cssContent = file_get_contents($cssFile);
@@ -158,10 +151,8 @@ final class ResourceCompressorTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getFilenamesFromMainDirInFrontendContextDataProvider
-     */
+    #[DataProvider('getFilenamesFromMainDirInFrontendContextDataProvider')]
+    #[Test]
     public function getFilenamesFromMainDirInFrontendContext(string $filename, string $expected): void
     {
         // getCurrentScript() called by PathUtility::getRelativePathTo() is usually something
diff --git a/typo3/sysext/core/Tests/Functional/Resource/ResourceStorageTest.php b/typo3/sysext/core/Tests/Functional/Resource/ResourceStorageTest.php
index 4147e3b8dfee..eff72c2c480e 100644
--- a/typo3/sysext/core/Tests/Functional/Resource/ResourceStorageTest.php
+++ b/typo3/sysext/core/Tests/Functional/Resource/ResourceStorageTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Resource;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\EventDispatcher\NoopEventDispatcher;
 use TYPO3\CMS\Core\Resource\Driver\DriverInterface;
 use TYPO3\CMS\Core\Resource\Driver\LocalDriver;
@@ -42,9 +44,7 @@ final class ResourceStorageTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addFileFailsIfFileDoesNotExist(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -55,9 +55,7 @@ final class ResourceStorageTest extends FunctionalTestCase
         $subject->addFile('/some/random/file', $folder);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPublicUrlReturnsNullIfStorageIsNotOnline(): void
     {
         $localDriver = new LocalDriver(['basePath' => $this->instancePath . '/resource-storage-test']);
@@ -98,10 +96,10 @@ final class ResourceStorageTest extends FunctionalTestCase
     }
 
     /**
-     * @test
-     * @dataProvider checkFolderPermissionsFilesystemPermissionsDataProvider
      * @param 'read'|'write' $action
      */
+    #[DataProvider('checkFolderPermissionsFilesystemPermissionsDataProvider')]
+    #[Test]
     public function checkFolderPermissionsRespectsFilesystemPermissions(string $action, array $permissionsFromDriver, bool $expectedResult): void
     {
         $localDriver = $this->getMockBuilder(LocalDriver::class)
@@ -125,9 +123,7 @@ final class ResourceStorageTest extends FunctionalTestCase
         self::assertSame($expectedResult, $subject->checkFolderActionPermission($action, $mockedFolder));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function checkUserActionPermissionsAlwaysReturnsTrueIfNoUserPermissionsAreSet(): void
     {
         $localDriver = new LocalDriver(['basePath' => $this->instancePath . '/resource-storage-test']);
@@ -135,9 +131,7 @@ final class ResourceStorageTest extends FunctionalTestCase
         self::assertTrue($subject->checkUserActionPermission('read', 'folder'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function checkUserActionPermissionReturnsFalseIfPermissionIsSetToZero(): void
     {
         $localDriver = new LocalDriver(['basePath' => $this->instancePath . '/resource-storage-test']);
@@ -170,10 +164,8 @@ final class ResourceStorageTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider checkUserActionPermission_arbitraryPermissionDataProvider
-     */
+    #[DataProvider('checkUserActionPermission_arbitraryPermissionDataProvider')]
+    #[Test]
     public function checkUserActionPermissionAcceptsArbitrarilyCasedArguments(array $permissions, string $action, string $type): void
     {
         $localDriver = new LocalDriver(['basePath' => $this->instancePath . '/resource-storage-test']);
@@ -182,9 +174,7 @@ final class ResourceStorageTest extends FunctionalTestCase
         self::assertTrue($subject->checkUserActionPermission($action, $type));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function userActionIsDisallowedIfPermissionIsSetToFalse(): void
     {
         $localDriver = new LocalDriver(['basePath' => $this->instancePath . '/resource-storage-test']);
@@ -194,9 +184,7 @@ final class ResourceStorageTest extends FunctionalTestCase
         self::assertFalse($subject->checkUserActionPermission('read', 'folder'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function userActionIsDisallowedIfPermissionIsNotSet(): void
     {
         $localDriver = new LocalDriver(['basePath' => $this->instancePath . '/resource-storage-test']);
@@ -206,9 +194,7 @@ final class ResourceStorageTest extends FunctionalTestCase
         self::assertFalse($subject->checkUserActionPermission('write', 'folder'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function metaDataEditIsNotAllowedWhenWhenNoFileMountsAreSet(): void
     {
         $localDriver = new LocalDriver(['basePath' => $this->instancePath . '/resource-storage-test']);
@@ -217,9 +203,7 @@ final class ResourceStorageTest extends FunctionalTestCase
         self::assertFalse($subject->checkFileActionPermission('editMeta', new File(['identifier' => '/foo/bar.jpg'], $subject)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getEvaluatePermissionsWhenSetFalse(): void
     {
         $localDriver = new LocalDriver(['basePath' => $this->instancePath . '/resource-storage-test']);
@@ -228,9 +212,7 @@ final class ResourceStorageTest extends FunctionalTestCase
         self::assertFalse($subject->getEvaluatePermissions());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getEvaluatePermissionsWhenSetTrue(): void
     {
         $localDriver = new LocalDriver(['basePath' => $this->instancePath . '/resource-storage-test']);
@@ -239,9 +221,7 @@ final class ResourceStorageTest extends FunctionalTestCase
         self::assertTrue($subject->getEvaluatePermissions());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteFolderThrowsExceptionIfFolderIsNotEmptyAndRecursiveDeleteIsDisabled(): void
     {
         $this->expectException(\RuntimeException::class);
@@ -255,9 +235,7 @@ final class ResourceStorageTest extends FunctionalTestCase
         $subject->deleteFolder($folderMock);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renameFileWillCallRenameFileIfUnsanitizedAndNoChangeInTargetFilename(): void
     {
         $driverMock = $this->getMockBuilder(LocalDriver::class)
diff --git a/typo3/sysext/core/Tests/Functional/Resource/Security/SvgSanitizerTest.php b/typo3/sysext/core/Tests/Functional/Resource/Security/SvgSanitizerTest.php
index 90d57752e397..00c04a68be56 100644
--- a/typo3/sysext/core/Tests/Functional/Resource/Security/SvgSanitizerTest.php
+++ b/typo3/sysext/core/Tests/Functional/Resource/Security/SvgSanitizerTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Resource\Security;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\Finder\Finder;
 use TYPO3\CMS\Core\Resource\Security\SvgSanitizer;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -47,10 +49,8 @@ final class SvgSanitizerTest extends FunctionalTestCase
         return $data;
     }
 
-    /**
-     * @test
-     * @dataProvider svgContentIsSanitizedDataProvider
-     */
+    #[DataProvider('svgContentIsSanitizedDataProvider')]
+    #[Test]
     public function svgContentIsSanitized(string $filePath, string $sanitizedFilePath): void
     {
         $sanitizer = new SvgSanitizer();
diff --git a/typo3/sysext/core/Tests/Functional/Resource/StorageRepositoryTest.php b/typo3/sysext/core/Tests/Functional/Resource/StorageRepositoryTest.php
index f49efadf2b1d..f43d60b94276 100644
--- a/typo3/sysext/core/Tests/Functional/Resource/StorageRepositoryTest.php
+++ b/typo3/sysext/core/Tests/Functional/Resource/StorageRepositoryTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Resource;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Resource\DuplicationBehavior;
 use TYPO3\CMS\Core\Resource\Exception\ExistingTargetFileNameException;
@@ -94,10 +96,8 @@ final class StorageRepositoryTest extends FunctionalTestCase
         yield ['{public}/files/nested/images/img.png', '6:/images/img.png'];
     }
 
-    /**
-     * @test
-     * @dataProvider bestStorageIsResolvedDataProvider
-     */
+    #[DataProvider('bestStorageIsResolvedDataProvider')]
+    #[Test]
     public function bestStorageIsResolved(string $sourceIdentifier, string $expectedCombinedIdentifier): void
     {
         $subject = GeneralUtility::makeInstance(StorageRepository::class);
@@ -136,9 +136,7 @@ final class StorageRepositoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getNestedProcessingFolderTest(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_file_storage.csv');
@@ -210,10 +208,8 @@ final class StorageRepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider isWithinFileMountBoundariesDataProvider
-     */
+    #[DataProvider('isWithinFileMountBoundariesDataProvider')]
+    #[Test]
     public function isWithinFileMountBoundariesRespectsReadOnlyFileMounts(string $targetDirectory, string $fileMountFolder, bool $isFileMountReadOnly, bool $checkWriteAccess, bool $expectedResult): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_file_storage.csv');
@@ -234,9 +230,7 @@ final class StorageRepositoryTest extends FunctionalTestCase
         self::assertSame($expectedResult, $subject->isWithinFileMountBoundaries($file, $checkWriteAccess));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getProcessingRootFolderTest(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_file_storage.csv');
@@ -247,9 +241,7 @@ final class StorageRepositoryTest extends FunctionalTestCase
         self::assertInstanceOf(Folder::class, $processingFolder);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getRoleReturnsDefaultForRegularFolders(): void
     {
         $folderIdentifier = StringUtility::getUniqueId();
@@ -262,9 +254,7 @@ final class StorageRepositoryTest extends FunctionalTestCase
         self::assertSame(FolderInterface::ROLE_DEFAULT, $role);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function replaceFileFailsIfLocalFileDoesNotExist(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_file_storage.csv');
@@ -279,9 +269,7 @@ final class StorageRepositoryTest extends FunctionalTestCase
         $subject->replaceFile($file, Environment::getPublicPath() . '/' . StringUtility::getUniqueId());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createFolderThrowsExceptionIfParentFolderDoesNotExist(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_file_storage.csv');
@@ -293,9 +281,7 @@ final class StorageRepositoryTest extends FunctionalTestCase
         $subject->createFolder('newFolder', new Folder($subject, '/foo/', 'foo'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteFileMovesFileToRecyclerFolderIfAvailable(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_file_storage.csv');
@@ -311,9 +297,7 @@ final class StorageRepositoryTest extends FunctionalTestCase
         self::assertFileDoesNotExist(Environment::getPublicPath() . '/fileadmin/foo/bar.txt');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deleteFileUnlinksFileIfNoRecyclerFolderAvailable(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_file_storage.csv');
@@ -450,10 +434,10 @@ final class StorageRepositoryTest extends FunctionalTestCase
     }
 
     /**
-     * @test
-     * @dataProvider searchFilesFindsFilesInFolderDataProvider
      * @param string[] $expectedIdentifiers
      */
+    #[DataProvider('searchFilesFindsFilesInFolderDataProvider')]
+    #[Test]
     public function searchFilesFindsFilesInFolder(string $searchTerm, ?string $searchFolder, bool $recursive, array $filters, array $expectedIdentifiers): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_file_storage.csv');
@@ -487,9 +471,7 @@ final class StorageRepositoryTest extends FunctionalTestCase
         self::assertSame($expectedFiles, iterator_to_array($result));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyFolderThrowsErrorWhenFolderAlreadyExistsInTargetFolderAndConflictModeIsCancel(): void
     {
         $conflictMode = (string)DuplicationBehavior::cast(DuplicationBehavior::CANCEL);
@@ -505,9 +487,7 @@ final class StorageRepositoryTest extends FunctionalTestCase
         $subject->copyFolder($folderToCopy, $targetParentFolder, null, $conflictMode);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyFolderGeneratesNewFolderNameWhenFolderAlreadyExistsInTargetFolderAndConflictModeIsRename(): void
     {
         $conflictMode = (string)DuplicationBehavior::cast(DuplicationBehavior::RENAME);
@@ -523,9 +503,7 @@ final class StorageRepositoryTest extends FunctionalTestCase
         self::assertInstanceOf(Folder::class, $newFolder);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyFileThrowsErrorWhenFileWithSameNameAlreadyExistsInTargetFolderAndConflictModeIsCancel(): void
     {
         $conflictMode = (string)DuplicationBehavior::cast(DuplicationBehavior::CANCEL);
@@ -543,9 +521,7 @@ final class StorageRepositoryTest extends FunctionalTestCase
         $subject->copyFile($fileToCopy, $targetParentFolder, null, $conflictMode);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyFileGeneratesNewFileNameWhenFileAlreadyExistsInTargetFolderAndConflictModeIsRename(): void
     {
         $conflictMode = (string)DuplicationBehavior::cast(DuplicationBehavior::RENAME);
@@ -563,9 +539,7 @@ final class StorageRepositoryTest extends FunctionalTestCase
         self::assertInstanceOf(File::class, $newFile);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function copyFileCopiesMetadata(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_file_storage.csv');
diff --git a/typo3/sysext/core/Tests/Functional/Resource/SynchronizeFolderRelationsTest.php b/typo3/sysext/core/Tests/Functional/Resource/SynchronizeFolderRelationsTest.php
index abc9c3a38ea5..73eaa5f1818a 100644
--- a/typo3/sysext/core/Tests/Functional/Resource/SynchronizeFolderRelationsTest.php
+++ b/typo3/sysext/core/Tests/Functional/Resource/SynchronizeFolderRelationsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Resource;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Messaging\FlashMessageService;
@@ -46,9 +47,7 @@ final class SynchronizeFolderRelationsTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function synchronizeFilemountsAfterRenameTest(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/FilemountsBase.csv');
@@ -70,9 +69,7 @@ final class SynchronizeFolderRelationsTest extends FunctionalTestCase
         self::assertStringContainsString('6 Filemount records', $flashMessage->getMessage());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function synchronizeFileCollectionsAfterRenameTest(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/FileCollectionBase.csv');
diff --git a/typo3/sysext/core/Tests/Functional/Routing/Aspect/PersistedAliasMapperTest.php b/typo3/sysext/core/Tests/Functional/Routing/Aspect/PersistedAliasMapperTest.php
index af696e179c9f..8f1561ba4e85 100644
--- a/typo3/sysext/core/Tests/Functional/Routing/Aspect/PersistedAliasMapperTest.php
+++ b/typo3/sysext/core/Tests/Functional/Routing/Aspect/PersistedAliasMapperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Routing\Aspect;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use TYPO3\CMS\Core\Configuration\SiteConfiguration;
 use TYPO3\CMS\Core\Context\Context;
@@ -194,10 +196,8 @@ final class PersistedAliasMapperTest extends FunctionalTestCase
         return $dataSet;
     }
 
-    /**
-     * @test
-     * @dataProvider languageAwareRecordsAreResolvedDataProvider
-     */
+    #[DataProvider('languageAwareRecordsAreResolvedDataProvider')]
+    #[Test]
     public function languageAwareRecordsAreResolved(string $identifier, string $requestValue, string $language, ?string $expectation): void
     {
         $this->subject->setSiteLanguage(
@@ -267,10 +267,8 @@ final class PersistedAliasMapperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider recordVisibilityDataProvider
-     */
+    #[DataProvider('recordVisibilityDataProvider')]
+    #[Test]
     public function recordVisibilityIsConsideredForResolving(Context $context, array $parameters, bool $expectation): void
     {
         $this->subject->setContext($context);
@@ -278,10 +276,8 @@ final class PersistedAliasMapperTest extends FunctionalTestCase
         self::assertSame($expectedResult, $this->subject->resolve($parameters['slug']));
     }
 
-    /**
-     * @test
-     * @dataProvider recordVisibilityDataProvider
-     */
+    #[DataProvider('recordVisibilityDataProvider')]
+    #[Test]
     public function recordVisibilityIsConsideredForGeneration(Context $context, array $parameters, bool $expectation): void
     {
         $this->subject->setContext($context);
@@ -289,9 +285,7 @@ final class PersistedAliasMapperTest extends FunctionalTestCase
         self::assertSame($expectedResult, $this->subject->generate($parameters['uid']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function generateWithUidOfExistingPageReturnsPageSlug(): void
     {
         $result = $this->subject->generate('3010');
@@ -299,9 +293,7 @@ final class PersistedAliasMapperTest extends FunctionalTestCase
         self::assertSame('30xx-slug', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function generateWithUidOfExistingPageSuffixedWithGarbageStringReturnsNull(): void
     {
         $result = $this->subject->generate('3010-i-am-garbage');
diff --git a/typo3/sysext/core/Tests/Functional/Routing/Aspect/PersistedPatternMapperTest.php b/typo3/sysext/core/Tests/Functional/Routing/Aspect/PersistedPatternMapperTest.php
index b8d7bc4dea5e..f5fd18003db8 100644
--- a/typo3/sysext/core/Tests/Functional/Routing/Aspect/PersistedPatternMapperTest.php
+++ b/typo3/sysext/core/Tests/Functional/Routing/Aspect/PersistedPatternMapperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Routing\Aspect;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use TYPO3\CMS\Core\Configuration\SiteConfiguration;
 use TYPO3\CMS\Core\Context\Context;
@@ -202,10 +204,8 @@ final class PersistedPatternMapperTest extends FunctionalTestCase
         return $dataSet;
     }
 
-    /**
-     * @test
-     * @dataProvider languageAwareRecordsAreResolvedDataProvider
-     */
+    #[DataProvider('languageAwareRecordsAreResolvedDataProvider')]
+    #[Test]
     public function languageAwareRecordsAreResolved(string $identifier, string $requestValue, string $language, ?string $expectation): void
     {
         $this->subject->setSiteLanguage(
@@ -275,10 +275,8 @@ final class PersistedPatternMapperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider recordVisibilityDataProvider
-     */
+    #[DataProvider('recordVisibilityDataProvider')]
+    #[Test]
     public function recordVisibilityIsConsideredForResolving(Context $context, array $parameters, bool $expectation): void
     {
         $this->subject->setContext($context);
@@ -286,10 +284,8 @@ final class PersistedPatternMapperTest extends FunctionalTestCase
         self::assertSame($expectedResult, $this->subject->resolve($parameters['slug']));
     }
 
-    /**
-     * @test
-     * @dataProvider recordVisibilityDataProvider
-     */
+    #[DataProvider('recordVisibilityDataProvider')]
+    #[Test]
     public function recordVisibilityIsConsideredForGeneration(Context $context, array $parameters, bool $expectation): void
     {
         $this->subject->setContext($context);
@@ -297,9 +293,7 @@ final class PersistedPatternMapperTest extends FunctionalTestCase
         self::assertSame($expectedResult, $this->subject->generate($parameters['uid']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function generateWithUidOfExistingPageReturnsPageSlug(): void
     {
         $result = $this->subject->generate('3010');
@@ -307,9 +301,7 @@ final class PersistedPatternMapperTest extends FunctionalTestCase
         self::assertSame('30xx-slug-0', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function generateWithUidOfExistingPageSuffixedWithGarbageStringReturnsNull(): void
     {
         $result = $this->subject->generate('3010-i-am-garbage');
diff --git a/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/ModelServiceTest.php b/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/ModelServiceTest.php
index 377fc26acdf6..0a64525be975 100644
--- a/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/ModelServiceTest.php
+++ b/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/ModelServiceTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Security\ContentSecurityPolicy;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Security\ContentSecurityPolicy\HashProxy;
 use TYPO3\CMS\Core\Security\ContentSecurityPolicy\HashValue;
 use TYPO3\CMS\Core\Security\ContentSecurityPolicy\ModelService;
@@ -57,18 +59,14 @@ final class ModelServiceTest extends FunctionalTestCase
         yield 'wss:' => ['wss:', SourceScheme::wss];
     }
 
-    /**
-     * @test
-     * @dataProvider enumSourceInterfaceIsBuiltFromStringDataProvider
-     */
+    #[DataProvider('enumSourceInterfaceIsBuiltFromStringDataProvider')]
+    #[Test]
     public function enumSourceInterfaceIsBuiltFromString(string $string, SourceInterface $expectation): void
     {
         self::assertSame($expectation, $this->subject->buildSourceFromString($string));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function uriValueIsBuiltFromString(): void
     {
         $uri = 'https://*.example.org/';
@@ -77,9 +75,7 @@ final class ModelServiceTest extends FunctionalTestCase
         self::assertSame($uri, (string)$source);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function rawValueIsBuiltFromString(): void
     {
         $value = 'https:////slashes.example.org';
@@ -88,9 +84,7 @@ final class ModelServiceTest extends FunctionalTestCase
         self::assertSame($value, (string)$source);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hashValueIsBuiltFromString(): void
     {
         $hash = hash('sha256', 'test', true);
@@ -101,9 +95,7 @@ final class ModelServiceTest extends FunctionalTestCase
         self::assertSame($hashB64, $source->value);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function urlHashProxyIsBuiltFromString(): void
     {
         $url = 'https://example.org/file.js';
@@ -150,10 +142,8 @@ final class ModelServiceTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider buildMutationFromArrayThrowsValueErrorDataProvider
-     */
+    #[DataProvider('buildMutationFromArrayThrowsValueErrorDataProvider')]
+    #[Test]
     public function buildMutationFromArrayThrowsValueError(array $array, string $expectedErrorMessage): void
     {
         $this->expectException(\ValueError::class);
diff --git a/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/PolicyProviderTest.php b/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/PolicyProviderTest.php
index 363903dda1c4..8c509e77a92f 100644
--- a/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/PolicyProviderTest.php
+++ b/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/PolicyProviderTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Security\ContentSecurityPolicy;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\ServerRequestInterface;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -112,10 +114,8 @@ final class PolicyProviderTest extends FunctionalTestCase
         yield [Scope::backend(), null, true, 'https://website.fallback/typo3/@http-reporting?csp=report'];
     }
 
-    /**
-     * @test
-     * @dataProvider defaultReportingUriBaseIsResolvedDataProvider
-     */
+    #[DataProvider('defaultReportingUriBaseIsResolvedDataProvider')]
+    #[Test]
     public function defaultReportingUriBaseIsResolved(Scope $scope, ?string $languagePreset, bool $absolute, string $expectation): void
     {
         $request = $this->buildServerRequest($scope, $languagePreset);
diff --git a/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/PolicyTest.php b/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/PolicyTest.php
index 29aa2a40faad..09bc69d6be71 100644
--- a/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/PolicyTest.php
+++ b/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/PolicyTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Security\ContentSecurityPolicy;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Security\ContentSecurityPolicy\ConsumableNonce;
 use TYPO3\CMS\Core\Security\ContentSecurityPolicy\Directive;
 use TYPO3\CMS\Core\Security\ContentSecurityPolicy\HashProxy;
@@ -41,9 +43,7 @@ final class PolicyTest extends FunctionalTestCase
         $this->nonce = new ConsumableNonce();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hashProxyIsCompiled(): void
     {
         // ```
@@ -58,9 +58,7 @@ final class PolicyTest extends FunctionalTestCase
         self::assertSame("script-src 'sha256-dawsv3oUbEz6NVoOxXFAu0k7W3I/PS6NucUIAmvoIng='", $policy->compile($this->nonce));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hashValueIsCompiled(): void
     {
         $hash = hash('sha256', 'test', true);
@@ -69,18 +67,14 @@ final class PolicyTest extends FunctionalTestCase
         self::assertSame("script-src 'sha256-$hashB64'", $policy->compile($this->nonce));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function constructorSetsdefaultDirective(): void
     {
         $policy = (new Policy(SourceKeyword::self));
         self::assertSame("default-src 'self'", $policy->compile($this->nonce));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function defaultDirectiveIsModified(): void
     {
         $policy = (new Policy(SourceKeyword::self))
@@ -88,9 +82,7 @@ final class PolicyTest extends FunctionalTestCase
         self::assertSame("default-src 'none'", $policy->compile($this->nonce));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function defaultDirectiveConsidersVeto(): void
     {
         $policy = (new Policy(SourceKeyword::self))
@@ -98,9 +90,7 @@ final class PolicyTest extends FunctionalTestCase
         self::assertSame("default-src 'none'", $policy->compile($this->nonce));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function newDirectiveExtendsDefault(): void
     {
         $policy = (new Policy(SourceKeyword::self))
@@ -108,9 +98,7 @@ final class PolicyTest extends FunctionalTestCase
         self::assertSame("default-src 'self'; script-src 'self' 'unsafe-inline'", $policy->compile($this->nonce));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function nonAncestorDirectiveDoesNotExtendDefault(): void
     {
         $policy = (new Policy(SourceKeyword::self))
@@ -160,19 +148,15 @@ final class PolicyTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider ancestorInheritanceIsAppliedFromMutationsDataProvider
-     */
+    #[DataProvider('ancestorInheritanceIsAppliedFromMutationsDataProvider')]
+    #[Test]
     public function ancestorInheritanceIsAppliedFromMutations(MutationCollection $mutations, string $expectation): void
     {
         $policy = (new Policy())->mutate($mutations);
         self::assertSame($expectation, $policy->compile($this->nonce));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function newDirectiveDoesNotExtendDefault(): void
     {
         $policy = (new Policy(SourceKeyword::self))
@@ -180,9 +164,7 @@ final class PolicyTest extends FunctionalTestCase
         self::assertSame("default-src 'self'; script-src 'unsafe-inline'", $policy->compile($this->nonce));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function directiveIsReduced(): void
     {
         $policy = (new Policy())
@@ -191,18 +173,14 @@ final class PolicyTest extends FunctionalTestCase
         self::assertSame("script-src 'unsafe-inline'", $policy->compile($this->nonce));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function sourceSchemeIsCompiled(): void
     {
         $policy = (new Policy(SourceKeyword::self, SourceScheme::blob));
         self::assertSame("default-src 'self' blob:", $policy->compile($this->nonce));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function nonceProxyIsCompiled(): void
     {
         $policy = (new Policy(SourceKeyword::self, SourceKeyword::nonceProxy));
@@ -211,9 +189,8 @@ final class PolicyTest extends FunctionalTestCase
 
     /**
      * `strict-dynamic` is only allowed for `script-src*` and implicitly adds a `nonce-proxy`.
-     *
-     * @test
      */
+    #[Test]
     public function strictDynamicIsApplied(): void
     {
         $policy = (new Policy(SourceKeyword::self, SourceKeyword::strictDynamic))
@@ -225,9 +202,7 @@ final class PolicyTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function directiveIsRemoved(): void
     {
         $policy = (new Policy(SourceKeyword::self))
@@ -235,9 +210,7 @@ final class PolicyTest extends FunctionalTestCase
         self::assertSame('', $policy->compile($this->nonce));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function superfluousDirectivesArePurged(): void
     {
         $policy = (new Policy(SourceKeyword::self, SourceScheme::data))
@@ -245,9 +218,7 @@ final class PolicyTest extends FunctionalTestCase
         self::assertSame("default-src 'self' data:", $policy->compile($this->nonce));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function backendPolicyIsCompiled(): void
     {
         $policy = (new Policy())
@@ -266,9 +237,7 @@ final class PolicyTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function containedDirectiveSourcesAreDetermined(): void
     {
         $policy = (new Policy())
@@ -280,9 +249,7 @@ final class PolicyTest extends FunctionalTestCase
         self::assertFalse($policy->containsDirective(Directive::ConnectSrc, SourceScheme::https));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function coveredDirectiveSourcesAreDetermined(): void
     {
         $policy = (new Policy())
@@ -294,9 +261,7 @@ final class PolicyTest extends FunctionalTestCase
         self::assertFalse($policy->coversDirective(Directive::ConnectSrc, SourceScheme::https));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function containedPolicyIsDetermined(): void
     {
         $policy = (new Policy())
diff --git a/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/Reporting/ReportRepositoryTest.php b/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/Reporting/ReportRepositoryTest.php
index 69a2e37fe980..6d40ed5a75be 100644
--- a/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/Reporting/ReportRepositoryTest.php
+++ b/typo3/sysext/core/Tests/Functional/Security/ContentSecurityPolicy/Reporting/ReportRepositoryTest.php
@@ -17,14 +17,13 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Security\ContentSecurityPolicy\Reporting;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Security\ContentSecurityPolicy\Reporting\ReportRepository;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class ReportRepositoryTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function findAllSummarizedReturnsAllSummaries(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/sys_http_report.csv');
diff --git a/typo3/sysext/core/Tests/Functional/Service/Archive/ZipServiceTest.php b/typo3/sysext/core/Tests/Functional/Service/Archive/ZipServiceTest.php
index 38d4b7d34348..de6e7fe8488c 100644
--- a/typo3/sysext/core/Tests/Functional/Service/Archive/ZipServiceTest.php
+++ b/typo3/sysext/core/Tests/Functional/Service/Archive/ZipServiceTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Service\Archive;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Exception\Archive\ExtractException;
 use TYPO3\CMS\Core\Service\Archive\ZipService;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -33,9 +34,7 @@ final class ZipServiceTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function filesCanNotGetExtractedOutsideTargetDirectory(): void
     {
         $extensionDirectory = $this->instancePath . '/typo3conf/ext/malicious';
@@ -51,9 +50,7 @@ final class ZipServiceTest extends FunctionalTestCase
         self::assertFalse(is_link($extensionDirectory . '/passwd'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fileContentIsExtractedAsExpected(): void
     {
         $extensionDirectory = $this->instancePath . '/typo3conf/ext/my_extension';
@@ -67,9 +64,7 @@ final class ZipServiceTest extends FunctionalTestCase
         self::assertFileExists($extensionDirectory . '/ext_emconf.php');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fileContentIsExtractedAsExpectedAndSetsPermissions(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['fileCreateMask'] = '0777';
@@ -89,9 +84,7 @@ final class ZipServiceTest extends FunctionalTestCase
         self::assertEquals($GLOBALS['TYPO3_CONF_VARS']['SYS']['folderCreateMask'], substr(sprintf('%o', $folderPerms), -4));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function nonExistentFileThrowsException(): void
     {
         $this->expectException(ExtractException::class);
@@ -104,9 +97,7 @@ final class ZipServiceTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function nonExistentDirectoryThrowsException(): void
     {
         $this->expectException(\RuntimeException::class);
@@ -117,9 +108,7 @@ final class ZipServiceTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyDetectsValidArchive(): void
     {
         self::assertTrue(
@@ -127,9 +116,7 @@ final class ZipServiceTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function verifyDetectsSuspiciousSequences(): void
     {
         $this->expectException(ExtractException::class);
diff --git a/typo3/sysext/core/Tests/Functional/Session/Backend/DatabaseSessionBackendTest.php b/typo3/sysext/core/Tests/Functional/Session/Backend/DatabaseSessionBackendTest.php
index 2542cbd150d9..29fe1b96f52c 100644
--- a/typo3/sysext/core/Tests/Functional/Session/Backend/DatabaseSessionBackendTest.php
+++ b/typo3/sysext/core/Tests/Functional/Session/Backend/DatabaseSessionBackendTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Session\Backend;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Session\Backend\DatabaseSessionBackend;
 use TYPO3\CMS\Core\Session\Backend\Exception\SessionNotCreatedException;
 use TYPO3\CMS\Core\Session\Backend\Exception\SessionNotFoundException;
@@ -55,17 +56,13 @@ final class DatabaseSessionBackendTest extends FunctionalTestCase
         ]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canValidateSessionBackend(): void
     {
         $this->subject->validateConfiguration();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function sessionDataIsStoredProperly(): void
     {
         $record = $this->subject->set('randomSessionId', $this->testSessionRecord);
@@ -77,9 +74,7 @@ final class DatabaseSessionBackendTest extends FunctionalTestCase
         self::assertSame($expected['ses_userid'], (int)$this->subject->get('randomSessionId')['ses_userid']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function anonymousSessionDataIsStoredProperly(): void
     {
         $record = $this->subject->set('randomSessionId', array_merge($this->testSessionRecord, ['ses_userid' => 0]));
@@ -91,9 +86,7 @@ final class DatabaseSessionBackendTest extends FunctionalTestCase
         self::assertSame($expected['ses_userid'], (int)$this->subject->get('randomSessionId')['ses_userid']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function throwExceptionOnNonExistingSessionId(): void
     {
         $this->expectException(SessionNotFoundException::class);
@@ -101,9 +94,7 @@ final class DatabaseSessionBackendTest extends FunctionalTestCase
         $this->subject->get('IDoNotExist');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function mergeSessionDataWithNewData(): void
     {
         $this->subject->set('randomSessionId', $this->testSessionRecord);
@@ -119,9 +110,7 @@ final class DatabaseSessionBackendTest extends FunctionalTestCase
         self::assertSame($expectedMergedData['ses_userid'], (int)$fetchedRecord['ses_userid']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function existingSessionMustNotBeOverridden(): void
     {
         $this->expectException(SessionNotCreatedException::class);
@@ -133,9 +122,7 @@ final class DatabaseSessionBackendTest extends FunctionalTestCase
         $this->subject->set('randomSessionId', $newData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function cannotChangeSessionId(): void
     {
         $this->subject->set('randomSessionId', $this->testSessionRecord);
@@ -156,9 +143,7 @@ final class DatabaseSessionBackendTest extends FunctionalTestCase
         $this->subject->get('newRandomSessionId');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function sessionGetsDestroyed(): void
     {
         $this->subject->set('randomSessionId', $this->testSessionRecord);
@@ -172,9 +157,7 @@ final class DatabaseSessionBackendTest extends FunctionalTestCase
         $this->subject->get('randomSessionId');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canLoadAllSessions(): void
     {
         $this->subject->set('randomSessionId', $this->testSessionRecord);
@@ -184,9 +167,7 @@ final class DatabaseSessionBackendTest extends FunctionalTestCase
         self::assertCount(2, $this->subject->getAll());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canCollectGarbage(): void
     {
         $GLOBALS['EXEC_TIME'] = 150;
@@ -233,9 +214,7 @@ final class DatabaseSessionBackendTest extends FunctionalTestCase
         $this->subject->get('anonymousSession');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canPartiallyUpdateAfterGet(): void
     {
         $updatedRecord = array_merge(
diff --git a/typo3/sysext/core/Tests/Functional/Session/Backend/RedisSessionBackendTest.php b/typo3/sysext/core/Tests/Functional/Session/Backend/RedisSessionBackendTest.php
index b71de460c9ea..c6b61c994717 100644
--- a/typo3/sysext/core/Tests/Functional/Session/Backend/RedisSessionBackendTest.php
+++ b/typo3/sysext/core/Tests/Functional/Session/Backend/RedisSessionBackendTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Session\Backend;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Session\Backend\Exception\SessionNotCreatedException;
 use TYPO3\CMS\Core\Session\Backend\Exception\SessionNotFoundException;
 use TYPO3\CMS\Core\Session\Backend\Exception\SessionNotUpdatedException;
@@ -89,9 +90,7 @@ final class RedisSessionBackendTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function cannotUpdateNonExistingRecord(): void
     {
         $this->expectException(SessionNotUpdatedException::class);
@@ -99,17 +98,13 @@ final class RedisSessionBackendTest extends FunctionalTestCase
         $this->subject->update('iSoNotExist', []);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canValidateSessionBackend(): void
     {
         $this->subject->validateConfiguration();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function sessionDataIsStoredProperly(): void
     {
         $record = $this->subject->set('randomSessionId', $this->testSessionRecord);
@@ -121,9 +116,7 @@ final class RedisSessionBackendTest extends FunctionalTestCase
         self::assertSame($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function anonymousSessionDataIsStoredProperly(): void
     {
         $record = $this->subject->set('randomSessionId', array_merge($this->testSessionRecord, ['ses_userid' => 0]));
@@ -134,9 +127,7 @@ final class RedisSessionBackendTest extends FunctionalTestCase
         self::assertSame($expected, $this->subject->get('randomSessionId'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function throwExceptionOnNonExistingSessionId(): void
     {
         $this->expectException(SessionNotFoundException::class);
@@ -144,9 +135,7 @@ final class RedisSessionBackendTest extends FunctionalTestCase
         $this->subject->get('IDoNotExist');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function mergeSessionDataWithNewData(): void
     {
         $this->subject->set('randomSessionId', $this->testSessionRecord);
@@ -161,9 +150,7 @@ final class RedisSessionBackendTest extends FunctionalTestCase
         self::assertSame($expectedMergedData, $fetchedRecord);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function existingSessionMustNotBeOverridden(): void
     {
         $this->expectException(SessionNotCreatedException::class);
@@ -175,9 +162,7 @@ final class RedisSessionBackendTest extends FunctionalTestCase
         $this->subject->set('randomSessionId', $newData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function cannotChangeSessionId(): void
     {
         $this->subject->set('randomSessionId', $this->testSessionRecord);
@@ -197,9 +182,7 @@ final class RedisSessionBackendTest extends FunctionalTestCase
         $this->subject->get('newRandomSessionId');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function sessionGetsDestroyed(): void
     {
         $this->subject->set('randomSessionId', $this->testSessionRecord);
@@ -213,9 +196,7 @@ final class RedisSessionBackendTest extends FunctionalTestCase
         $this->subject->get('randomSessionId');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canLoadAllSessions(): void
     {
         $this->subject->set('randomSessionId', $this->testSessionRecord);
@@ -225,9 +206,7 @@ final class RedisSessionBackendTest extends FunctionalTestCase
         self::assertCount(2, $this->subject->getAll());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canCollectGarbage(): void
     {
         $GLOBALS['EXEC_TIME'] = 150;
@@ -274,9 +253,7 @@ final class RedisSessionBackendTest extends FunctionalTestCase
         $this->subject->get('anonymousSession');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canPartiallyUpdateAfterGet(): void
     {
         $updatedRecord = array_merge(
diff --git a/typo3/sysext/core/Tests/Functional/Session/SessionManagerTest.php b/typo3/sysext/core/Tests/Functional/Session/SessionManagerTest.php
index 0e514660f5c6..f5c7a4e2376f 100644
--- a/typo3/sysext/core/Tests/Functional/Session/SessionManagerTest.php
+++ b/typo3/sysext/core/Tests/Functional/Session/SessionManagerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Session;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Session\SessionManager;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -67,9 +68,7 @@ final class SessionManagerTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function clearAllSessionsByUserIdDestroyAllSessionsForBackend(): void
     {
         $backendSessionBackend = $this->subject->getSessionBackend('BE');
@@ -82,9 +81,7 @@ final class SessionManagerTest extends FunctionalTestCase
         self::assertSame(2, (int)$allActiveSessions[0]['ses_userid']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function clearAllSessionsByUserIdDestroyAllSessionsForFrontend(): void
     {
         $frontendSessionBackend = $this->subject->getSessionBackend('FE');
diff --git a/typo3/sysext/core/Tests/Functional/Tca/BackendGroupsVisibleFieldsTest.php b/typo3/sysext/core/Tests/Functional/Tca/BackendGroupsVisibleFieldsTest.php
index a2123c1b19ae..a62c31de11c3 100644
--- a/typo3/sysext/core/Tests/Functional/Tca/BackendGroupsVisibleFieldsTest.php
+++ b/typo3/sysext/core/Tests/Functional/Tca/BackendGroupsVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -44,9 +45,7 @@ final class BackendGroupsVisibleFieldsTest extends FunctionalTestCase
         'TSconfig',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function backendGroupsFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/core/Tests/Functional/Tca/BackendUsersVisibleFieldsTest.php b/typo3/sysext/core/Tests/Functional/Tca/BackendUsersVisibleFieldsTest.php
index da28acf69842..4cce14c3d31f 100644
--- a/typo3/sysext/core/Tests/Functional/Tca/BackendUsersVisibleFieldsTest.php
+++ b/typo3/sysext/core/Tests/Functional/Tca/BackendUsersVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -60,9 +61,7 @@ final class BackendUsersVisibleFieldsTest extends FunctionalTestCase
         'lastlogin' => 'Last login',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function backendUsersFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -87,9 +86,7 @@ final class BackendUsersVisibleFieldsTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function backendUsersFormContainsExpectedFieldsForAdmins(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/core/Tests/Functional/Tca/CategoryVisibleFieldsTest.php b/typo3/sysext/core/Tests/Functional/Tca/CategoryVisibleFieldsTest.php
index b60d2cc7f581..23778452544b 100644
--- a/typo3/sysext/core/Tests/Functional/Tca/CategoryVisibleFieldsTest.php
+++ b/typo3/sysext/core/Tests/Functional/Tca/CategoryVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -35,9 +36,7 @@ final class CategoryVisibleFieldsTest extends FunctionalTestCase
         'endtime',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function categoryFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/core/Tests/Functional/Tca/FileCollectionVisibleFieldsTest.php b/typo3/sysext/core/Tests/Functional/Tca/FileCollectionVisibleFieldsTest.php
index 42be4ff62abb..bafd8f1e5f0a 100644
--- a/typo3/sysext/core/Tests/Functional/Tca/FileCollectionVisibleFieldsTest.php
+++ b/typo3/sysext/core/Tests/Functional/Tca/FileCollectionVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -42,9 +43,7 @@ final class FileCollectionVisibleFieldsTest extends FunctionalTestCase
         'static' => ['files'],
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fileCollectionFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/core/Tests/Functional/Tca/FileMetadataVisibleFieldsTest.php b/typo3/sysext/core/Tests/Functional/Tca/FileMetadataVisibleFieldsTest.php
index 6743e0feaa07..3bba2e9388c3 100644
--- a/typo3/sysext/core/Tests/Functional/Tca/FileMetadataVisibleFieldsTest.php
+++ b/typo3/sysext/core/Tests/Functional/Tca/FileMetadataVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -31,9 +32,7 @@ final class FileMetadataVisibleFieldsTest extends FunctionalTestCase
         'categories',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fileMetadataFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/core/Tests/Functional/Tca/FileStorageVisibleFieldsTest.php b/typo3/sysext/core/Tests/Functional/Tca/FileStorageVisibleFieldsTest.php
index a36aa1071d40..14540419670b 100644
--- a/typo3/sysext/core/Tests/Functional/Tca/FileStorageVisibleFieldsTest.php
+++ b/typo3/sysext/core/Tests/Functional/Tca/FileStorageVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -37,9 +38,7 @@ final class FileStorageVisibleFieldsTest extends FunctionalTestCase
         'is_online',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fileStorageFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/core/Tests/Functional/Tca/NewsVisibleFieldsTest.php b/typo3/sysext/core/Tests/Functional/Tca/NewsVisibleFieldsTest.php
index f04f8a880efa..881f912abb0c 100644
--- a/typo3/sysext/core/Tests/Functional/Tca/NewsVisibleFieldsTest.php
+++ b/typo3/sysext/core/Tests/Functional/Tca/NewsVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -32,9 +33,7 @@ final class NewsVisibleFieldsTest extends FunctionalTestCase
         'endtime',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function newsFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/core/Tests/Functional/Tca/PagesVisibleFieldsTest.php b/typo3/sysext/core/Tests/Functional/Tca/PagesVisibleFieldsTest.php
index f9882910f5d5..a7a925b2c40e 100644
--- a/typo3/sysext/core/Tests/Functional/Tca/PagesVisibleFieldsTest.php
+++ b/typo3/sysext/core/Tests/Functional/Tca/PagesVisibleFieldsTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Domain\Repository\PageRepository;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -226,10 +228,8 @@ final class PagesVisibleFieldsTest extends FunctionalTestCase
         return $pageTypes;
     }
 
-    /**
-     * @test
-     * @dataProvider pagesFormContainsExpectedFieldsDataProvider
-     */
+    #[DataProvider('pagesFormContainsExpectedFieldsDataProvider')]
+    #[Test]
     public function pagesFormContainsExpectedFields(int $doktype, array $expectedFields, array $hiddenFields): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/core/Tests/Functional/TypoScript/AST/AstBuilderInterfaceTest.php b/typo3/sysext/core/Tests/Functional/TypoScript/AST/AstBuilderInterfaceTest.php
index b13aba3db9e2..24be33106c0f 100644
--- a/typo3/sysext/core/Tests/Functional/TypoScript/AST/AstBuilderInterfaceTest.php
+++ b/typo3/sysext/core/Tests/Functional/TypoScript/AST/AstBuilderInterfaceTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\TypoScript\AST;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\TypoScript\AST\AstBuilder;
 use TYPO3\CMS\Core\TypoScript\AST\CommentAwareAstBuilder;
 use TYPO3\CMS\Core\TypoScript\AST\Node\RootNode;
@@ -34,9 +35,7 @@ final class AstBuilderInterfaceTest extends FunctionalTestCase
         'typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_typoscript_ast_function_event',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notModifiedValueKeepsNullValue(): void
     {
         $tokens = (new LosslessTokenizer())->tokenize('foo := doesNotExistFunction()');
@@ -46,9 +45,7 @@ final class AstBuilderInterfaceTest extends FunctionalTestCase
         self::assertEquals($ast, unserialize(serialize($ast)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notModifiedValueKeepsNullValueCommentAware(): void
     {
         $tokens = (new LosslessTokenizer())->tokenize('foo := doesNotExistFunction()');
@@ -58,9 +55,7 @@ final class AstBuilderInterfaceTest extends FunctionalTestCase
         self::assertEquals($ast, unserialize(serialize($ast)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notModifiedValueKeepsOriginalValue(): void
     {
         $tokens = (new LosslessTokenizer())->tokenize(
@@ -73,9 +68,7 @@ final class AstBuilderInterfaceTest extends FunctionalTestCase
         self::assertEquals($ast, unserialize(serialize($ast)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notModifiedValueKeepsOriginalValueCommentAware(): void
     {
         $tokens = (new LosslessTokenizer())->tokenize(
@@ -88,9 +81,7 @@ final class AstBuilderInterfaceTest extends FunctionalTestCase
         self::assertEquals($ast, unserialize(serialize($ast)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifiedValueUpdatesOriginalValue(): void
     {
         $tokens = (new LosslessTokenizer())->tokenize(
@@ -103,9 +94,7 @@ final class AstBuilderInterfaceTest extends FunctionalTestCase
         self::assertEquals($ast, unserialize(serialize($ast)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifiedValueUpdatesOriginalValueCommentAware(): void
     {
         $tokens = (new LosslessTokenizer())->tokenize(
diff --git a/typo3/sysext/core/Tests/Functional/TypoScript/FrontendTypoScriptFactoryPageLayoutConditionTest.php b/typo3/sysext/core/Tests/Functional/TypoScript/FrontendTypoScriptFactoryPageLayoutConditionTest.php
index b217e6bd60e2..e635f5bf523b 100644
--- a/typo3/sysext/core/Tests/Functional/TypoScript/FrontendTypoScriptFactoryPageLayoutConditionTest.php
+++ b/typo3/sysext/core/Tests/Functional/TypoScript/FrontendTypoScriptFactoryPageLayoutConditionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\TypoScript;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -42,9 +43,7 @@ final class FrontendTypoScriptFactoryPageLayoutConditionTest extends FunctionalT
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function treePageLayoutConditionMetForBackendLayoutOnRootPage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/FrontendTypoScriptFactoryPageLayoutCondition/backendLayoutOnRoot.csv');
@@ -58,9 +57,7 @@ final class FrontendTypoScriptFactoryPageLayoutConditionTest extends FunctionalT
         self::assertStringContainsString('Default Layout', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function treePageLayoutConditionNotMetForBackendLayoutNextLevelOnRootPage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/FrontendTypoScriptFactoryPageLayoutCondition/backendLayoutNextLevelOnRoot.csv');
@@ -74,9 +71,7 @@ final class FrontendTypoScriptFactoryPageLayoutConditionTest extends FunctionalT
         self::assertStringNotContainsString('Default Layout', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function treePageLayoutConditionMetForBackendLayoutNextLevelInheritedOnSubpageLevel1(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/FrontendTypoScriptFactoryPageLayoutCondition/backendLayoutAndNextLevelOnRoot.csv');
@@ -90,9 +85,7 @@ final class FrontendTypoScriptFactoryPageLayoutConditionTest extends FunctionalT
         self::assertStringContainsString('Inherited Layout', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function treePageLayoutConditionMetForBackendLayoutNextLevelInheritedOnSubpageLevel2(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/FrontendTypoScriptFactoryPageLayoutCondition/backendLayoutAndNextLevelOnRootSubOverride1.csv');
@@ -106,9 +99,7 @@ final class FrontendTypoScriptFactoryPageLayoutConditionTest extends FunctionalT
         self::assertStringContainsString('Inherited Layout', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function treePageLayoutConditionMetForBackendLayoutOnSubpageLevel3(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/FrontendTypoScriptFactoryPageLayoutCondition/backendLayoutAndNextLevelOnRootSubOverride2.csv');
@@ -122,9 +113,7 @@ final class FrontendTypoScriptFactoryPageLayoutConditionTest extends FunctionalT
         self::assertStringContainsString('Extra Layout', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function treePageLayoutConditionMetForBackendLayoutNextLevelOverrideOnSubpageLevel3(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/FrontendTypoScriptFactoryPageLayoutCondition/backendLayoutAndNextLevelOnRootSubOverride3.csv');
diff --git a/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/SysTemplateRepositoryTest.php b/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/SysTemplateRepositoryTest.php
index e67ab2052b93..e9088fee6bcc 100644
--- a/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/SysTemplateRepositoryTest.php
+++ b/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/SysTemplateRepositoryTest.php
@@ -17,14 +17,13 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\TypoScript\IncludeTree;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateRepository;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class SysTemplateRepositoryTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function singleRootTemplate(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysTemplate/singleRootTemplate.csv');
@@ -42,9 +41,7 @@ final class SysTemplateRepositoryTest extends FunctionalTestCase
         self::assertSame(1, $result[0]['uid']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function twoPagesTwoTemplates(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysTemplate/twoPagesTwoTemplates.csv');
@@ -69,9 +66,7 @@ final class SysTemplateRepositoryTest extends FunctionalTestCase
         self::assertSame(2, $result[1]['uid']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function twoTemplatesOnPagePrefersTheOneWithLowerSorting(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysTemplate/twoTemplatesOnPage.csv');
diff --git a/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/SysTemplateTreeBuilderTest.php b/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/SysTemplateTreeBuilderTest.php
index 136cfc29006e..b5b1e12aaf9c 100644
--- a/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/SysTemplateTreeBuilderTest.php
+++ b/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/SysTemplateTreeBuilderTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\TypoScript\IncludeTree;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Cache\CacheManager;
 use TYPO3\CMS\Core\Site\SiteFinder;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
@@ -66,9 +67,7 @@ final class SysTemplateTreeBuilderTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function singleRootTemplate(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysTemplate/singleRootTemplate.csv');
@@ -87,9 +86,7 @@ final class SysTemplateTreeBuilderTest extends FunctionalTestCase
         self::assertSame('fooValue', $ast->getChildByName('foo')->getValue());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function singleRootTemplateLoadsFromGlobals(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysTemplate/singleRootTemplate.csv');
@@ -110,9 +107,7 @@ final class SysTemplateTreeBuilderTest extends FunctionalTestCase
         self::assertSame('barValue', $ast->getChildByName('bar')->getValue());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function singleRootTemplateLoadConstantFromSite(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysTemplate/singleRootTemplate.csv');
@@ -137,9 +132,7 @@ final class SysTemplateTreeBuilderTest extends FunctionalTestCase
         self::assertSame('testValueFromSite', $ast->getChildByName('testConstantFromSite')->getValue());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function twoPagesTwoTemplates(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysTemplate/twoPagesTwoTemplates.csv');
@@ -164,9 +157,7 @@ final class SysTemplateTreeBuilderTest extends FunctionalTestCase
         self::assertSame('barValue', $ast->getChildByName('bar')->getValue());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function twoPagesTwoTemplatesWithoutClearForConstantsStillLoadsFromGlobals(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysTemplate/twoPagesTwoTemplatesNoClearForConstants.csv');
@@ -193,9 +184,7 @@ final class SysTemplateTreeBuilderTest extends FunctionalTestCase
         self::assertSame('globalsConstantValue', $ast->getChildByName('globalsConstant')->getValue());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function twoPagesTwoTemplatesWithoutClearForSetupStillLoadsFromGlobals(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysTemplate/twoPagesTwoTemplatesNoClearForSetup.csv');
@@ -222,9 +211,7 @@ final class SysTemplateTreeBuilderTest extends FunctionalTestCase
         self::assertSame('globalsValue', $ast->getChildByName('globalsKey')->getValue());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function twoPagesTwoTemplatesBothClear(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysTemplate/twoPagesTwoTemplatesBothClear.csv');
@@ -249,9 +236,7 @@ final class SysTemplateTreeBuilderTest extends FunctionalTestCase
         self::assertSame('barValue', $ast->getChildByName('bar')->getValue());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function twoTemplatesOnPagePrefersTheOneWithLowerSorting(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysTemplate/twoTemplatesOnPage.csv');
@@ -271,9 +256,7 @@ final class SysTemplateTreeBuilderTest extends FunctionalTestCase
         self::assertNull($ast->getChildByName('bar'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function basedOnSimple(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysTemplate/basedOnSimple.csv');
@@ -293,9 +276,7 @@ final class SysTemplateTreeBuilderTest extends FunctionalTestCase
         self::assertSame('loadedByBasedOn', $ast->getChildByName('bar')->getValue());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function basedOnAfterIncludeStatic(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysTemplate/basedOnAfterIncludeStatic.csv');
@@ -315,9 +296,7 @@ final class SysTemplateTreeBuilderTest extends FunctionalTestCase
         self::assertSame('loadedByBasedOn', $ast->getChildByName('bar')->getValue());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function basedOnBeforeIncludeStatic(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysTemplate/basedOnBeforeIncludeStatic.csv');
diff --git a/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/TreeFromLineStreamBuilderTest.php b/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/TreeFromLineStreamBuilderTest.php
index 68b28a60aa48..ff3b693595f2 100644
--- a/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/TreeFromLineStreamBuilderTest.php
+++ b/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/TreeFromLineStreamBuilderTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\TypoScript\IncludeTree;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\AtImportInclude;
 use TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\ConditionElseInclude;
 use TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\ConditionInclude;
@@ -281,10 +283,8 @@ final class TreeFromLineStreamBuilderTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider buildTreeConditionDataProvider
-     */
+    #[DataProvider('buildTreeConditionDataProvider')]
+    #[Test]
     public function buildTreeCondition(IncludeInterface $tree, IncludeInterface $expectedTree): void
     {
         $this->get(TreeFromLineStreamBuilder::class)->buildTree($tree, 'setup', new LossyTokenizer());
@@ -772,10 +772,8 @@ final class TreeFromLineStreamBuilderTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider buildTreeAtImportDataProvider
-     */
+    #[DataProvider('buildTreeAtImportDataProvider')]
+    #[Test]
     public function buildTreeAtImport(LineStream $lineStream, IncludeInterface $expectedTree): void
     {
         $tree = (new FileInclude());
@@ -809,10 +807,8 @@ final class TreeFromLineStreamBuilderTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider buildTreeAtImportTsConfigDataProvider
-     */
+    #[DataProvider('buildTreeAtImportTsConfigDataProvider')]
+    #[Test]
     public function buildTreeAtImportTsConfig(LineStream $lineStream, IncludeInterface $expectedTree): void
     {
         $tree = (new FileInclude());
@@ -1410,10 +1406,8 @@ final class TreeFromLineStreamBuilderTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider buildTreeImportTyposcriptDataProvider
-     */
+    #[DataProvider('buildTreeImportTyposcriptDataProvider')]
+    #[Test]
     public function buildTreeImportTyposcript(LineStream $lineStream, IncludeInterface $expectedTree): void
     {
         $tree = (new FileInclude());
@@ -1423,9 +1417,7 @@ final class TreeFromLineStreamBuilderTest extends FunctionalTestCase
         self::assertEquals($expectedTree, $tree);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function atImportIncludesMagicTypoScriptRenderingForSimpleFile(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['FE']['contentRenderingTemplates'] = [
@@ -1453,9 +1445,7 @@ final class TreeFromLineStreamBuilderTest extends FunctionalTestCase
         self::assertEquals($expectedTree, $tree);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function atImportIncludesMagicTypoScriptRenderingForSimpleFileWithoutDotTypoScriptEnding(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['FE']['contentRenderingTemplates'] = [
@@ -1483,9 +1473,7 @@ final class TreeFromLineStreamBuilderTest extends FunctionalTestCase
         self::assertEquals($expectedTree, $tree);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function atImportIncludesMagicTypoScriptRenderingForDirectoryInclude(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['FE']['contentRenderingTemplates'] = [
@@ -1529,9 +1517,7 @@ final class TreeFromLineStreamBuilderTest extends FunctionalTestCase
         self::assertEquals($expectedTree, $tree);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function atImportIncludesMagicTypoScriptRenderingForWildcardInclude(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['FE']['contentRenderingTemplates'] = [
@@ -1564,9 +1550,7 @@ final class TreeFromLineStreamBuilderTest extends FunctionalTestCase
         self::assertEquals($expectedTree, $tree);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importTyposcriptIncludesMagicTypoScriptRenderingForSimpleFile(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['FE']['contentRenderingTemplates'] = [
diff --git a/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/Visitor/IncludeTreeSetupConditionConstantSubstitutionVisitorTest.php b/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/Visitor/IncludeTreeSetupConditionConstantSubstitutionVisitorTest.php
index 1dbdfe768099..a88c29e78619 100644
--- a/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/Visitor/IncludeTreeSetupConditionConstantSubstitutionVisitorTest.php
+++ b/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/Visitor/IncludeTreeSetupConditionConstantSubstitutionVisitorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\TypoScript\IncludeTree\Visitor;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\ConditionInclude;
 use TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\FileInclude;
 use TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\IncludeInterface;
@@ -109,10 +111,8 @@ final class IncludeTreeSetupConditionConstantSubstitutionVisitorTest extends Fun
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider visitDataProvider
-     */
+    #[DataProvider('visitDataProvider')]
+    #[Test]
     public function visit(array $flattenedConstants, IncludeInterface $node, IncludeInterface $expectedNode): void
     {
         $subject = new IncludeTreeSetupConditionConstantSubstitutionVisitor();
diff --git a/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/Visitor/IncludeTreeSyntaxScannerVisitorTest.php b/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/Visitor/IncludeTreeSyntaxScannerVisitorTest.php
index 8c42815e8f70..4cdd46e5ecdc 100644
--- a/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/Visitor/IncludeTreeSyntaxScannerVisitorTest.php
+++ b/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/Visitor/IncludeTreeSyntaxScannerVisitorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\TypoScript\IncludeTree\Visitor;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\FileInclude;
 use TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\IncludeInterface;
 use TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateRepository;
@@ -126,10 +128,8 @@ final class IncludeTreeSyntaxScannerVisitorTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider visitDataProvider
-     */
+    #[DataProvider('visitDataProvider')]
+    #[Test]
     public function visit(IncludeInterface $node, array $expectedErrors): void
     {
         $subject = new IncludeTreeSyntaxScannerVisitor();
@@ -137,9 +137,7 @@ final class IncludeTreeSyntaxScannerVisitorTest extends FunctionalTestCase
         self::assertEquals($expectedErrors, $this->removeLineFromErrors($subject->getErrors()));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function visitFindsEmptyImports()
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/IncludeTreeSyntaxScannerVisitor/RootTemplate.csv');
diff --git a/typo3/sysext/core/Tests/Functional/TypoScript/PageTsConfigFactoryPageLayoutConditionTest.php b/typo3/sysext/core/Tests/Functional/TypoScript/PageTsConfigFactoryPageLayoutConditionTest.php
index b082be92a3b8..c5d2e4d7e963 100644
--- a/typo3/sysext/core/Tests/Functional/TypoScript/PageTsConfigFactoryPageLayoutConditionTest.php
+++ b/typo3/sysext/core/Tests/Functional/TypoScript/PageTsConfigFactoryPageLayoutConditionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\TypoScript;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Site\Entity\NullSite;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
@@ -45,9 +46,7 @@ final class PageTsConfigFactoryPageLayoutConditionTest extends FunctionalTestCas
         $this->setUpBackendUser(1);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function treePageLayoutConditionMetForBackendLayoutOnRootPage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/PageTsConfigFactoryPageLayoutCondition/backendLayoutOnRootPage.csv');
@@ -59,9 +58,7 @@ final class PageTsConfigFactoryPageLayoutConditionTest extends FunctionalTestCas
         self::assertStringContainsString('Default Layout', $pageTsConfigArray['layout'] ?? '');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function treePageLayoutConditionNotMetForBackendLayoutNextLevelOnRootPage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/PageTsConfigFactoryPageLayoutCondition/backendLayoutNextLevelOnRootPage.csv');
@@ -73,9 +70,7 @@ final class PageTsConfigFactoryPageLayoutConditionTest extends FunctionalTestCas
         self::assertStringNotContainsString('Default Layout', $pageTsConfigArray['layout'] ?? '');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function treePageLayoutConditionMetForBackendLayoutNextLevelInheritedOnSubpageLevel1(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/PageTsConfigFactoryPageLayoutCondition/backendLayoutAndNextLevelOnRootPage.csv');
@@ -87,9 +82,7 @@ final class PageTsConfigFactoryPageLayoutConditionTest extends FunctionalTestCas
         self::assertStringContainsString('Inherited Layout', $pageTsConfigArray['layout'] ?? '');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function treePageLayoutConditionMetForBackendLayoutNextLevelInheritedOnSubpageLevel2(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/PageTsConfigFactoryPageLayoutCondition/backendLayoutAndNextLevelOnRootPageSubOverride1.csv');
@@ -101,9 +94,7 @@ final class PageTsConfigFactoryPageLayoutConditionTest extends FunctionalTestCas
         self::assertStringContainsString('Inherited Layout', $pageTsConfigArray['layout'] ?? '');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function treePageLayoutConditionMetForBackendLayoutOnSubpageLevel3(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/PageTsConfigFactoryPageLayoutCondition/backendLayoutAndNextLevelOnRootPageSubOverride2.csv');
@@ -115,9 +106,7 @@ final class PageTsConfigFactoryPageLayoutConditionTest extends FunctionalTestCas
         self::assertStringContainsString('Extra Layout', $pageTsConfigArray['layout'] ?? '');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function treePageLayoutConditionMetForBackendLayoutNextLevelOverrideOnSubpageLevel3(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/PageTsConfigFactoryPageLayoutCondition/backendLayoutAndNextLevelOnRootPageSubOverride3.csv');
diff --git a/typo3/sysext/core/Tests/Functional/TypoScript/PageTsConfigFactoryTest.php b/typo3/sysext/core/Tests/Functional/TypoScript/PageTsConfigFactoryTest.php
index 9b2569b1bcaa..cde737cea3a2 100644
--- a/typo3/sysext/core/Tests/Functional/TypoScript/PageTsConfigFactoryTest.php
+++ b/typo3/sysext/core/Tests/Functional/TypoScript/PageTsConfigFactoryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\TypoScript;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Site\Entity\NullSite;
 use TYPO3\CMS\Core\Site\Entity\Site;
 use TYPO3\CMS\Core\Site\Entity\SiteSettings;
@@ -33,9 +34,7 @@ final class PageTsConfigFactoryTest extends FunctionalTestCase
         'typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_typoscript_pagetsconfigfactory',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTsConfigLoadsDefaultsFromGlobals(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] = 'loadedFromGlobals = loadedFromGlobals';
@@ -44,9 +43,7 @@ final class PageTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromGlobals', $pageTsConfig->getPageTsConfigArray()['loadedFromGlobals']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTsConfigLoadsSingleFileWithOldImportSyntaxFromGlobals(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] = '<INCLUDE_TYPOSCRIPT: source="FILE:EXT:test_typoscript_pagetsconfigfactory/Configuration/TsConfig/tsconfig-includes.tsconfig">';
@@ -56,9 +53,7 @@ final class PageTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromTsconfigIncludesWithTsconfigSuffix', $pageTsConfig->getPageTsConfigArray()['loadedFromTsconfigIncludesWithTsconfigSuffix']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTsConfigLoadsFromPagesTsconfigTestExtensionConfigurationFile(): void
     {
         $subject = $this->get(PageTsConfigFactory::class);
@@ -66,9 +61,7 @@ final class PageTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromTestExtensionConfigurationPageTsConfig', $pageTsConfig->getPageTsConfigArray()['loadedFromTestExtensionConfigurationPageTsConfig']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTsConfigLoadsFromPageRecordTsconfigField(): void
     {
         $rootLine = [
@@ -82,9 +75,7 @@ final class PageTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromTsConfigField', $pageTsConfig->getPageTsConfigArray()['loadedFromTsConfigField']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTsConfigLoadsFromWildcardAtImportWithTsconfigSuffix(): void
     {
         $rootLine = [
@@ -98,9 +89,7 @@ final class PageTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromTsconfigIncludesWithTsconfigSuffix', $pageTsConfig->getPageTsConfigArray()['loadedFromTsconfigIncludesWithTsconfigSuffix']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTsConfigLoadsFromWildcardAtImportWithTypoScriptSuffix(): void
     {
         $rootLine = [
@@ -114,9 +103,7 @@ final class PageTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromTsconfigIncludesWithTyposcriptSuffix', $pageTsConfig->getPageTsConfigArray()['loadedFromTsconfigIncludesWithTyposcriptSuffix']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTsConfigLoadsSingleFileWithOldImportSyntax(): void
     {
         $rootLine = [
@@ -131,9 +118,7 @@ final class PageTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromTsconfigIncludesWithTsconfigSuffix', $pageTsConfig->getPageTsConfigArray()['loadedFromTsconfigIncludesWithTsconfigSuffix']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTsConfigLoadsFromPageRecordTsconfigFieldOverridesByLowerLevel(): void
     {
         $rootLine = [
@@ -154,9 +139,7 @@ final class PageTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromTsConfigField2Override', $pageTsConfig->getPageTsConfigArray()['loadedFromTsConfigField2']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTsConfigSubstitutesSettingsFromSite(): void
     {
         $rootLine = [
@@ -172,9 +155,7 @@ final class PageTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('aSiteSettingValue', $pageTsConfig->getPageTsConfigArray()['siteSetting']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTsConfigLoadsFromEvent(): void
     {
         $subject = $this->get(PageTsConfigFactory::class);
@@ -182,9 +163,7 @@ final class PageTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromEvent', $pageTsConfig->getPageTsConfigArray()['loadedFromEvent']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTsConfigLoadsFromLegacyEvent(): void
     {
         $subject = $this->get(PageTsConfigFactory::class);
@@ -192,9 +171,7 @@ final class PageTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromLegacyEvent', $pageTsConfig->getPageTsConfigArray()['loadedFromLegacyEvent']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTsConfigCanBeOverloadedWithUserTsConfig(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/pageTsConfigTestFixture.csv');
diff --git a/typo3/sysext/core/Tests/Functional/TypoScript/TypoScriptStringFactoryTest.php b/typo3/sysext/core/Tests/Functional/TypoScript/TypoScriptStringFactoryTest.php
index 194e810f9649..8c6c9a63c050 100644
--- a/typo3/sysext/core/Tests/Functional/TypoScript/TypoScriptStringFactoryTest.php
+++ b/typo3/sysext/core/Tests/Functional/TypoScript/TypoScriptStringFactoryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\TypoScript;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\EventDispatcher\NoopEventDispatcher;
 use TYPO3\CMS\Core\TypoScript\AST\AstBuilder;
 use TYPO3\CMS\Core\TypoScript\AST\Node\ChildNode;
@@ -28,9 +29,7 @@ final class TypoScriptStringFactoryTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseFromStringWithIncludesParsesImport(): void
     {
         $expected = new RootNode();
@@ -45,9 +44,7 @@ final class TypoScriptStringFactoryTest extends FunctionalTestCase
         self::assertEquals($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function parseFromStringParsesSimpleString(): void
     {
         $expected = new RootNode();
diff --git a/typo3/sysext/core/Tests/Functional/TypoScript/UserTsConfigFactoryTest.php b/typo3/sysext/core/Tests/Functional/TypoScript/UserTsConfigFactoryTest.php
index 0612b3d32f70..16b05c879d47 100644
--- a/typo3/sysext/core/Tests/Functional/TypoScript/UserTsConfigFactoryTest.php
+++ b/typo3/sysext/core/Tests/Functional/TypoScript/UserTsConfigFactoryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\TypoScript;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\TypoScript\UserTsConfigFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -29,9 +30,7 @@ final class UserTsConfigFactoryTest extends FunctionalTestCase
         'typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_typoscript_usertsconfigfactory',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function userTsConfigLoadsDefaultFromGlobals(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] = 'loadedFromGlobals = loadedFromGlobals';
@@ -42,9 +41,7 @@ final class UserTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromGlobals', $userTsConfig->getUserTsConfigArray()['loadedFromGlobals']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function userTsConfigLoadsSingleFileWithOldImportSyntaxFromGlobals(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] = '<INCLUDE_TYPOSCRIPT: source="FILE:EXT:test_typoscript_usertsconfigfactory/Configuration/TsConfig/tsconfig-includes.tsconfig">';
@@ -56,9 +53,7 @@ final class UserTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromTsconfigIncludesWithTsconfigSuffix', $userTsConfig->getUserTsConfigArray()['loadedFromTsconfigIncludesWithTsconfigSuffix']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function userTsConfigLoadsDefaultFromBackendUserTsConfigField(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/userTsConfigTestFixture.csv');
@@ -68,9 +63,7 @@ final class UserTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromUser', $userTsConfig->getUserTsConfigArray()['loadedFromUser']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function userTsConfigLoadsDefaultFromBackendUserGroupTsConfigField(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/userTsConfigTestFixture.csv');
@@ -80,9 +73,7 @@ final class UserTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromUserGroup', $userTsConfig->getUserTsConfigArray()['loadedFromUserGroup']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function userTsConfigLoadsDefaultFromBackendUserGroupTsConfigFieldAndGroupOverride(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/userTsConfigTestFixture.csv');
@@ -92,9 +83,7 @@ final class UserTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromUserGroupOverride', $userTsConfig->getUserTsConfigArray()['loadedFromUserGroup']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function userTsConfigLoadsFromWildcardAtImportWithTsconfigSuffix(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/userTsConfigTestFixture.csv');
@@ -104,9 +93,7 @@ final class UserTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('loadedFromTsconfigIncludesWithTsconfigSuffix', $userTsConfig->getUserTsConfigArray()['loadedFromTsconfigIncludesWithTsconfigSuffix']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function userTsConfigLoadsFromWildcardAtImportWithTypoScriptSuffix(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/userTsConfigTestFixture.csv');
diff --git a/typo3/sysext/core/Tests/Functional/Utility/ExtensionManagementUtility/ExtensionManagementUtilityTcaOverrideRequireTest.php b/typo3/sysext/core/Tests/Functional/Utility/ExtensionManagementUtility/ExtensionManagementUtilityTcaOverrideRequireTest.php
index 5c303f58f368..ec9616a1bced 100644
--- a/typo3/sysext/core/Tests/Functional/Utility/ExtensionManagementUtility/ExtensionManagementUtilityTcaOverrideRequireTest.php
+++ b/typo3/sysext/core/Tests/Functional/Utility/ExtensionManagementUtility/ExtensionManagementUtilityTcaOverrideRequireTest.php
@@ -15,6 +15,7 @@
 
 namespace TYPO3\CMS\Core\Tests\Functional\Utility\ExtensionManagementUtility;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class ExtensionManagementUtilityTcaOverrideRequireTest extends FunctionalTestCase
@@ -24,10 +25,7 @@ final class ExtensionManagementUtilityTcaOverrideRequireTest extends FunctionalT
         'typo3/sysext/core/Tests/Functional/Utility/ExtensionManagementUtility/Fixtures/Extensions/test_tcaoverride_b',
     ];
 
-    /**
-     * @test
-     * Regression test for https://forge.typo3.org/issues/96929
-     */
+    #[Test]
     public function extensionManagementUtilityBuildBaseTcaFromSingleFiles(): void
     {
         // This is a dummy assertion to test a general behaviour. If this test fails, this means that
diff --git a/typo3/sysext/core/Tests/Functional/Utility/ExtensionManagementUtility/ExtensionManagementUtilityTcaRequireTest.php b/typo3/sysext/core/Tests/Functional/Utility/ExtensionManagementUtility/ExtensionManagementUtilityTcaRequireTest.php
index 3982a9e7531d..f0afa2aa1a3c 100644
--- a/typo3/sysext/core/Tests/Functional/Utility/ExtensionManagementUtility/ExtensionManagementUtilityTcaRequireTest.php
+++ b/typo3/sysext/core/Tests/Functional/Utility/ExtensionManagementUtility/ExtensionManagementUtilityTcaRequireTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Utility\ExtensionManagementUtility;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class ExtensionManagementUtilityTcaRequireTest extends FunctionalTestCase
@@ -26,10 +27,7 @@ final class ExtensionManagementUtilityTcaRequireTest extends FunctionalTestCase
         'typo3/sysext/core/Tests/Functional/Utility/ExtensionManagementUtility/Fixtures/Extensions/test_tca_b',
     ];
 
-    /**
-     * @test
-     * Regression test for https://forge.typo3.org/issues/96929
-     */
+    #[Test]
     public function extensionManagementUtilityBuildBaseTcaFromSingleFiles(): void
     {
         // This is a dummy assertion to test a general behaviour. If this test fails, this means that
diff --git a/typo3/sysext/core/Tests/Functional/Utility/File/ExtendedFileUtilityTest.php b/typo3/sysext/core/Tests/Functional/Utility/File/ExtendedFileUtilityTest.php
index 1021c0472b8e..dba6efe0d743 100644
--- a/typo3/sysext/core/Tests/Functional/Utility/File/ExtendedFileUtilityTest.php
+++ b/typo3/sysext/core/Tests/Functional/Utility/File/ExtendedFileUtilityTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Utility\File;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Resource\StorageRepository;
 use TYPO3\CMS\Core\Utility\File\ExtendedFileUtility;
@@ -37,9 +38,7 @@ final class ExtendedFileUtilityTest extends FunctionalTestCase
         $GLOBALS['LANG'] = GeneralUtility::makeInstance(LanguageServiceFactory::class)->create('default');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function folderHasFilesInUseReturnsTrueIfItHasFilesInUse(): void
     {
         $storageRepository = $this->get(StorageRepository::class);
@@ -52,9 +51,7 @@ final class ExtendedFileUtilityTest extends FunctionalTestCase
         self::assertTrue($result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function folderHasFilesInUseReturnsFalseIfItHasNoFilesInUse(): void
     {
         $storageRepository = $this->get(StorageRepository::class);
@@ -67,9 +64,7 @@ final class ExtendedFileUtilityTest extends FunctionalTestCase
         self::assertFalse($result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function folderHasFilesInUseReturnsFalseIfItHasNoFiles(): void
     {
         $storageRepository = $this->get(StorageRepository::class);
diff --git a/typo3/sysext/core/Tests/Functional/Utility/RootlineUtilityTest.php b/typo3/sysext/core/Tests/Functional/Utility/RootlineUtilityTest.php
index 2b3d03167401..b2e593ada541 100644
--- a/typo3/sysext/core/Tests/Functional/Utility/RootlineUtilityTest.php
+++ b/typo3/sysext/core/Tests/Functional/Utility/RootlineUtilityTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\Utility;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\WorkspaceAspect;
 use TYPO3\CMS\Core\Core\Bootstrap;
@@ -65,9 +66,7 @@ final class RootlineUtilityTest extends FunctionalTestCase
         });
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getForRootPageOnlyReturnsRootPageInformation(): void
     {
         $rootPageUid = 1000;
@@ -79,9 +78,7 @@ final class RootlineUtilityTest extends FunctionalTestCase
         self::assertSame($rootPageUid, (int)$result[0]['uid']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getForRootPageAndWithMissingTableColumnsTcaReturnsEmptyArray(): void
     {
         $rootPageUid = 1000;
@@ -94,9 +91,7 @@ final class RootlineUtilityTest extends FunctionalTestCase
         self::assertSame($rootPageUid, (int)$result[0]['uid']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getForRootPageAndWithNonArrayTableColumnsTcaReturnsEmptyArray(): void
     {
         $rootPageUid = 1000;
@@ -109,9 +104,7 @@ final class RootlineUtilityTest extends FunctionalTestCase
         self::assertSame($rootPageUid, (int)$result[0]['uid']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveLivePagesAndSkipWorkspacedVersions(): void
     {
         $context = GeneralUtility::makeInstance(Context::class);
@@ -148,9 +141,7 @@ final class RootlineUtilityTest extends FunctionalTestCase
         self::assertSame($expected, $this->filterExpectedValues($result, ['pid', 'uid', 't3ver_oid', 't3ver_wsid', 't3ver_state', 'title']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveWorkspaceOverlaysOfNewPageInWorkspace(): void
     {
         $context = GeneralUtility::makeInstance(Context::class);
@@ -180,9 +171,7 @@ final class RootlineUtilityTest extends FunctionalTestCase
         self::assertSame($expected, $this->filterExpectedValues($result, ['pid', 'uid', 't3ver_oid', 't3ver_wsid', 't3ver_state', 'title', '_ORIG_uid', '_ORIG_pid']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveLiveRootLineForMovedPage(): void
     {
         $context = GeneralUtility::makeInstance(Context::class);
@@ -227,9 +216,7 @@ final class RootlineUtilityTest extends FunctionalTestCase
         self::assertSame($expected, $this->filterExpectedValues($result, ['pid', 'uid', 't3ver_oid', 't3ver_wsid', 't3ver_state', 'title', '_ORIG_uid', '_ORIG_pid']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveWorkspaceOverlaysOfMovedPage(): void
     {
         $context = GeneralUtility::makeInstance(Context::class);
@@ -282,9 +269,7 @@ final class RootlineUtilityTest extends FunctionalTestCase
         self::assertSame($expected, $this->filterExpectedValues($result, ['pid', 'uid', 't3ver_oid', 't3ver_wsid', 't3ver_state', 'title', '_ORIG_uid', '_ORIG_pid']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function rootlineFailsForDeletedParentPageInWorkspace(): void
     {
         $this->expectException(PageNotFoundException::class);
diff --git a/typo3/sysext/core/Tests/Functional/ViewHelpers/IconForRecordViewHelperTest.php b/typo3/sysext/core/Tests/Functional/ViewHelpers/IconForRecordViewHelperTest.php
index 6692c2db16e3..322d8768b1c6 100644
--- a/typo3/sysext/core/Tests/Functional/ViewHelpers/IconForRecordViewHelperTest.php
+++ b/typo3/sysext/core/Tests/Functional/ViewHelpers/IconForRecordViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\ViewHelpers;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -28,9 +29,7 @@ final class IconForRecordViewHelperTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderRendersIconCallingIconFactoryAccordingToGivenArguments(): void
     {
         $iconMock = $this->createMock(Icon::class);
diff --git a/typo3/sysext/core/Tests/Functional/ViewHelpers/IconViewHelperTest.php b/typo3/sysext/core/Tests/Functional/ViewHelpers/IconViewHelperTest.php
index 3261d3ccccd7..9b5617c98569 100644
--- a/typo3/sysext/core/Tests/Functional/ViewHelpers/IconViewHelperTest.php
+++ b/typo3/sysext/core/Tests/Functional/ViewHelpers/IconViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\Functional\ViewHelpers;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Type\Icon\IconState;
@@ -29,9 +30,7 @@ final class IconViewHelperTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCallsIconFactoryWithDefaultSizeAndDefaultStateAndReturnsResult(): void
     {
         $iconFactoryMock = $this->createMock(IconFactory::class);
@@ -47,9 +46,7 @@ final class IconViewHelperTest extends FunctionalTestCase
         self::assertSame('htmlFoo', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCallsIconFactoryWithGivenSizeAndReturnsResult(): void
     {
         $iconFactoryMock = $this->createMock(IconFactory::class);
@@ -65,9 +62,7 @@ final class IconViewHelperTest extends FunctionalTestCase
         self::assertSame('htmlFoo', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCallsIconFactoryWithGivenStateAndReturnsResult(): void
     {
         $iconFactoryMock = $this->createMock(IconFactory::class);
@@ -83,9 +78,7 @@ final class IconViewHelperTest extends FunctionalTestCase
         self::assertSame('htmlFoo', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCallsIconFactoryWithGivenOverlayAndReturnsResult(): void
     {
         $iconFactoryMock = $this->createMock(IconFactory::class);
@@ -101,9 +94,7 @@ final class IconViewHelperTest extends FunctionalTestCase
         self::assertSame('htmlFoo', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function titleIsPassedFromViewhelperToIconClass(): void
     {
         $iconFactoryMock = $this->createMock(IconFactory::class);
diff --git a/typo3/sysext/core/Tests/FunctionalDeprecated/Domain/Repository/PageRepositoryTest.php b/typo3/sysext/core/Tests/FunctionalDeprecated/Domain/Repository/PageRepositoryTest.php
index 37db334c7423..eb483037103e 100644
--- a/typo3/sysext/core/Tests/FunctionalDeprecated/Domain/Repository/PageRepositoryTest.php
+++ b/typo3/sysext/core/Tests/FunctionalDeprecated/Domain/Repository/PageRepositoryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\FunctionalDeprecated\Domain\Repository;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\DateTimeAspect;
 use TYPO3\CMS\Core\Context\WorkspaceAspect;
@@ -33,9 +34,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/Fixtures/pages.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function initSetsPublicPropertyCorrectlyForWorkspacePreview(): void
     {
         $workspaceId = 2;
@@ -56,9 +55,7 @@ final class PageRepositoryTest extends FunctionalTestCase
         self::assertSame($expectedSQL, $subject->where_hid_del);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function initSetsEnableFieldsCorrectlyForLive(): void
     {
         $subject = new PageRepository(new Context([
diff --git a/typo3/sysext/core/Tests/FunctionalDeprecated/TypoScript/PageTsConfigFactoryTest.php b/typo3/sysext/core/Tests/FunctionalDeprecated/TypoScript/PageTsConfigFactoryTest.php
index fa014a7e86d9..c60a90a2898f 100644
--- a/typo3/sysext/core/Tests/FunctionalDeprecated/TypoScript/PageTsConfigFactoryTest.php
+++ b/typo3/sysext/core/Tests/FunctionalDeprecated/TypoScript/PageTsConfigFactoryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\FunctionalDeprecated\TypoScript;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Http\NormalizedParams;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Site\Entity\NullSite;
@@ -27,9 +28,7 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class PageTsConfigFactoryTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTsConfigMatchesRequestHttpsCondition(): void
     {
         $request = (new ServerRequest('https://www.example.com/', null, 'php://input', [], ['HTTPS' => 'ON']));
@@ -49,9 +48,7 @@ final class PageTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('on', $pageTsConfig->getPageTsConfigArray()['isHttps']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTsConfigMatchesRequestHttpsElseCondition(): void
     {
         $request = new ServerRequest('http://www.example.com/');
@@ -71,9 +68,7 @@ final class PageTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('off', $pageTsConfig->getPageTsConfigArray()['isHttps']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTsConfigMatchesRequestHttpsConditionUsingSiteConstant(): void
     {
         $request = (new ServerRequest('https://www.example.com/', null, 'php://input', [], ['HTTPS' => 'ON']));
diff --git a/typo3/sysext/core/Tests/FunctionalDeprecated/TypoScript/Parser/TypoScriptParserTest.php b/typo3/sysext/core/Tests/FunctionalDeprecated/TypoScript/Parser/TypoScriptParserTest.php
index 27a47a449be2..3aed7108e9c0 100644
--- a/typo3/sysext/core/Tests/FunctionalDeprecated/TypoScript/Parser/TypoScriptParserTest.php
+++ b/typo3/sysext/core/Tests/FunctionalDeprecated/TypoScript/Parser/TypoScriptParserTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\FunctionalDeprecated\TypoScript\Parser;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -27,9 +28,8 @@ final class TypoScriptParserTest extends FunctionalTestCase
     /**
      * This tests triggers an error if the serialize(unserialize())) call
      * within TypoScriptParser is removed. See forge issue #76919
-     *
-     * @test
      */
+    #[Test]
     public function hasFlakyReferences(): void
     {
         $typoScript = implode(LF, [
diff --git a/typo3/sysext/core/Tests/FunctionalDeprecated/TypoScript/UserTsConfigFactoryTest.php b/typo3/sysext/core/Tests/FunctionalDeprecated/TypoScript/UserTsConfigFactoryTest.php
index 547bb18d0f0f..7f292ec7fceb 100644
--- a/typo3/sysext/core/Tests/FunctionalDeprecated/TypoScript/UserTsConfigFactoryTest.php
+++ b/typo3/sysext/core/Tests/FunctionalDeprecated/TypoScript/UserTsConfigFactoryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Tests\FunctionalDeprecated\TypoScript;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Http\NormalizedParams;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -26,9 +27,7 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class UserTsConfigFactoryTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function userTsConfigMatchesRequestHttpsCondition(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/userTsConfigTestFixture.csv');
@@ -45,9 +44,7 @@ final class UserTsConfigFactoryTest extends FunctionalTestCase
         self::assertSame('on', $userTsConfig->getUserTsConfigArray()['isHttps']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function userTsConfigMatchesRequestHttpsElseCondition(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/userTsConfigTestFixture.csv');
diff --git a/typo3/sysext/dashboard/Tests/Functional/WidgetRegistryTest.php b/typo3/sysext/dashboard/Tests/Functional/WidgetRegistryTest.php
index 45e30a5ce168..24afad223f31 100644
--- a/typo3/sysext/dashboard/Tests/Functional/WidgetRegistryTest.php
+++ b/typo3/sysext/dashboard/Tests/Functional/WidgetRegistryTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Dashboard\Tests\Functional;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Dashboard\WidgetRegistry;
 use TYPO3\CMS\Dashboard\Widgets\WidgetConfiguration;
@@ -108,18 +110,14 @@ final class WidgetRegistryTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function initiallyZeroWidgetAreRegistered(): void
     {
         $subject = new WidgetRegistry($this->getContainer());
         self::assertCount(0, $subject->getAllWidgets());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getAllWidgetsReturnsAllRegisteredWidgets(): void
     {
         $this->registerWidgets();
@@ -156,10 +154,8 @@ final class WidgetRegistryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider expectedAmountOfWidgetsForUserDataProvider
-     */
+    #[DataProvider('expectedAmountOfWidgetsForUserDataProvider')]
+    #[Test]
     public function returnsExpectedAmountOfWidgetsForUser(
         int $userId,
         int $countGroup1,
@@ -174,9 +170,7 @@ final class WidgetRegistryTest extends FunctionalTestCase
         self::assertCount($countTotal, $this->subject->getAvailableWidgets());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addWidgetsInItemsProcFunc(): void
     {
         $this->registerWidgets();
diff --git a/typo3/sysext/extbase/Tests/Functional/Configuration/BackendConfigurationManagerTest.php b/typo3/sysext/extbase/Tests/Functional/Configuration/BackendConfigurationManagerTest.php
index 74597fc110de..a84e201f439e 100644
--- a/typo3/sysext/extbase/Tests/Functional/Configuration/BackendConfigurationManagerTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Configuration/BackendConfigurationManagerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Configuration;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -26,9 +27,7 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class BackendConfigurationManagerTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function setConfigurationSetsExtensionAndPluginName(): void
     {
         $subject = $this->get(BackendConfigurationManager::class);
@@ -40,9 +39,7 @@ final class BackendConfigurationManagerTest extends FunctionalTestCase
         self::assertEquals('SomePluginName', (new \ReflectionProperty($subject, 'pluginName'))->getValue($subject));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setConfigurationConvertsTypoScriptArrayToPlainArray(): void
     {
         $configuration = [
@@ -60,9 +57,7 @@ final class BackendConfigurationManagerTest extends FunctionalTestCase
         self::assertEquals($expectedResult, (new \ReflectionProperty($subject, 'configuration'))->getValue($subject));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getConfigurationRecursivelyMergesCurrentExtensionConfigurationWithFrameworkConfiguration(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/BackendConfigurationManagerTestTypoScript.csv');
@@ -99,9 +94,7 @@ final class BackendConfigurationManagerTest extends FunctionalTestCase
         self::assertEquals($expectedResult, $subject->getConfiguration('CurrentExtensionName'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getConfigurationRecursivelyMergesCurrentPluginConfigurationWithFrameworkConfiguration(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/BackendConfigurationManagerTestTypoScript.csv');
@@ -138,9 +131,7 @@ final class BackendConfigurationManagerTest extends FunctionalTestCase
         self::assertEquals($expectedResult, $subject->getConfiguration('CurrentExtensionName', 'CurrentPluginName'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getCurrentPageIdReturnsPageIdFromGet(): void
     {
         $request = (new ServerRequest())->withQueryParams(['id' => 123]);
@@ -150,9 +141,7 @@ final class BackendConfigurationManagerTest extends FunctionalTestCase
         self::assertEquals(123, $actualResult);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getCurrentPageIdReturnsPageIdFromPost(): void
     {
         $request = (new ServerRequest())->withQueryParams(['id' => 123])->withParsedBody(['id' => 321]);
@@ -162,9 +151,7 @@ final class BackendConfigurationManagerTest extends FunctionalTestCase
         self::assertEquals(321, $actualResult);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getCurrentPageIdReturnsPidFromFirstRootTemplateIfIdIsNotSetAndNoRootPageWasFound(): void
     {
         (new ConnectionPool())->getConnectionForTable('sys_template')->insert(
@@ -182,9 +169,7 @@ final class BackendConfigurationManagerTest extends FunctionalTestCase
         self::assertEquals(123, $actualResult);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getCurrentPageIdReturnsUidFromFirstRootPageIfIdIsNotSet(): void
     {
         (new ConnectionPool())->getConnectionForTable('pages')->insert(
@@ -201,9 +186,7 @@ final class BackendConfigurationManagerTest extends FunctionalTestCase
         self::assertEquals(1, $actualResult);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getCurrentPageIdReturnsDefaultStoragePidIfIdIsNotSetNoRootTemplateAndRootPageWasFound(): void
     {
         $subject = $this->get(BackendConfigurationManager::class);
@@ -212,9 +195,7 @@ final class BackendConfigurationManagerTest extends FunctionalTestCase
         self::assertEquals(0, $actualResult);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getRecursiveStoragePidsReturnsListOfPages(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/BackendConfigurationManagerRecursivePids.csv');
@@ -226,18 +207,14 @@ final class BackendConfigurationManagerTest extends FunctionalTestCase
         self::assertEquals([1, 2, 4, 5, 3, 6, 7], $actualResult);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getContentObjectReturnsInstanceOfContentObjectRenderer(): void
     {
         $subject = $this->get(BackendConfigurationManager::class);
         self::assertInstanceOf(ContentObjectRenderer::class, $subject->getContentObject());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getContentObjectTheCurrentContentObject(): void
     {
         $subject = $this->get(BackendConfigurationManager::class);
diff --git a/typo3/sysext/extbase/Tests/Functional/Configuration/FrontendConfigurationManagerTest.php b/typo3/sysext/extbase/Tests/Functional/Configuration/FrontendConfigurationManagerTest.php
index f1f30bba8ba9..f077fce68a93 100644
--- a/typo3/sysext/extbase/Tests/Functional/Configuration/FrontendConfigurationManagerTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Configuration/FrontendConfigurationManagerTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Configuration;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Core\EventDispatcher\ListenerProvider;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -29,9 +31,7 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class FrontendConfigurationManagerTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function beforeFlexFormConfigurationOverrideEventIsDispatched(): void
     {
         $typoScript = [
@@ -342,10 +342,8 @@ final class FrontendConfigurationManagerTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider overrideConfigurationFromFlexFormSettingsDataProvider
-     */
+    #[DataProvider('overrideConfigurationFromFlexFormSettingsDataProvider')]
+    #[Test]
     public function overrideConfigurationFromFlexFormIgnoresConfiguredEmptyFlexFormSettings(
         string $flexFormConfiguration,
         array $frameworkConfiguration,
diff --git a/typo3/sysext/extbase/Tests/Functional/Mvc/Controller/ActionControllerArgumentTest.php b/typo3/sysext/extbase/Tests/Functional/Mvc/Controller/ActionControllerArgumentTest.php
index 487c4397e7d0..d9545a347c98 100644
--- a/typo3/sysext/extbase/Tests/Functional/Mvc/Controller/ActionControllerArgumentTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Mvc/Controller/ActionControllerArgumentTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Mvc\Controller;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\ResponseInterface;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -69,10 +71,10 @@ final class ActionControllerArgumentTest extends FunctionalTestCase
     }
 
     /**
-     * @test
-     * @dataProvider validationErrorReturnsToForwardedPreviousActionDataProvider
      * @todo: It might be better if these tests would executeFrontendSubRequest() to setup less stuff on their own?!
      */
+    #[DataProvider('validationErrorReturnsToForwardedPreviousActionDataProvider')]
+    #[Test]
     public function validationErrorReturnsToForwardedPreviousAction(string $forwardTargetAction, array $forwardTargetArguments, string $validateAction, array $expectations): void
     {
         $inputRequest = $this->buildRequest('forward');
diff --git a/typo3/sysext/extbase/Tests/Functional/Mvc/Controller/ActionControllerTest.php b/typo3/sysext/extbase/Tests/Functional/Mvc/Controller/ActionControllerTest.php
index 3f92fbb27449..95fda7ae4e10 100644
--- a/typo3/sysext/extbase/Tests/Functional/Mvc/Controller/ActionControllerTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Mvc/Controller/ActionControllerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Mvc\Controller;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Page\PageRenderer;
 use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
@@ -42,9 +43,7 @@ final class ActionControllerTest extends FunctionalTestCase
         'typo3/sysext/extbase/Tests/Functional/Mvc/Controller/Fixture/Extension/action_controller_test',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function initializeActionMethodArgumentsRegistersArgumentsFoundInTheSignatureOfTheCurrentActionMethod(): void
     {
         $subject = $this->get(TestController::class);
@@ -65,9 +64,7 @@ final class ActionControllerTest extends FunctionalTestCase
         self::assertNull($subject->arguments['objectArgument']->getDefaultValue());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function initializeActionMethodArgumentsRegistersOptionalArgumentsAsSuch(): void
     {
         $subject = $this->get(TestController::class);
@@ -88,9 +85,7 @@ final class ActionControllerTest extends FunctionalTestCase
         self::assertSame('foo', $subject->arguments['arg3']->getDefaultValue());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function initializeActionMethodArgumentsThrowsExceptionIfDataTypeWasNotSpecified(): void
     {
         $this->expectException(InvalidArgumentTypeException::class);
@@ -101,9 +96,7 @@ final class ActionControllerTest extends FunctionalTestCase
         $subject->initializeActionMethodArguments();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function processRequestThrowsAnExceptionIfTheActionDefinedInTheRequestDoesNotExist(): void
     {
         $this->expectException(NoSuchActionException::class);
@@ -117,9 +110,7 @@ final class ActionControllerTest extends FunctionalTestCase
         $subject->processRequest($request);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function processRequestSetsActionMethodName(): void
     {
         $serverRequest = (new ServerRequest())->withAttribute('extbase', new ExtbaseRequestParameters());
@@ -132,9 +123,7 @@ final class ActionControllerTest extends FunctionalTestCase
         self::assertSame('quxAction', $subject->actionMethodName);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function customValidatorsAreProperlyResolved(): void
     {
         $serverRequest = (new ServerRequest())->withAttribute('extbase', new ExtbaseRequestParameters());
@@ -158,9 +147,7 @@ final class ActionControllerTest extends FunctionalTestCase
         self::assertInstanceOf(CustomValidator::class, $validators->current());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function extbaseValidatorsAreProperlyResolved(): void
     {
         $serverRequest = (new ServerRequest())->withAttribute('extbase', new ExtbaseRequestParameters());
@@ -185,9 +172,7 @@ final class ActionControllerTest extends FunctionalTestCase
         self::assertInstanceOf(NotEmptyValidator::class, $validators->current());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveViewRespectsDefaultViewObjectName(): void
     {
         $serverRequest = (new ServerRequest())->withAttribute('extbase', new ExtbaseRequestParameters());
@@ -209,9 +194,7 @@ final class ActionControllerTest extends FunctionalTestCase
         self::assertInstanceOf(JsonView::class, $view);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setViewConfigurationConfiguresViewWithArray(): void
     {
         $configurationManagerMock = $this->createMock(ConfigurationManager::class);
@@ -235,9 +218,7 @@ final class ActionControllerTest extends FunctionalTestCase
         $subject->setViewConfiguration($viewMock);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setViewConfigurationDoesNotCallSettersWithEmptyArray(): void
     {
         $configurationManagerMock = $this->createMock(ConfigurationManager::class);
@@ -261,9 +242,7 @@ final class ActionControllerTest extends FunctionalTestCase
         $subject->setViewConfiguration($viewMock);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderAssetsForRequestAssignsHeaderDataFromViewIntoPageRenderer(): void
     {
         $viewMock = $this->createMock(FluidTemplateView::class);
@@ -283,9 +262,7 @@ final class ActionControllerTest extends FunctionalTestCase
         $subject->renderAssetsForRequest($request);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderAssetsForRequestAssignsFooterDataFromViewIntoPageRenderer(): void
     {
         $viewMock = $this->createMock(FluidTemplateView::class);
@@ -305,9 +282,7 @@ final class ActionControllerTest extends FunctionalTestCase
         $subject->renderAssetsForRequest($request);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addFlashMessageAddsFlashMessageToFlashMessageQueue(): void
     {
         $serverRequest = (new ServerRequest())->withAttribute('extbase', new ExtbaseRequestParameters());
diff --git a/typo3/sysext/extbase/Tests/Functional/Mvc/Controller/ControllerArgumentsMappingTest.php b/typo3/sysext/extbase/Tests/Functional/Mvc/Controller/ControllerArgumentsMappingTest.php
index 719222b8864e..fafb209f6c8c 100644
--- a/typo3/sysext/extbase/Tests/Functional/Mvc/Controller/ControllerArgumentsMappingTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Mvc/Controller/ControllerArgumentsMappingTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Mvc\Controller;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\ResponseInterface;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\LanguageAspect;
@@ -32,7 +34,7 @@ use TYPO3Tests\BlogExample\Controller\BlogController;
 final class ControllerArgumentsMappingTest extends FunctionalTestCase
 {
     /**
-     * @var \TYPO3\CMS\Extbase\Mvc\Request
+     * @var Request
      */
     protected $request;
 
@@ -89,10 +91,8 @@ final class ControllerArgumentsMappingTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider actionGetsBlogFromUidArgumentDataProvider
-     */
+    #[DataProvider('actionGetsBlogFromUidArgumentDataProvider')]
+    #[Test]
     public function actionGetsBlogFromUidArgument(int $language, int $blogUid, string $expectedTitle): void
     {
         $context = GeneralUtility::makeInstance(Context::class);
diff --git a/typo3/sysext/extbase/Tests/Functional/Mvc/Validation/ActionControllerValidationTest.php b/typo3/sysext/extbase/Tests/Functional/Mvc/Validation/ActionControllerValidationTest.php
index c04992a604ad..fc1672e6b00b 100644
--- a/typo3/sysext/extbase/Tests/Functional/Mvc/Validation/ActionControllerValidationTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Mvc/Validation/ActionControllerValidationTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Mvc\Validation;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\Response;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -63,10 +65,8 @@ final class ActionControllerValidationTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider forwardedActionValidatesPreviouslyIgnoredArgumentDataProvider
-     */
+    #[DataProvider('forwardedActionValidatesPreviouslyIgnoredArgumentDataProvider')]
+    #[Test]
     public function forwardedActionValidatesPreviouslyIgnoredArgument(array $blogPostArgument, array $trustedProperties, array $expectedErrorCodes): void
     {
         $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->create('default');
@@ -113,9 +113,7 @@ final class ActionControllerValidationTest extends FunctionalTestCase
         self::assertEquals('testFormAction', $response->getBody()->getContents());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validationResultsAreProvidedForTheSameObjectInDifferentArguments(): void
     {
         $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->create('default');
@@ -176,9 +174,7 @@ final class ActionControllerValidationTest extends FunctionalTestCase
         self::assertEquals('testFormAction', $response->getBody()->getContents());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function argumentsOfOriginalRequestRemainOnValidationErrors(): void
     {
         $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->create('default');
diff --git a/typo3/sysext/extbase/Tests/Functional/Mvc/Web/RequestBuilderTest.php b/typo3/sysext/extbase/Tests/Functional/Mvc/Web/RequestBuilderTest.php
index 7ea6353d9bfe..d8cdec1e3bcf 100644
--- a/typo3/sysext/extbase/Tests/Functional/Mvc/Web/RequestBuilderTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Mvc/Web/RequestBuilderTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Mvc\Web;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\ServerRequestInterface;
 use TYPO3\CMS\Backend\Module\ExtbaseModule;
 use TYPO3\CMS\Backend\Routing\Route;
@@ -68,9 +69,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function buildBuildsARequestInterfaceObject(): void
     {
         $extensionName = 'blog_example';
@@ -101,9 +100,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         self::assertSame('html', $request->getFormat());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function loadDefaultValuesOverridesFormatIfConfigured(): void
     {
         $extensionName = 'blog_example';
@@ -135,9 +132,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         self::assertSame('json', $request->getFormat());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function buildOverridesFormatIfSetInGetParameters(): void
     {
         $extensionName = 'blog_example';
@@ -169,9 +164,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         self::assertSame('json', $request->getFormat());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function loadDefaultValuesThrowsExceptionIfExtensionNameIsNotProperlyConfigured(): void
     {
         $this->expectException(Exception::class);
@@ -183,9 +176,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         $requestBuilder->build($mainRequest);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function loadDefaultValuesThrowsExceptionIfPluginNameIsNotProperlyConfigured(): void
     {
         $this->expectException(Exception::class);
@@ -200,9 +191,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         $requestBuilder->build($mainRequest);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function untangleFilesArrayDetectsASingleUploadedFileInBackend(): void
     {
         $_FILES['dummy'] = [
@@ -257,9 +246,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         self::assertSame(98174, $request->getArgument('size'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function untangleFilesArrayDetectsMultipleUploadedFileInBackend(): void
     {
         $_FILES['dummy'] = [
@@ -339,9 +326,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         self::assertNotTrue(isset($argument['size']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveControllerClassNameThrowsInvalidControllerNameExceptionIfNonExistentControllerIsSetViaGetParameter(): void
     {
         $this->expectException(InvalidControllerNameException::class);
@@ -376,9 +361,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         $requestBuilder->build($mainRequest);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveControllerClassNameThrowsPageNotFoundException(): void
     {
         $this->expectException(PageNotFoundException::class);
@@ -412,9 +395,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         $requestBuilder->build($mainRequest);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveControllerClassNameThrowsAnExceptionIfTheDefaultControllerCannotBeDetermined(): void
     {
         $this->expectException(Exception::class);
@@ -436,9 +417,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         $requestBuilder->build($mainRequest);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveControllerClassNameReturnsDefaultControllerIfCallDefaultActionIfActionCantBeResolvedIsConfigured(): void
     {
         $extensionName = 'blog_example';
@@ -471,9 +450,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         self::assertSame('Blog', $request->getControllerName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveControllerClassNameReturnsControllerDefinedViaParametersIfControllerIsConfigured(): void
     {
         $extensionName = 'blog_example';
@@ -506,9 +483,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         self::assertSame('User', $request->getControllerName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveActionNameThrowsInvalidActionNameExceptionIfNonExistentActionIsSetViaGetParameter(): void
     {
         $this->expectException(InvalidActionNameException::class);
@@ -541,9 +516,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         $requestBuilder->build($mainRequest);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveActionNameThrowsPageNotFoundException(): void
     {
         $this->expectException(PageNotFoundException::class);
@@ -577,9 +550,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         $requestBuilder->build($mainRequest);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveActionNameReturnsDefaultActionIfCallDefaultActionIfActionCantBeResolvedIsConfigured(): void
     {
         $extensionName = 'blog_example';
@@ -612,9 +583,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         self::assertSame('list', $request->getControllerActionName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveActionNameReturnsActionDefinedViaParametersIfActionIsConfigured(): void
     {
         $extensionName = 'blog_example';
@@ -646,9 +615,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         self::assertSame('show', $request->getControllerActionName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveActionNameThrowsAnExceptionIfTheDefaultActionCannotBeDetermined(): void
     {
         $this->expectException(Exception::class);
@@ -680,9 +647,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         $requestBuilder->build($mainRequest);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveActionNameReturnsActionDefinedViaParametersOfServerRequest(): void
     {
         $mainRequest = $this->prepareServerRequest('https://example.com/');
@@ -717,9 +682,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         self::assertSame('show', $request->getControllerActionName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveActionNameReturnsActionDefinedViaPageArgumentOfServerRequest(): void
     {
         $pageArguments = new PageArguments(1, '0', ['tx_blog_example_blog' => ['action' => 'show']]);
@@ -758,9 +721,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         self::assertSame('show', $request->getControllerActionName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function resolveActionNameReturnsActionDefinedViaParsedBodyOfServerRequest(): void
     {
         $mainRequest = $this->prepareServerRequest('https://example.com/', 'POST');
@@ -795,9 +756,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         self::assertSame('show', $request->getControllerActionName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function silentlyIgnoreInvalidParameterAndUseDefaultAction(): void
     {
         $pageArguments = new PageArguments(1, '0', ['tx_blog_example_blog' => 'not_an_array']);
@@ -834,9 +793,7 @@ final class RequestBuilderTest extends FunctionalTestCase
         self::assertSame('list', $request->getControllerActionName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function controllerActionParametersAreAddedToRequest(): void
     {
         $mainRequest = $this->prepareServerRequest('https://example.com/typo3/module/blog-example/Blog/show');
diff --git a/typo3/sysext/extbase/Tests/Functional/Pagination/QueryResultPaginatorTest.php b/typo3/sysext/extbase/Tests/Functional/Pagination/QueryResultPaginatorTest.php
index d0a2be568def..5d24b60af08d 100644
--- a/typo3/sysext/extbase/Tests/Functional/Pagination/QueryResultPaginatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Pagination/QueryResultPaginatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Pagination;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Pagination\QueryResultPaginator;
@@ -43,18 +44,15 @@ final class QueryResultPaginatorTest extends FunctionalTestCase
 
     /**
      * A short integration test to check that the fixtures are as expected
-     *
-     * @test
      */
+    #[Test]
     public function integration(): void
     {
         $queryResult = $this->postRepository->findAll();
         self::assertCount(14, $queryResult);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function checkPaginatorWithDefaultConfiguration(): void
     {
         $paginator = new QueryResultPaginator($this->postRepository->findAll());
@@ -65,9 +63,7 @@ final class QueryResultPaginatorTest extends FunctionalTestCase
         self::assertCount(10, $paginator->getPaginatedItems());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function paginatorRespectsItemsPerPageConfiguration(): void
     {
         $paginator = new QueryResultPaginator(
@@ -82,9 +78,7 @@ final class QueryResultPaginatorTest extends FunctionalTestCase
         self::assertCount(3, $paginator->getPaginatedItems());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function paginatorRespectsItemsPerPageConfigurationAndCurrentPage(): void
     {
         $paginator = new QueryResultPaginator(
@@ -99,9 +93,7 @@ final class QueryResultPaginatorTest extends FunctionalTestCase
         self::assertCount(3, $paginator->getPaginatedItems());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function paginatorProperlyCalculatesLastPage(): void
     {
         $paginator = new QueryResultPaginator(
@@ -116,9 +108,7 @@ final class QueryResultPaginatorTest extends FunctionalTestCase
         self::assertCount(2, $paginator->getPaginatedItems());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function withCurrentPageNumberThrowsInvalidArgumentExceptionIfCurrentPageIsLowerThanOne(): void
     {
         $this->expectExceptionCode(1573047338);
@@ -131,9 +121,7 @@ final class QueryResultPaginatorTest extends FunctionalTestCase
         $paginator->withCurrentPageNumber(0);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function paginatorSetsCurrentPageToLastPageIfCurrentPageExceedsMaximum(): void
     {
         $paginator = new QueryResultPaginator(
@@ -147,9 +135,7 @@ final class QueryResultPaginatorTest extends FunctionalTestCase
         self::assertCount(4, $paginator->getPaginatedItems());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function paginatorProperlyCalculatesOnlyOnePage(): void
     {
         $paginator = new QueryResultPaginator(
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/AddTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/AddTest.php
index 03735c73855f..dea56c0f120f 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/AddTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/AddTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Database\ConnectionPool;
@@ -48,9 +49,7 @@ final class AddTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addSimpleObjectTest(): void
     {
         $newBlogTitle = 'aDi1oogh';
@@ -76,9 +75,7 @@ final class AddTest extends FunctionalTestCase
         self::assertEquals(1, $newBlogCount);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addObjectSetsDefaultLanguageTest(): void
     {
         $newBlogTitle = 'aDi1oogh';
@@ -104,9 +101,7 @@ final class AddTest extends FunctionalTestCase
         self::assertEquals(0, $newBlogRecord['sys_language_uid']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addObjectSetsDefinedLanguageTest(): void
     {
         $newBlogTitle = 'aDi1oogh';
@@ -133,9 +128,7 @@ final class AddTest extends FunctionalTestCase
         self::assertEquals(-1, $newBlogRecord['sys_language_uid']);
     }
 
-    /**
-    * @test
-    */
+    #[Test]
     public function addObjectSetsNullAsNullForSimpleTypes(): void
     {
         $newBlogTitle = 'aDi1oogh';
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/CountTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/CountTest.php
index 4356130f7698..1827fc4ccfd0 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/CountTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/CountTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -42,18 +43,14 @@ final class CountTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function simpleCountTest(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
         self::assertSame($this->numberOfRecordsInFixture, $query->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function offsetCountTest(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -62,9 +59,7 @@ final class CountTest extends FunctionalTestCase
         self::assertSame($this->numberOfRecordsInFixture - 6, $query->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exceedingOffsetCountTest(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -73,9 +68,7 @@ final class CountTest extends FunctionalTestCase
         self::assertSame(0, $query->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function limitCountTest(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -83,9 +76,7 @@ final class CountTest extends FunctionalTestCase
         self::assertSame(4, $query->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function limitAndOffsetCountTest(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -95,9 +86,7 @@ final class CountTest extends FunctionalTestCase
         self::assertSame(3, $query->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inConstraintCountTest(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -109,9 +98,8 @@ final class CountTest extends FunctionalTestCase
 
     /**
      * Test if count works with subproperties in subselects.
-     *
-     * @test
      */
+    #[Test]
     public function subpropertyJoinCountTest(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -123,9 +111,8 @@ final class CountTest extends FunctionalTestCase
 
     /**
      * Test if count works with subproperties in subselects that use the same table as the repository.
-     *
-     * @test
      */
+    #[Test]
     public function subpropertyJoinSameTableCountTest(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -137,9 +124,8 @@ final class CountTest extends FunctionalTestCase
 
     /**
      * Test if count works with subproperties in multiple left join.
-     *
-     * @test
      */
+    #[Test]
     public function subpropertyInMultipleLeftJoinCountTest(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -155,9 +141,7 @@ final class CountTest extends FunctionalTestCase
         self::assertSame(10, $result->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function queryWithAndConditionsToTheSameTableReturnExpectedCount(): void
     {
         $personRepository = $this->get(PersonRepository::class);
@@ -171,9 +155,7 @@ final class CountTest extends FunctionalTestCase
         self::assertSame(1, $query->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function queryWithOrConditionsToTheSameTableReturnExpectedCount(): void
     {
         $personRepository = $this->get(PersonRepository::class);
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/EnableFieldsTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/EnableFieldsTest.php
index 162a2ea063d7..512ef0e792a0 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/EnableFieldsTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/EnableFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -41,9 +42,7 @@ final class EnableFieldsTest extends AbstractDataHandlerActionTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function protectedRecordsNotFoundIfNoUserLoggedIn(): void
     {
         $response = $this->executeFrontendSubRequest((new InternalRequest())->withPageId(1));
@@ -52,9 +51,7 @@ final class EnableFieldsTest extends AbstractDataHandlerActionTestCase
             ->setTable(self::TABLE_Blog)->setField('title')->setValues('Blog1'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function onlyReturnProtectedRecordsForTheFirstUserGroup(): void
     {
         $response = $this->executeFrontendSubRequest((new InternalRequest())->withPageId(1), (new InternalRequestContext())->withFrontendUserId(1));
@@ -63,9 +60,7 @@ final class EnableFieldsTest extends AbstractDataHandlerActionTestCase
             ->setTable(self::TABLE_Blog)->setField('title')->setValues('Blog1', 'Blog2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function onlyReturnProtectedRecordsForTheSecondUserGroup(): void
     {
         $response = $this->executeFrontendSubRequest((new InternalRequest())->withPageId(1), (new InternalRequestContext())->withFrontendUserId(2));
@@ -74,9 +69,7 @@ final class EnableFieldsTest extends AbstractDataHandlerActionTestCase
             ->setTable(self::TABLE_Blog)->setField('title')->setValues('Blog1', 'Blog3'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function onlyOwnProtectedRecordsWithQueryCacheInvolvedAreReturned(): void
     {
         // first request to fill the query cache
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Mapper/ColumnMapFactoryTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Mapper/ColumnMapFactoryTest.php
index cae390a9b475..394117486b35 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Mapper/ColumnMapFactoryTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Mapper/ColumnMapFactoryTest.php
@@ -17,11 +17,14 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence\Generic\Mapper;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\DataHandling\TableColumnType;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap;
 use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap\Relation;
 use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMapFactory;
+use TYPO3\CMS\Extbase\Tests\Functional\Persistence\Generic\Mapper\Fixtures\ColumnMapFactoryEntityFixture;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class ColumnMapFactoryTest extends FunctionalTestCase
@@ -88,15 +91,13 @@ final class ColumnMapFactoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider createWithGroupTypeDataProvider
-     * @test
-     */
+    #[DataProvider('createWithGroupTypeDataProvider')]
+    #[Test]
     public function createWithGroupType(string $columnName, array $columnConfiguration, string $propertyName, ColumnMap $expectedColumnMap): void
     {
         self::assertEquals(
             $expectedColumnMap,
-            $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, Fixtures\ColumnMapFactoryEntityFixture::class)
+            $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, ColumnMapFactoryEntityFixture::class)
         );
     }
 
@@ -212,15 +213,13 @@ final class ColumnMapFactoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider createWithSelectTypeDataProvider
-     * @test
-     */
+    #[DataProvider('createWithSelectTypeDataProvider')]
+    #[Test]
     public function createWithSelectType(string $columnName, array $columnConfiguration, string $propertyName, ColumnMap $expectedColumnMap): void
     {
         self::assertEquals(
             $expectedColumnMap,
-            $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, Fixtures\ColumnMapFactoryEntityFixture::class)
+            $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, ColumnMapFactoryEntityFixture::class)
         );
     }
 
@@ -243,15 +242,13 @@ final class ColumnMapFactoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider createWithFolderTypeDataProvider
-     * @test
-     */
+    #[DataProvider('createWithFolderTypeDataProvider')]
+    #[Test]
     public function createWithFolderType(string $columnName, array $columnConfiguration, string $propertyName, ColumnMap $expectedColumnMap): void
     {
         self::assertEquals(
             $expectedColumnMap,
-            $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, Fixtures\ColumnMapFactoryEntityFixture::class)
+            $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, ColumnMapFactoryEntityFixture::class)
         );
     }
 
@@ -281,21 +278,17 @@ final class ColumnMapFactoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider createWithInlineTypeDataProvider
-     * @test
-     */
+    #[DataProvider('createWithInlineTypeDataProvider')]
+    #[Test]
     public function createWithInlineType(string $columnName, array $columnConfiguration, string $propertyName, ColumnMap $expectedColumnMap): void
     {
         self::assertEquals(
             $expectedColumnMap,
-            $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, Fixtures\ColumnMapFactoryEntityFixture::class)
+            $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, ColumnMapFactoryEntityFixture::class)
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function settingOneToOneRelationSetsRelationTableMatchFields(): void
     {
         $columnName = 'has_one';
@@ -311,7 +304,7 @@ final class ColumnMapFactoryTest extends FunctionalTestCase
             ],
         ];
 
-        $columnMap = $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, Fixtures\ColumnMapFactoryEntityFixture::class);
+        $columnMap = $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, ColumnMapFactoryEntityFixture::class);
 
         self::assertSame(
             [
@@ -321,9 +314,7 @@ final class ColumnMapFactoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function settingOneToManyRelationSetsRelationTableMatchFields(): void
     {
         $columnName = 'has_many';
@@ -339,7 +330,7 @@ final class ColumnMapFactoryTest extends FunctionalTestCase
             ],
         ];
 
-        $columnMap = $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, Fixtures\ColumnMapFactoryEntityFixture::class);
+        $columnMap = $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, ColumnMapFactoryEntityFixture::class);
 
         self::assertSame(
             [
@@ -349,9 +340,7 @@ final class ColumnMapFactoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function columnMapIsInitializedWithManyToManyRelationOfTypeSelect(): void
     {
         $columnName = 'has_and_belongs_to_many';
@@ -375,12 +364,10 @@ final class ColumnMapFactoryTest extends FunctionalTestCase
             ],
         ];
 
-        self::assertEquals($expectedColumnMap, $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, Fixtures\ColumnMapFactoryEntityFixture::class));
+        self::assertEquals($expectedColumnMap, $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, ColumnMapFactoryEntityFixture::class));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function columnMapIsInitializedWithOppositeManyToManyRelationOfTypeSelect(): void
     {
         $columnName = 'has_and_belongs_to_many';
@@ -403,12 +390,10 @@ final class ColumnMapFactoryTest extends FunctionalTestCase
             ],
         ];
 
-        self::assertEquals($expectedColumnMap, $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, Fixtures\ColumnMapFactoryEntityFixture::class));
+        self::assertEquals($expectedColumnMap, $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, ColumnMapFactoryEntityFixture::class));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function columnMapIsInitializedWithManyToManyRelationOfTypeInlineAndIntermediateTable(): void
     {
         $columnName = 'has_and_belongs_to_many';
@@ -431,7 +416,7 @@ final class ColumnMapFactoryTest extends FunctionalTestCase
             ],
         ];
 
-        self::assertEquals($expectedColumnMap, $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, Fixtures\ColumnMapFactoryEntityFixture::class));
+        self::assertEquals($expectedColumnMap, $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, ColumnMapFactoryEntityFixture::class));
     }
 
     public static function columnMapIsInitializedWithFieldEvaluationsForDateTimeFieldsDataProvider(): array
@@ -444,10 +429,8 @@ final class ColumnMapFactoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider columnMapIsInitializedWithFieldEvaluationsForDateTimeFieldsDataProvider
-     */
+    #[DataProvider('columnMapIsInitializedWithFieldEvaluationsForDateTimeFieldsDataProvider')]
+    #[Test]
     public function columnMapIsInitializedWithFieldEvaluationsForDateTimeFields(string $type, ?string $expectedValue): void
     {
         $columnName = 'virtual';
@@ -459,7 +442,7 @@ final class ColumnMapFactoryTest extends FunctionalTestCase
             ],
         ];
 
-        $columnMap = $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, Fixtures\ColumnMapFactoryEntityFixture::class);
+        $columnMap = $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, ColumnMapFactoryEntityFixture::class);
 
         self::assertSame($expectedValue, $columnMap->getDateTimeStorageFormat());
     }
@@ -494,10 +477,8 @@ final class ColumnMapFactoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider tcaConfigurationsContainingTypeDataProvider
-     */
+    #[DataProvider('tcaConfigurationsContainingTypeDataProvider')]
+    #[Test]
     public function setTypeDetectsTypeProperly(string $type, TableColumnType $expectedType): void
     {
         $columnName = 'virtual';
@@ -508,7 +489,7 @@ final class ColumnMapFactoryTest extends FunctionalTestCase
             ],
         ];
 
-        $columnMap = $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, Fixtures\ColumnMapFactoryEntityFixture::class);
+        $columnMap = $this->columnMapFactory->create($columnName, $columnConfiguration, $propertyName, ColumnMapFactoryEntityFixture::class);
 
         self::assertSame($expectedType, $columnMap->getType());
     }
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Mapper/DataMapFactoryTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Mapper/DataMapFactoryTest.php
index 891d27fe5fbf..08f1685b0373 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Mapper/DataMapFactoryTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Mapper/DataMapFactoryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence\Generic\Mapper;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap;
 use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap;
@@ -40,9 +41,7 @@ final class DataMapFactoryTest extends FunctionalTestCase
         $GLOBALS['BE_USER'] = new BackendUserAuthentication();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function classSettingsAreResolved(): void
     {
         $dataMap = $this->dataMapFactory->buildDataMap(Administrator::class);
@@ -52,9 +51,7 @@ final class DataMapFactoryTest extends FunctionalTestCase
         self::assertEquals('fe_users', $dataMap->getTableName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function columnMapPropertiesAreResolved(): void
     {
         $dataMap = $this->dataMapFactory->buildDataMap(TtContent::class);
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Mapper/DataMapperTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Mapper/DataMapperTest.php
index fdea8edaf63f..9cdaf679a355 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Mapper/DataMapperTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Mapper/DataMapperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence\Generic\Mapper;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Cache\CacheManager;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
@@ -26,6 +28,7 @@ use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap;
 use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper;
 use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\Exception\UnknownPropertyTypeException;
 use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
+use TYPO3\CMS\Extbase\Tests\Functional\Persistence\Generic\Mapper\Fixtures\HydrationFixtureEntity;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Tests\BlogExample\Domain\Model\Blog;
 use TYPO3Tests\BlogExample\Domain\Model\Comment;
@@ -55,9 +58,7 @@ final class DataMapperTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function dateValuesAreStoredInUtcInIntegerDatabaseFields(): void
     {
         $example = new DateExample();
@@ -75,9 +76,7 @@ final class DataMapperTest extends FunctionalTestCase
         self::assertEquals($example->getDatetimeInt()->getTimestamp(), $date->getTimestamp());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function dateValuesAreStoredInUtcInTextDatabaseFields(): void
     {
         $example = new DateExample();
@@ -95,9 +94,7 @@ final class DataMapperTest extends FunctionalTestCase
         self::assertEquals($example->getDatetimeText()->getTimestamp(), $date->getTimestamp());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function dateValuesAreStoredInLocalTimeInDatetimeDatabaseFields(): void
     {
         $example = new DateExample();
@@ -115,9 +112,7 @@ final class DataMapperTest extends FunctionalTestCase
         self::assertEquals($example->getDatetimeDatetime()->getTimestamp(), $date->getTimestamp());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function dateTimeImmutableIntIsHandledAsDateTime(): void
     {
         $subject = new DateTimeImmutableExample();
@@ -135,9 +130,7 @@ final class DataMapperTest extends FunctionalTestCase
         self::assertEquals($date, $subject->getDatetimeImmutableInt());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function dateTimeImmutableTextIsHandledAsDateTime(): void
     {
         $subject = new DateTimeImmutableExample();
@@ -155,9 +148,7 @@ final class DataMapperTest extends FunctionalTestCase
         self::assertEquals($date, $subject->getDatetimeImmutableText());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function dateTimeImmutableDateTimeIsHandledAsDateTime(): void
     {
         $subject = new DateTimeImmutableExample();
@@ -175,9 +166,7 @@ final class DataMapperTest extends FunctionalTestCase
         self::assertSame($date->getTimestamp(), $subject->getDatetimeImmutableDatetime()->getTimestamp());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function mapMapsArrayToObject(): void
     {
         $rows = [['uid' => 1234]];
@@ -189,9 +178,7 @@ final class DataMapperTest extends FunctionalTestCase
         self::assertSame(1234, $mappedObjectArray[0]->getUid());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function mapMapsArrayToObjectFromPersistence(): void
     {
         $rows1 = [['uid' => 1234, 'title' => 'From persistence']];
@@ -206,9 +193,7 @@ final class DataMapperTest extends FunctionalTestCase
         self::assertSame('From persistence', $mappedObjectArray[0]->getTitle());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function thawPropertiesSetsPropertyValues(): void
     {
         $rows = [
@@ -242,9 +227,7 @@ final class DataMapperTest extends FunctionalTestCase
         self::assertTrue($reflectionProperty->isInitialized($object));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function thawPropertiesThrowsExceptionOnUnknownPropertyType(): void
     {
         $rows = [
@@ -260,9 +243,7 @@ final class DataMapperTest extends FunctionalTestCase
         $dataMapper->map(Example::class, $rows);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fetchRelatedEagerReturnsNullForEmptyRelationHasOne(): void
     {
         $rows = [
@@ -277,9 +258,7 @@ final class DataMapperTest extends FunctionalTestCase
         self::assertNull($mappedObjectsArray[0]->getBlog());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fetchRelatedEagerReturnsEmptyArrayForEmptyRelationNotHasOne(): void
     {
         $rows = [
@@ -294,9 +273,7 @@ final class DataMapperTest extends FunctionalTestCase
         self::assertCount(0, $mappedObjectsArray[0]->getPosts());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function mapObjectToClassPropertyReturnsExistingObjectWithoutCallingFetchRelated(): void
     {
         $blogRows = [
@@ -337,10 +314,8 @@ final class DataMapperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider mapDateTimeHandlesDifferentFieldEvaluationsDataProvider
-     */
+    #[DataProvider('mapDateTimeHandlesDifferentFieldEvaluationsDataProvider')]
+    #[Test]
     public function mapDateTimeHandlesDifferentFieldEvaluations(string|int|null $value, string|null $storageFormat, string|null $expectedValue): void
     {
         $GLOBALS['TCA']['tx_testdatamapper_domain_model_example']['columns']['initialized_date_time_property']['config']['dbType'] = $storageFormat;
@@ -372,10 +347,8 @@ final class DataMapperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider mapDateTimeHandlesDifferentFieldEvaluationsWithTimeZoneDataProvider
-     */
+    #[DataProvider('mapDateTimeHandlesDifferentFieldEvaluationsWithTimeZoneDataProvider')]
+    #[Test]
     public function mapDateTimeHandlesDifferentFieldEvaluationsWithTimeZone(string|int|null $value, ?string $storageFormat, ?string $expectedValue): void
     {
         $originalTimeZone = date_default_timezone_get();
@@ -403,9 +376,7 @@ final class DataMapperTest extends FunctionalTestCase
         date_default_timezone_set($originalTimeZone);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function mapDateTimeHandlesSubclassesOfDateTime(): void
     {
         $rows = [
@@ -420,9 +391,7 @@ final class DataMapperTest extends FunctionalTestCase
         self::assertInstanceOf(CustomDateTime::class, $mappedObjectsArray[0]->getCustomDateTime());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPlainValueReturnsCorrectDateTimeFormat(): void
     {
         $dataMapper = $this->get(DataMapper::class);
@@ -455,10 +424,8 @@ final class DataMapperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getPlainValueReturnsExpectedValuesDataProvider
-     */
+    #[DataProvider('getPlainValueReturnsExpectedValuesDataProvider')]
+    #[Test]
     public function getPlainValueReturnsExpectedValues(string|int $expectedValue, mixed $input): void
     {
         $dataMapper = $this->get(DataMapper::class);
@@ -468,9 +435,7 @@ final class DataMapperTest extends FunctionalTestCase
         self::assertSame($expectedValue, $plainValue);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPlainValueCallsGetRealInstanceOnInputIfInputIsInstanceOfLazyLoadingProxy(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/DataMapperTestImport.csv');
@@ -488,9 +453,7 @@ final class DataMapperTest extends FunctionalTestCase
         self::assertSame(1, $plainValue);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fetchRelatedRespectsForeignDefaultSortByTCAConfiguration(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/DataMapperTestImport.csv');
@@ -510,9 +473,7 @@ final class DataMapperTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createEmptyObjectThrowsInvalidClassExceptionIfClassNameDoesNotImplementDomainObjectInterface(): void
     {
         self::expectException(InvalidClassException::class);
@@ -523,9 +484,7 @@ final class DataMapperTest extends FunctionalTestCase
         $subjectReflection->getMethod('createEmptyObject')->invoke($subject, \stdClass::class);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createEmptyObjectInstantiatesWithoutCallingTheConstructorButCallsInitializeObject(): void
     {
         self::expectException(\RuntimeException::class);
@@ -533,6 +492,6 @@ final class DataMapperTest extends FunctionalTestCase
         self::expectExceptionCode(1680071491);
         $subject = $this->get(DataMapper::class);
         $subjectReflection = new \ReflectionObject($subject);
-        $subjectReflection->getMethod('createEmptyObject')->invoke($subject, Fixtures\HydrationFixtureEntity::class);
+        $subjectReflection->getMethod('createEmptyObject')->invoke($subject, HydrationFixtureEntity::class);
     }
 }
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Storage/Typo3DbBackendTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Storage/Typo3DbBackendTest.php
index f90ad76490c5..47945cd60449 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Storage/Typo3DbBackendTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Storage/Typo3DbBackendTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence\Generic\Storage;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\LanguageAspect;
 use TYPO3\CMS\Core\Context\WorkspaceAspect;
@@ -40,9 +41,7 @@ final class Typo3DbBackendTest extends FunctionalTestCase
         'typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function uidOfAlreadyPersistedValueObjectIsDeterminedCorrectly(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/Typo3DbBackendTestImport.csv');
@@ -52,9 +51,7 @@ final class Typo3DbBackendTest extends FunctionalTestCase
         self::assertSame(10, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getObjectDataByQueryChangesUidIfInPreview(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/Typo3DbBackendTestImport.csv');
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Storage/Typo3DbQueryParserTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Storage/Typo3DbQueryParserTest.php
index 8cc41b332748..bcc17f036f1e 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Storage/Typo3DbQueryParserTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/Generic/Storage/Typo3DbQueryParserTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence\Generic\Storage;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\DateTimeAspect;
 use TYPO3\CMS\Core\Context\LanguageAspect;
@@ -44,9 +46,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         'typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertQueryToDoctrineQueryBuilderDoesNotAddAndWhereWithEmptyConstraint(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -66,9 +66,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertCount(4, $compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertQueryToDoctrineQueryBuilderThrowsExceptionOnNotImplementedConstraint(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -91,9 +89,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         $typo3DbQueryParser->convertQueryToDoctrineQueryBuilder($query);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertQueryToDoctrineQueryBuilderAddsSimpleAndWhere(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -116,9 +112,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertStringContainsString('uid', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertQueryToDoctrineQueryBuilderAddsNotConstraint(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -141,9 +135,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/NOT\(.*uid/', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertQueryToDoctrineQueryBuilderAddsAndConstraint(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -170,9 +162,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/title.* AND .*description/', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertQueryToDoctrineQueryBuilderAddsOrConstraint(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -199,9 +189,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/title.* OR .*description/', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function languageStatementWorksForDefaultLanguage(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -220,9 +208,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/sys_language_uid. IN \(0, -1\)/', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function languageStatementWorksForNonDefaultLanguage(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -249,9 +235,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/sys_language_uid. IN \(1, -1\)/', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function languageStatementWorksInBackendContext(): void
     {
         $GLOBALS['TYPO3_REQUEST'] = (new ServerRequest())->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_BE);
@@ -274,9 +258,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/sys_language_uid. IN \(1, -1\)/', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addGetLanguageStatementWorksForForeignLanguageWithSubselectionWithoutDeleteStatementReturned(): void
     {
         $GLOBALS['TCA']['tx_blogexample_domain_model_blog']['ctrl']['delete'] = null;
@@ -301,9 +283,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertStringNotContainsString('deleted', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addGetLanguageStatementWorksForForeignLanguageWithSubselectionTakesDeleteStatementIntoAccountIfNecessary(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -331,9 +311,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertStringContainsString('deleted', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addGetLanguageStatementWorksInBackendContextWithSubselectionTakesDeleteStatementIntoAccountIfNecessary(): void
     {
         $GLOBALS['TYPO3_REQUEST'] = (new ServerRequest())
@@ -358,9 +336,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertStringContainsString('deleted', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function orderStatementGenerationWorks(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -387,9 +363,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/title. DESC/', $orderBy[0]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function orderStatementGenerationThrowsExceptionOnUnsupportedOrder(): void
     {
         $this->expectException(UnsupportedOrderException::class);
@@ -416,9 +390,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         $typo3DbQueryParser->convertQueryToDoctrineQueryBuilder($query);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function orderStatementGenerationWorksWithMultipleOrderings(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -448,9 +420,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/description. ASC/', $orderBy[1]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function expressionIsOmittedForIgnoreEnableFieldsAreAndDoNotIncludeDeletedInBackendContext(): void
     {
         $GLOBALS['TYPO3_REQUEST'] = (new ServerRequest())
@@ -473,9 +443,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertStringNotContainsString('deleted', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function expressionIsGeneratedForIgnoreEnableFieldsAndDoNotIncludeDeletedInBackendContext(): void
     {
         $GLOBALS['TYPO3_REQUEST'] = (new ServerRequest())
@@ -498,9 +466,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertStringContainsString('deleted', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function expressionIsGeneratedForDoNotIgnoreEnableFieldsAndIncludeDeletedInBackendContext(): void
     {
         $GLOBALS['TYPO3_REQUEST'] = (new ServerRequest())
@@ -522,9 +488,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertStringNotContainsString('deleted', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function expressionIsGeneratedForDoNotIgnoreEnableFieldsAndDoNotIncludeDeletedInBackendContext(): void
     {
         $GLOBALS['TYPO3_REQUEST'] = (new ServerRequest())
@@ -546,9 +510,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertStringContainsString('deleted', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function expressionIsOmittedForIgnoreEnableFieldsAreAndDoNotIncludeDeletedInFrontendContext(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -573,9 +535,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertStringNotContainsString('deleted', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function expressionIsGeneratedForIgnoreEnableFieldsAndDoNotIncludeDeletedInFrontendContext(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -600,9 +560,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertStringContainsString('deleted', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function expressionIsGeneratedForIgnoreOnlyFeGroupAndDoNotIncludeDeletedInFrontendContext(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -629,9 +587,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertStringContainsString('deleted', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function expressionIsGeneratedForDoNotIgnoreEnableFieldsAndDoNotIncludeDeletedInFrontendContext(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -657,9 +613,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertStringContainsString('deleted', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function respectEnableFieldsSettingGeneratesCorrectStatementWithOnlyEndTimeInFrontendContext(): void
     {
         $GLOBALS['TCA']['tx_blogexample_domain_model_blog']['ctrl']['enablecolumns']['endtime'] = 'endtime_column';
@@ -685,9 +639,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/endtime_column. = 0\) OR \(.*endtime_column. > 1451779200/', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function respectEnableFieldsSettingGeneratesCorrectStatementWithOnlyEndTimeInBackendContext(): void
     {
         // simulate time for backend enable fields
@@ -712,9 +664,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertMatchesRegularExpression('/endtime_column. = 0\) OR \(.*endtime_column. > 1451779200/', (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function visibilityConstraintStatementGenerationThrowsExceptionIfTheQuerySettingsAreInconsistent(): void
     {
         $frontendTypoScript = new FrontendTypoScript(new RootNode(), []);
@@ -772,10 +722,8 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider addPageIdStatementSetsPidToZeroIfTableDeclaresRootLevelDataProvider
-     */
+    #[DataProvider('addPageIdStatementSetsPidToZeroIfTableDeclaresRootLevelDataProvider')]
+    #[Test]
     public function addPageIdStatementSetsPidToZeroIfTableDeclaresRootLevel(int $rootLevel, string $expectedSql, array $storagePageIds): void
     {
         $GLOBALS['TCA']['tx_blogexample_domain_model_blog']['ctrl'] = [
@@ -801,9 +749,7 @@ final class Typo3DbQueryParserTest extends FunctionalTestCase
         self::assertMatchesRegularExpression($expectedSql, (string)$compositeExpression);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function tcaWithoutCtrlCreatesAValidSQLStatement(): void
     {
         $GLOBALS['TYPO3_REQUEST'] = (new ServerRequest())
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/InTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/InTest.php
index 1d6573edb8bc..c2297976c923 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/InTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/InTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Persistence\Generic\LazyObjectStorage;
@@ -44,9 +45,7 @@ final class InTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inConditionWorksWithArrayOfObjects(): void
     {
         $blog1 = $this->blogRepository->findByUid(1);
@@ -58,9 +57,7 @@ final class InTest extends FunctionalTestCase
         self::assertSame(11, $inQuery->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inConditionWorksWithArrayOfObjectsOnSecondCall(): void
     {
         $blog1 = $this->blogRepository->findByUid(1);
@@ -77,9 +74,7 @@ final class InTest extends FunctionalTestCase
         self::assertSame(10, $newInQuery->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inConditionWorksWithObjectStorage(): void
     {
         $blog1 = $this->blogRepository->findByUid(1);
@@ -94,9 +89,7 @@ final class InTest extends FunctionalTestCase
         self::assertSame(11, $inQuery->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inConditionWorksWithObjectStorageOnSecondCall(): void
     {
         $blog1 = $this->blogRepository->findByUid(1);
@@ -118,9 +111,7 @@ final class InTest extends FunctionalTestCase
         self::assertSame(10, $newInQuery->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inConditionWorksWithQueryResult(): void
     {
         $query = $this->blogRepository->createQuery();
@@ -133,9 +124,7 @@ final class InTest extends FunctionalTestCase
         self::assertSame(11, $inQuery->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inConditionWorksWithQueryResultOnSecondCall(): void
     {
         $query = $this->blogRepository->createQuery();
@@ -153,9 +142,7 @@ final class InTest extends FunctionalTestCase
         self::assertSame(11, $newInQuery->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inConditionWorksWithLazyObjectStorage(): void
     {
         $blog = $this->blogRepository->findByUid(1);
@@ -167,9 +154,7 @@ final class InTest extends FunctionalTestCase
         self::assertSame(10, $inQuery->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function inConditionWorksWithLazyObjectStorageOnSecondCall(): void
     {
         $blog = $this->blogRepository->findByUid(1);
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/IsDirtyTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/IsDirtyTest.php
index 94f2ee748d1b..cd34d857b617 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/IsDirtyTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/IsDirtyTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy;
@@ -39,18 +40,14 @@ final class IsDirtyTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function objectFetchedFromDbIsNotDirty(): void
     {
         $blog = $this->get(BlogRepository::class)->findByUid(3);
         self::assertFalse($blog->_isDirty());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function lazyLoadingProxyReplacedByRealInstanceIsNotDirty(): void
     {
         $blog = $this->get(BlogRepository::class)->findByUid(3);
@@ -61,9 +58,7 @@ final class IsDirtyTest extends FunctionalTestCase
         self::assertFalse($blog->_isDirty());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function lazyLoadingProxyReplacedByWrongInstanceIsDirty(): void
     {
         $blog = $this->get(BlogRepository::class)->findByUid(3);
@@ -72,9 +67,7 @@ final class IsDirtyTest extends FunctionalTestCase
         self::assertTrue($blog->_isDirty());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function realInstanceReplacedByLazyLoadingProxyIsNotDirty(): void
     {
         $blog = $this->get(BlogRepository::class)->findByUid(3);
@@ -88,9 +81,7 @@ final class IsDirtyTest extends FunctionalTestCase
         self::assertFalse($blog->_isDirty());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function lazyLoadingProxyByWrongLazyLoadingProxyIsDirtyAndUpdated(): void
     {
         $blogRepository = $this->get(BlogRepository::class);
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/LazyLoadingProxyTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/LazyLoadingProxyTest.php
index 53563db76e2d..a47e0365942d 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/LazyLoadingProxyTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/LazyLoadingProxyTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy;
@@ -38,9 +39,7 @@ final class LazyLoadingProxyTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function serializeAndUnserialize(): void
     {
         $blog = new Blog();
@@ -61,9 +60,7 @@ final class LazyLoadingProxyTest extends FunctionalTestCase
         self::assertSame('Blog Admin', $administrator->getUsername());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function nonExistingLazyLoadedPropertyReturnsNull(): void
     {
         $lazyLoadingProxy = new LazyLoadingProxy(new Blog(), 'administrator', 0);
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/LazyObjectStorageTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/LazyObjectStorageTest.php
index 7754055ad71a..651894f5b535 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/LazyObjectStorageTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/LazyObjectStorageTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Persistence\Generic\LazyObjectStorage;
@@ -40,9 +41,7 @@ final class LazyObjectStorageTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function serializeAndUnserialize(): void
     {
         $blog = new Blog();
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/OperatorTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/OperatorTest.php
index 72594adf6b63..4699469c7019 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/OperatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/OperatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Persistence\QueryInterface;
@@ -37,9 +38,7 @@ final class OperatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function equalsNullIsResolvedCorrectly(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -49,9 +48,7 @@ final class OperatorTest extends FunctionalTestCase
         self::assertSame(0, $query->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function equalsCorrectlyHandlesCaseSensitivity(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -61,9 +58,7 @@ final class OperatorTest extends FunctionalTestCase
         self::assertSame(2, $query->count());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function betweenSetsBoundariesCorrectly(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/ParentChildTranslationTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/ParentChildTranslationTest.php
index 05698f4e667d..5d70465036d7 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/ParentChildTranslationTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/ParentChildTranslationTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Context\LanguageAspect;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Tests\ParentChildTranslation\Domain\Repository\MainRepository;
@@ -32,9 +33,7 @@ final class ParentChildTranslationTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/Fixtures/parentChildTranslationExampleData.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizeChildrenOfAllLanguageElementToDefaultLanguage(): void
     {
         $query = $this->get(MainRepository::class)->createQuery();
@@ -59,9 +58,7 @@ final class ParentChildTranslationTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizesChildrenOfAllLanguageElementToTranslation(): void
     {
         $query = $this->get(MainRepository::class)->createQuery();
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/QueryLocalizedDataTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/QueryLocalizedDataTest.php
index ed5c982e8153..a550ed56fd18 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/QueryLocalizedDataTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/QueryLocalizedDataTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\LanguageAspect;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
@@ -67,9 +69,8 @@ final class QueryLocalizedDataTest extends FunctionalTestCase
      *
      * Note that with feature flag disabled, you'll get same result (not translated record) for both calls ->findByUid(2)
      * and ->findByUid(11)
-     *
-     * @test
      */
+    #[Test]
     public function findByUidOverlayModeOnDefaultLanguage(): void
     {
         $context = GeneralUtility::makeInstance(Context::class);
@@ -109,9 +110,8 @@ final class QueryLocalizedDataTest extends FunctionalTestCase
 
     /**
      * Test in default language, overlays disabled
-     *
-     * @test
      */
+    #[Test]
     public function findByUidNoOverlaysDefaultLanguage(): void
     {
         $context = GeneralUtility::makeInstance(Context::class);
@@ -149,9 +149,8 @@ final class QueryLocalizedDataTest extends FunctionalTestCase
 
     /**
      * Test in language uid:1, overlays enabled
-     *
-     * @test
      */
+    #[Test]
     public function findByUidOverlayModeOnLanguage(): void
     {
         $context = GeneralUtility::makeInstance(Context::class);
@@ -188,9 +187,8 @@ final class QueryLocalizedDataTest extends FunctionalTestCase
 
     /**
      * Test in language uid:1, overlays disabled
-     *
-     * @test
      */
+    #[Test]
     public function findByUidNoOverlaysLanguage(): void
     {
         $context = GeneralUtility::makeInstance(Context::class);
@@ -232,9 +230,8 @@ final class QueryLocalizedDataTest extends FunctionalTestCase
      * All with overlay mode enabled.
      *
      * The post with uid 2 is translated to language 1, and there has uid 11.
-     *
-     * @test
      */
+    #[Test]
     public function customFindByUidOverlayEnabled(): void
     {
         // we're in default lang and fetching by uid of the record in default language
@@ -308,9 +305,8 @@ final class QueryLocalizedDataTest extends FunctionalTestCase
      * All with overlay mode disabled.
      *
      * The post with uid 2 is translated to language 1, and there has uid 11.
-     *
-     * @test
      */
+    #[Test]
     public function customFindByUidOverlayDisabled(): void
     {
         $query = $this->postRepository->createQuery();
@@ -790,10 +786,9 @@ final class QueryLocalizedDataTest extends FunctionalTestCase
      * This test check posts returned by repository, when changing language and languageOverlayMode
      * It also sets limit, offset to validate there are no "gaps" in pagination
      * and sorting (on a posts property)
-     *
-     * @test
-     * @dataProvider queryFirst5PostsDataProvider
      */
+    #[DataProvider('queryFirst5PostsDataProvider')]
+    #[Test]
     public function queryFirst5Posts(int $languageUid, string $overlay, array $expected): void
     {
         $languageAspect = new LanguageAspect($languageUid, $languageUid, $overlay);
@@ -1003,10 +998,9 @@ final class QueryLocalizedDataTest extends FunctionalTestCase
      * "Post 6" is not translated
      * "Post 5" is translated as "Post 5 - DA"
      * "Post DA only" has no translation parent
-     *
-     * @test
-     * @dataProvider queryPostsByPropertyDataProvider
      */
+    #[DataProvider('queryPostsByPropertyDataProvider')]
+    #[Test]
     public function queryPostsByProperty(int $languageUid, string $overlay, array $expected): void
     {
         $languageAspect = new LanguageAspect($languageUid, $languageUid, $overlay);
@@ -1084,10 +1078,9 @@ final class QueryLocalizedDataTest extends FunctionalTestCase
      * The expected state is that when setRespectSysLanguage is false, then both: default language record,
      * and translated language record should be returned. Regardless of the language setting or the overlay mode.
      * Now we're getting same record twice in some cases.
-     *
-     * @test
-     * @dataProvider postsWithoutRespectingSysLanguageDataProvider
      */
+    #[DataProvider('postsWithoutRespectingSysLanguageDataProvider')]
+    #[Test]
     public function postsWithoutRespectingSysLanguage(int $languageUid, string $overlay, array $expected): void
     {
         $languageAspect = new LanguageAspect($languageUid, $languageUid, $overlay);
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/QueryParserTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/QueryParserTest.php
index 1574e3b22949..dd02a0dfe954 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/QueryParserTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/QueryParserTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -39,9 +40,7 @@ final class QueryParserTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function queryWithMultipleRelationsToIdenticalTablesReturnsExpectedResultForOrQuery(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -59,9 +58,8 @@ final class QueryParserTest extends FunctionalTestCase
 
     /**
      * Test Relation::HAS_AND_BELONGS_TO_MANY
-     *
-     * @test
      */
+    #[Test]
     public function queryWithRelationHasAndBelongsToManyReturnsExpectedResult(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -73,9 +71,8 @@ final class QueryParserTest extends FunctionalTestCase
 
     /**
      * Test Relation::HAS_MANY
-     *
-     * @test
      */
+    #[Test]
     public function queryWithRelationHasManyWithoutParentKeyFieldNameReturnsExpectedResult(): void
     {
         $query = $this->get(AdministratorRepository::class)->createQuery();
@@ -87,9 +84,8 @@ final class QueryParserTest extends FunctionalTestCase
 
     /**
      * Test Relation::HAS_ONE, ColumnMap::Relation::HAS_AND_BELONGS_TO_MANY
-     *
-     * @test
      */
+    #[Test]
     public function queryWithRelationHasOneAndHasAndBelongsToManyWithoutParentKeyFieldNameReturnsExpectedResult(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -100,9 +96,7 @@ final class QueryParserTest extends FunctionalTestCase
         self::assertCount(12, $query->execute()->toArray());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function orReturnsExpectedResult(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -115,9 +109,7 @@ final class QueryParserTest extends FunctionalTestCase
         self::assertCount(2, $query->execute()->toArray());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function queryWithMultipleRelationsToIdenticalTablesReturnsExpectedResultForAndQuery(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -131,18 +123,14 @@ final class QueryParserTest extends FunctionalTestCase
         self::assertCount(1, $query->execute()->toArray());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function queryWithFindInSetReturnsExpectedResult(): void
     {
         $query = $this->get(AdministratorRepository::class)->createQuery();
         self::assertCount(2, $query->matching($query->contains('usergroup', 1))->execute());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function queryForPostWithCategoriesReturnsPostWithCategories(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -150,9 +138,7 @@ final class QueryParserTest extends FunctionalTestCase
         self::assertCount(3, $post->getCategories());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function queryForBlogsAndPostsWithNoPostsShowsBlogRecord(): void
     {
         $query = $this->get(BlogRepository::class)->createQuery();
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/RelationTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/RelationTest.php
index 4c06ac72b789..bb8e40888f3d 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/RelationTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/RelationTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Database\Connection;
@@ -58,9 +60,8 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Tests adding object at the end of sorted 1:M relation (Blog:Posts)
-     *
-     * @test
      */
+    #[Test]
     public function attachPostToBlogAtTheEnd(): void
     {
         $newPostTitle = 'sdufhisdhuf';
@@ -75,9 +76,8 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Tests removing object from the end of sorted 1:M relation (Blog:Posts)
-     *
-     * @test
      */
+    #[Test]
     public function removeLastPostFromBlog(): void
     {
         $posts = $this->blog->getPosts();
@@ -91,9 +91,8 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Tests adding object in the middle of the sorted 1:M relation (Blog:Posts)
-     *
-     * @test
      */
+    #[Test]
     public function addPostToBlogInTheMiddle(): void
     {
         $newPost = new Post();
@@ -117,9 +116,8 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Tests removing object from the middle of sorted 1:M relation (Blog:Posts)
-     *
-     * @test
      */
+    #[Test]
     public function removeMiddlePostFromBlog(): void
     {
         $posts = clone $this->blog->getPosts();
@@ -136,9 +134,8 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Tests moving object from the end to the middle of the sorted 1:M relation (Blog:Posts)
-     *
-     * @test
      */
+    #[Test]
     public function movePostFromEndToTheMiddle(): void
     {
         $posts = clone $this->blog->getPosts();
@@ -164,9 +161,8 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Tests adding object at the end of sorted M:M relation (Post:Tag)
-     *
-     * @test
      */
+    #[Test]
     public function attachTagToPostAtTheEnd(): void
     {
         $newTagTitle = 'sdufhisdhuf';
@@ -181,9 +177,8 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Tests removing object from the end of sorted M:M relation (Post:Tag)
-     *
-     * @test
      */
+    #[Test]
     public function removeLastTagFromPost(): void
     {
         $postRepository = $this->get(PostRepository::class);
@@ -204,9 +199,8 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Tests adding object in the middle of sorted M:M relation (Post:Tag)
-     *
-     * @test
      */
+    #[Test]
     public function addTagToPostInTheMiddle(): void
     {
         $postRepository = $this->get(PostRepository::class);
@@ -233,9 +227,8 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Tests removing object from the middle of the sorted M:M relation (Post:Tag)
-     *
-     * @test
      */
+    #[Test]
     public function removeMiddleTagFromPost(): void
     {
         $postRepository = $this->get(PostRepository::class);
@@ -256,9 +249,8 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Tests moving object from the end to the middle of sorted M:M relation (Post:Tag)
-     *
-     * @test
      */
+    #[Test]
     public function moveTagFromEndToTheMiddle(): void
     {
         $postRepository = $this->get(PostRepository::class);
@@ -289,9 +281,7 @@ final class RelationTest extends FunctionalTestCase
         $this->assertCSVDataSet(__DIR__ . '/Fixtures/RelationTestResultMoveTagFromEndToTheMiddle.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function mmRelationWithMatchFieldIsResolvedFromLocalSide(): void
     {
         $queryBuilder = (new ConnectionPool())->getQueryBuilderForTable('sys_category_record_mm');
@@ -324,9 +314,8 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Test query matching respects MM_match_fields
-     *
-     * @test
      */
+    #[Test]
     public function mmRelationWithMatchFieldIsResolvedFromForeignSide(): void
     {
         $postRepository = $this->get(PostRepository::class);
@@ -337,9 +326,7 @@ final class RelationTest extends FunctionalTestCase
         self::assertCount(0, $posts);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function mmRelationWithMatchFieldIsCreatedFromLocalSide(): void
     {
         $queryBuilder = (new ConnectionPool())->getQueryBuilderForTable('sys_category_record_mm');
@@ -400,9 +387,8 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Test if adjusting existing mm relations do not relations with other objects
-     *
-     * @test
      */
+    #[Test]
     public function adjustingMmRelationWithTablesnameAndFieldnameFieldDoNotTouchOtherRelations(): void
     {
         $postRepository = $this->get(PostRepository::class);
@@ -532,9 +518,9 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Addresses Relation::HAS_ONE relations.
-     * @test
-     * @dataProvider distinctDataProvider
      */
+    #[DataProvider('distinctDataProvider')]
+    #[Test]
     public function distinctPersonEntitiesAreFoundByPublisher(array $queryRequest): void
     {
         $query = $this->provideFindPostsByPublisherQuery(1);
@@ -550,9 +536,9 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Addresses Relation::HAS_ONE relations.
-     * @test
-     * @dataProvider distinctDataProvider
      */
+    #[DataProvider('distinctDataProvider')]
+    #[Test]
     public function distinctPersonRecordsAreFoundByPublisher(array $queryRequest): void
     {
         $query = $this->provideFindPostsByPublisherQuery(1);
@@ -578,9 +564,9 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Addresses Relation::HAS_MANY relations.
-     * @test
-     * @dataProvider distinctDataProvider
      */
+    #[DataProvider('distinctDataProvider')]
+    #[Test]
     public function distinctBlogEntitiesAreFoundByPostsSince(array $queryRequest): void
     {
         $query = $this->provideFindBlogsByPostsSinceQuery(
@@ -598,9 +584,9 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Addresses Relation::HAS_MANY relations.
-     * @test
-     * @dataProvider distinctDataProvider
      */
+    #[DataProvider('distinctDataProvider')]
+    #[Test]
     public function distinctBlogRecordsAreFoundByPostsSince(array $queryRequest): void
     {
         $query = $this->provideFindBlogsByPostsSinceQuery(
@@ -625,9 +611,9 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Addresses Relation::HAS_AND_BELONGS_TO_MANY relations.
-     * @test
-     * @dataProvider distinctDataProvider
      */
+    #[DataProvider('distinctDataProvider')]
+    #[Test]
     public function distinctPersonEntitiesAreFoundByTagNameAreFiltered(array $queryRequest): void
     {
         $query = $this->provideFindPersonsByTagNameQuery('SharedTag');
@@ -643,9 +629,9 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Addresses Relation::HAS_AND_BELONGS_TO_MANY relations.
-     * @test
-     * @dataProvider distinctDataProvider
      */
+    #[DataProvider('distinctDataProvider')]
+    #[Test]
     public function distinctPersonRecordsAreFoundByTagNameAreFiltered(array $queryRequest): void
     {
         $query = $this->provideFindPersonsByTagNameQuery('SharedTag');
@@ -671,9 +657,9 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Addresses Relation::HAS_ONE, Relation::HAS_AND_BELONGS_TO_MANY relations.
-     * @test
-     * @dataProvider distinctDataProvider
      */
+    #[DataProvider('distinctDataProvider')]
+    #[Test]
     public function distinctPostEntitiesAreFoundByAuthorTagNameAreFiltered(array $queryRequest): void
     {
         $query = $this->provideFindPostsByAuthorTagName('SharedTag');
@@ -689,9 +675,9 @@ final class RelationTest extends FunctionalTestCase
 
     /**
      * Addresses Relation::HAS_ONE, Relation::HAS_AND_BELONGS_TO_MANY relations.
-     * @test
-     * @dataProvider distinctDataProvider
      */
+    #[DataProvider('distinctDataProvider')]
+    #[Test]
     public function distinctPostRecordsAreFoundByAuthorTagNameAreFiltered(array $queryRequest): void
     {
         $query = $this->provideFindPostsByAuthorTagName('SharedTag');
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/RepositoryTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/RepositoryTest.php
index 2e76913ffe45..1d34add8a1c2 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/RepositoryTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/RepositoryTest.php
@@ -17,6 +17,9 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Extbase\Persistence\QueryInterface;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Tests\BlogExample\Domain\Model\Post;
@@ -50,26 +53,20 @@ final class RepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider findByRespectsSingleCriteriaDataProvider
-     */
+    #[DataProvider('findByRespectsSingleCriteriaDataProvider')]
+    #[Test]
     public function findByRespectsSingleCriteria(array $criteria, int $expectedCount): void
     {
         self::assertCount($expectedCount, $this->get(PostRepository::class)->findBy($criteria));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findByRespectsMultipleCriteria(): void
     {
         self::assertCount(6, $this->get(PostRepository::class)->findBy(['blog' => 1, 'author' => 1]));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findByRespectsSingleOrderBy(): void
     {
         $posts = $this->get(PostRepository::class)->findBy(
@@ -90,9 +87,7 @@ final class RepositoryTest extends FunctionalTestCase
         ], $titles);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findByRespectsMultipleOrderBy(): void
     {
         $posts = $this->get(PostRepository::class)->findBy(
@@ -165,9 +160,7 @@ final class RepositoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findByRespectsLimit(): void
     {
         $posts = $this->get(PostRepository::class)->findBy(
@@ -195,9 +188,7 @@ final class RepositoryTest extends FunctionalTestCase
         ], $titles);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findByRespectsOffset(): void
     {
         $posts = $this->get(PostRepository::class)->findBy(
@@ -238,10 +229,8 @@ final class RepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider findOneByRespectsSingleCriteriaDataProvider
-     */
+    #[DataProvider('findOneByRespectsSingleCriteriaDataProvider')]
+    #[Test]
     public function findOneByRespectsSingleCriteria(array $criteria, int|null $expectedUid): void
     {
         /** @var Post|null $post */
@@ -249,19 +238,15 @@ final class RepositoryTest extends FunctionalTestCase
         self::assertSame($expectedUid, $post?->getUid());
     }
 
-    /**
-     * @test
-     * @group not-postgres
-     */
+    #[Group('not-postgres')]
+    #[Test]
     public function findOneByRespectsMultipleCriteria(): void
     {
         $post = $this->get(PostRepository::class)->findOneBy(['blog' => 1, 'author' => 1]);
         self::assertSame('Post4', $post?->getTitle());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findOneByRespectsOrderBy(): void
     {
         $post = $this->get(PostRepository::class)->findOneBy(
@@ -271,9 +256,7 @@ final class RepositoryTest extends FunctionalTestCase
         self::assertSame('Post9', $post?->getTitle());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function countRespectsSingleCriteria(): void
     {
         self::assertSame(
@@ -284,9 +267,7 @@ final class RepositoryTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function countRespectsMultipleCriteria(): void
     {
         self::assertSame(
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/TranslatedSiteContentTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/TranslatedSiteContentTest.php
index f7ee24e3d1f9..c434bf39bd2d 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/TranslatedSiteContentTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/TranslatedSiteContentTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
@@ -78,9 +80,8 @@ final class TranslatedSiteContentTest extends AbstractDataHandlerActionTestCase
     /**
      * For the default language all combination of language settings should give the same result,
      * regardless of TypoScript settings, if the requested language is "0" then no TypoScript settings apply.
-     *
-     * @test
      */
+    #[Test]
     public function onlyEnglishContentIsRenderedForDefaultLanguage(): void
     {
         $this->writeSiteConfiguration(
@@ -213,10 +214,8 @@ final class TranslatedSiteContentTest extends AbstractDataHandlerActionTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider danishDataProvider
-     */
+    #[DataProvider('danishDataProvider')]
+    #[Test]
     public function renderingOfDanishLanguage(string $fallbackType, array $visibleRecords): void
     {
         $this->writeSiteConfiguration(
@@ -435,11 +434,11 @@ final class TranslatedSiteContentTest extends AbstractDataHandlerActionTestCase
     /**
      * Page uid 89 is NOT translated to german
      *
-     * @test
-     * @dataProvider contentOnNonTranslatedPageDataProvider
      *
      * @param int $statusCode '200' or '404'
      */
+    #[DataProvider('contentOnNonTranslatedPageDataProvider')]
+    #[Test]
     public function contentOnNonTranslatedPageGerman(string $fallbackType, array $fallbackChain, array $visibleRecords, int $statusCode = 200): void
     {
         $this->writeSiteConfiguration(
@@ -555,10 +554,9 @@ final class TranslatedSiteContentTest extends AbstractDataHandlerActionTestCase
 
     /**
      * Page uid 89 is translated to to Polish, but not all CE are translated
-     *
-     * @test
-     * @dataProvider contentOnPartiallyTranslatedPageDataProvider
      */
+    #[DataProvider('contentOnPartiallyTranslatedPageDataProvider')]
+    #[Test]
     public function contentOnPartiallyTranslatedPage(string $fallbackType, array $fallbackChain, array $visibleHeaders): void
     {
         $this->writeSiteConfiguration(
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/TranslationTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/TranslationTest.php
index 5182e0e16c8f..b9e87124fabb 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/TranslationTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/TranslationTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\LanguageAspect;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
@@ -67,9 +69,8 @@ final class TranslationTest extends FunctionalTestCase
 
     /**
      * Tests if repository returns correct number of posts in the default language
-     *
-     * @test
      */
+    #[Test]
     public function countReturnsCorrectNumberOfPosts(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -83,9 +84,8 @@ final class TranslationTest extends FunctionalTestCase
 
     /**
      * Test for fetching records with disabled overlay
-     *
-     * @test
      */
+    #[Test]
     public function countReturnsCorrectNumberOfPostsInEnglishLanguage(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -97,9 +97,7 @@ final class TranslationTest extends FunctionalTestCase
         self::assertSame(2, $postCount);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function countReturnsCorrectNumberOfPostsInGreekLanguage(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -111,9 +109,7 @@ final class TranslationTest extends FunctionalTestCase
         self::assertSame(2, $postCount);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fetchingPostsReturnsEnglishPostsWithFallback(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -129,9 +125,7 @@ final class TranslationTest extends FunctionalTestCase
         self::assertSame('B EN:Post1', $posts[1]->getTitle());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fetchingPostsByInClauseReturnsDefaultPostsWithFallback(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -148,9 +142,8 @@ final class TranslationTest extends FunctionalTestCase
 
     /**
      * This tests shows overlays in action
-     *
-     * @test
      */
+    #[Test]
     public function fetchingPostsReturnsGreekPostsWithFallback(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -168,9 +161,8 @@ final class TranslationTest extends FunctionalTestCase
 
     /**
      * This tests shows overlay 'hideNonTranslated' in action
-     *
-     * @test
      */
+    #[Test]
     public function fetchingPostsReturnsGreekPostsWithHideNonTranslated(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -200,10 +192,8 @@ final class TranslationTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider fetchingTranslatedPostByUidDataProvider
-     * @test
-     */
+    #[DataProvider('fetchingTranslatedPostByUidDataProvider')]
+    #[Test]
     public function fetchingTranslatedPostByInClauseWithStrictLanguageSettings(array $input, array $expectedTitles): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -223,10 +213,8 @@ final class TranslationTest extends FunctionalTestCase
         // self::assertEqualsCanonicalizing($expectedTitles, array_map(static fn(Post $post): string => $post->getTitle(), $posts));
     }
 
-    /**
-     * @dataProvider fetchingTranslatedPostByUidDataProvider
-     * @test
-     */
+    #[DataProvider('fetchingTranslatedPostByUidDataProvider')]
+    #[Test]
     public function fetchingTranslatedPostByEqualsUidClauseWithStrictLanguageSettings(array $input, array $expectedTitles): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -250,9 +238,7 @@ final class TranslationTest extends FunctionalTestCase
         // self::assertEqualsCanonicalizing($expectedTitles, array_map(static fn(Post $post): string => $post->getTitle(), $posts));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function orderingByTitleRespectsEnglishTitles(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -271,9 +257,8 @@ final class TranslationTest extends FunctionalTestCase
     /**
      * This test shows that ordering by blog title works
      * however the default language blog title is used
-     *
-     * @test
      */
+    #[Test]
     public function orderingByBlogTitle(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -296,9 +281,8 @@ final class TranslationTest extends FunctionalTestCase
      * This test checks whether setIgnoreEnableFields(true) affects the query
      * It's expected that when ignoring enable fields, the hidden record is also returned.
      * This is related to https://forge.typo3.org/issues/68672
-     *
-     * @test
      */
+    #[Test]
     public function fetchingHiddenPostsWithIgnoreEnableField(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -318,9 +302,8 @@ final class TranslationTest extends FunctionalTestCase
     /**
      * This test checks whether setIgnoreEnableFields(true) affects translated record too.
      * It's expected that when ignoring enable fields, the hidden translated record is shown.
-     *
-     * @test
      */
+    #[Test]
     public function fetchingHiddenPostsReturnsHiddenOverlay(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -345,9 +328,8 @@ final class TranslationTest extends FunctionalTestCase
      * This is related to https://forge.typo3.org/issues/68672
      *
      * This tests documents current, buggy behaviour!
-     *
-     * @test
      */
+    #[Test]
     public function fetchingHiddenPostsReturnsHiddenOverlayOverlayEnabled(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -371,9 +353,8 @@ final class TranslationTest extends FunctionalTestCase
 
     /**
      * Test checking if we can query db records by translated fields
-     *
-     * @test
      */
+    #[Test]
     public function fetchingTranslatedPostByTitle(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -392,9 +373,8 @@ final class TranslationTest extends FunctionalTestCase
     /**
      * Test checking if we can query db records by value of the child object
      * Note that only child objects from language 0 are taken into account
-     *
-     * @test
      */
+    #[Test]
     public function fetchingTranslatedPostByBlogTitle(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -411,9 +391,7 @@ final class TranslationTest extends FunctionalTestCase
         self::assertSame('GR:Post11', $posts[1]->getTitle());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fetchingPostByTagName(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
@@ -429,9 +407,7 @@ final class TranslationTest extends FunctionalTestCase
         self::assertSame('Post1', $posts[0]->getTitle());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fetchingTranslatedPostByTagName(): void
     {
         $query = $this->get(PostRepository::class)->createQuery();
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/WorkspaceTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/WorkspaceTest.php
index 6b806ee2ef10..fe1f7c225725 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/WorkspaceTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/WorkspaceTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Persistence;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\UserAspect;
@@ -118,10 +120,8 @@ final class WorkspaceTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider contextDataProvider
-     */
+    #[DataProvider('contextDataProvider')]
+    #[Test]
     public function countReturnsCorrectNumberOfBlogs(string $context): void
     {
         if ($context === 'FE') {
@@ -138,10 +138,8 @@ final class WorkspaceTest extends FunctionalTestCase
         self::assertSame(6, $query->execute()->count());
     }
 
-    /**
-     * @test
-     * @dataProvider contextDataProvider
-     */
+    #[DataProvider('contextDataProvider')]
+    #[Test]
     public function fetchingHiddenBlogInWorkspace(string $context): void
     {
         // Set up Context for Workspace=1
@@ -186,10 +184,8 @@ final class WorkspaceTest extends FunctionalTestCase
         ], $foundItems);
     }
 
-    /**
-     * @test
-     * @dataProvider contextDataProvider
-     */
+    #[DataProvider('contextDataProvider')]
+    #[Test]
     public function fetchingAllBlogsReturnsCorrectNumberOfBlogs(string $context): void
     {
         if ($context === 'FE') {
@@ -215,10 +211,8 @@ final class WorkspaceTest extends FunctionalTestCase
         self::assertSame('WorkspaceOverlay Blog6Enabled', $lastBlog->getTitle());
     }
 
-    /**
-     * @test
-     * @dataProvider contextDataProvider
-     */
+    #[DataProvider('contextDataProvider')]
+    #[Test]
     public function fetchingBlogReturnsOverlaidWorkspaceVersionForRelations(string $context): void
     {
         if ($context === 'FE') {
@@ -240,9 +234,7 @@ final class WorkspaceTest extends FunctionalTestCase
         self::assertSame('WorkspaceOverlay Post3', $posts[2]->getTitle());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fetchingBlogReturnsManyToManyRelationsInLiveWorkspace(): void
     {
         // Simulate LIVE workspace -> 3 relations
@@ -257,9 +249,7 @@ final class WorkspaceTest extends FunctionalTestCase
         self::assertCount(3, $blog->getCategories());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fetchingBlogReturnsOverlaidWorkspaceVersionForManyToManyRelations(): void
     {
         $this->setupSubjectInFrontend();
diff --git a/typo3/sysext/extbase/Tests/Functional/Property/PropertyMapperTest.php b/typo3/sysext/extbase/Tests/Functional/Property/PropertyMapperTest.php
index eb58531e5ea3..427e3eb79028 100644
--- a/typo3/sysext/extbase/Tests/Functional/Property/PropertyMapperTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Property/PropertyMapperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Property;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
@@ -48,9 +49,7 @@ final class PropertyMapperTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertCreatesAPropertyMappingConfigurationIfNotGiven(): void
     {
         // This test just increases the test coverage
@@ -58,9 +57,7 @@ final class PropertyMapperTest extends FunctionalTestCase
             ->convert('string', 'string');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertReturnsNullIfDoMappingReturnsAnError(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -69,9 +66,7 @@ final class PropertyMapperTest extends FunctionalTestCase
         self::assertNotEmpty($propertyMapper->getMessages());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertThrowsATargetNotFoundException(): void
     {
         $this->expectException(TargetNotFoundException::class);
@@ -81,9 +76,7 @@ final class PropertyMapperTest extends FunctionalTestCase
         $propertyMapper->convert(9999, Blog::class);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertThrowsAnExceptionIfNoTypeConverterCanBeFoundForTheConversionOfSimpleTypes(): void
     {
         $this->expectException(\Exception::class);
@@ -94,18 +87,14 @@ final class PropertyMapperTest extends FunctionalTestCase
         $propertyMapper->convert(9999, 'boolean');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertInternallyConvertsANullSourceToAnEmptyString(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
         self::assertSame('', $propertyMapper->convert(null, 'string'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertThrowsAnExceptionIfTargetTypeIsANonExistingClass(): void
     {
         $this->expectException(\Exception::class);
@@ -116,9 +105,7 @@ final class PropertyMapperTest extends FunctionalTestCase
         $propertyMapper->convert(1, 'NonExistingClass');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertThrowsAnExceptionIfAtLeastTwoConvertersAreRegisteredThatHandleTheConversionToTheSameInterface(): void
     {
         $this->expectException(\Exception::class);
@@ -136,9 +123,7 @@ final class PropertyMapperTest extends FunctionalTestCase
         $propertyMapper->convert(1, get_class($counter));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function doMappingReturnsTheSourceIfItIsAlreadyTheDesiredTypeWithoutCallingAConverter(): void
     {
         $objectStorage = new ObjectStorage();
@@ -151,9 +136,7 @@ final class PropertyMapperTest extends FunctionalTestCase
         self::assertSame($objectStorage, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findTypeConverterReturnsTheConverterFromThePropertyMappingConfiguration(): void
     {
         $class = new class () extends IntegerConverter {
@@ -175,9 +158,7 @@ final class PropertyMapperTest extends FunctionalTestCase
         self::assertSame(1575648246, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function determineSourceTypeThrowsInvalidSourceExceptionForNonSupportedTypes(): void
     {
         $this->expectException(\Exception::class);
@@ -192,9 +173,7 @@ final class PropertyMapperTest extends FunctionalTestCase
         $propertyMapper->convert($generator, 'string');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findFirstEligibleTypeConverterInObjectHierarchyReturnsNullIfNoTypeConvertersExistForTheSourceType(): void
     {
         $this->expectException(\Exception::class);
@@ -205,27 +184,21 @@ final class PropertyMapperTest extends FunctionalTestCase
         self::assertNull($result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findFirstEligibleTypeConverterInObjectHierarchyFindsConverterFromStringToObject(): void
     {
         $result = $this->get(PropertyMapper::class)->convert('tigger', Cat::class);
         self::assertInstanceOf(Cat::class, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findFirstEligibleTypeConverterInObjectHierarchyReturnsConverterForParentClass(): void
     {
         $result = $this->get(PropertyMapper::class)->convert('fluffy', Dog::class);
         self::assertInstanceOf(Animal::class, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findFirstEligibleTypeConverterInObjectHierarchyReturnsConverterForInterfaces(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -234,9 +207,7 @@ final class PropertyMapperTest extends FunctionalTestCase
         self::assertSame([], $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function defaultPropertyMappingConfiguration(): void
     {
         $source = [
@@ -258,9 +229,7 @@ final class PropertyMapperTest extends FunctionalTestCase
         self::assertSame('black', $result->getColor());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function skipPropertiesConfiguration(): void
     {
         $source = [
@@ -282,9 +251,7 @@ final class PropertyMapperTest extends FunctionalTestCase
         self::assertNull($result->getColor());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function allowAllPropertiesExceptConfiguration(): void
     {
         $this->expectException(\Exception::class);
@@ -306,9 +273,7 @@ final class PropertyMapperTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function allowAllPropertiesExceptWithSkipUnknownPropertiesConfiguration(): void
     {
         $source = [
diff --git a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/ArrayConverterTest.php b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/ArrayConverterTest.php
index 2881d912f105..8055b7e3d6ca 100644
--- a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/ArrayConverterTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/ArrayConverterTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Property\TypeConverter;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Extbase\Property\PropertyMapper;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -24,9 +25,7 @@ final class ArrayConverterTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertToArray(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
diff --git a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/BooleanConverterTest.php b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/BooleanConverterTest.php
index 59c279d2ba87..aa2f839c31b4 100644
--- a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/BooleanConverterTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/BooleanConverterTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Property\TypeConverter;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Extbase\Property\PropertyMapper;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -24,9 +25,7 @@ final class BooleanConverterTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertToBoolean(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
diff --git a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/DateTimeConverterTest.php b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/DateTimeConverterTest.php
index c96ed7826108..a9b7df0bf057 100644
--- a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/DateTimeConverterTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/DateTimeConverterTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Property\TypeConverter;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Extbase\Property\Exception;
 use TYPO3\CMS\Extbase\Property\PropertyMapper;
 use TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration;
@@ -27,9 +28,7 @@ final class DateTimeConverterTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertFromReturnsAnErrorWhenConvertingIntegersToDateTime(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -44,9 +43,7 @@ final class DateTimeConverterTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertFromReturnsNullIfSourceIsAnEmptyString(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -57,9 +54,7 @@ final class DateTimeConverterTest extends FunctionalTestCase
         self::assertFalse($propertyMapper->getMessages()->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertDefaultDateFormatString(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -70,9 +65,7 @@ final class DateTimeConverterTest extends FunctionalTestCase
         self::assertSame(1575745622, $dateTime->getTimestamp());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertCustomDateFormatString(): void
     {
         $propertyMapperConfiguration = new PropertyMappingConfiguration();
@@ -94,9 +87,7 @@ final class DateTimeConverterTest extends FunctionalTestCase
         self::assertSame(1575746145, $dateTime->getTimestamp());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertThrowsInvalidPropertyMappingConfigurationExceptionIfDateFormatIsNotAString(): void
     {
         $this->expectException(Exception::class);
@@ -119,9 +110,7 @@ final class DateTimeConverterTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertWithArraySourceWithStringDate(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -137,9 +126,7 @@ final class DateTimeConverterTest extends FunctionalTestCase
         self::assertSame(1575745622, $dateTime->getTimestamp());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertWithArraySourceWithIntegerDate(): void
     {
         $propertyMapperConfiguration = new PropertyMappingConfiguration();
@@ -163,9 +150,7 @@ final class DateTimeConverterTest extends FunctionalTestCase
         self::assertSame(1575745622, $dateTime->getTimestamp());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertWithArraySourceWithDayMonthAndYearSet(): void
     {
         $propertyMapperConfiguration = new PropertyMappingConfiguration();
@@ -191,9 +176,7 @@ final class DateTimeConverterTest extends FunctionalTestCase
         self::assertSame('2019-12-12', $dateTime->format('Y-m-d'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertWithArraySourceWithDayMonthYearAndDateFormatSet(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -212,9 +195,7 @@ final class DateTimeConverterTest extends FunctionalTestCase
         self::assertSame('2019-12-12', $dateTime->format('Y-m-d'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertWithArraySourceWithDayMonthYearHourMinuteAndSecondSet(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -237,9 +218,7 @@ final class DateTimeConverterTest extends FunctionalTestCase
         self::assertSame(1576163154, $dateTime->getTimestamp());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertWithArraySourceWithDayMonthYearAndTimeZoneSetWithDateThatIncludesTimezone(): void
     {
         // Hint:
@@ -261,9 +240,7 @@ final class DateTimeConverterTest extends FunctionalTestCase
         self::assertSame(1575745622, $dateTime->getTimestamp());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertWithArraySourceWithDayMonthYearAndTimeZoneSet(): void
     {
         $propertyMapperConfiguration = new PropertyMappingConfiguration();
@@ -289,9 +266,7 @@ final class DateTimeConverterTest extends FunctionalTestCase
         self::assertSame(1575785222, $dateTime->getTimestamp());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertFromReturnsErrorIfSourceIsAnArrayAndEitherDayMonthOrYearAreLowerThanOne(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -314,9 +289,7 @@ final class DateTimeConverterTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertFromThrowsTypeConverterExceptionIfSourceIsAnInvalidArraySource(): void
     {
         $this->expectException(Exception::class);
@@ -326,9 +299,7 @@ final class DateTimeConverterTest extends FunctionalTestCase
         $this->get(PropertyMapper::class)->convert([], \DateTime::class);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertFromThrowsTypeConverterExceptionIfGivenDateTimeZoneIsInvalid(): void
     {
         $this->expectException(Exception::class);
diff --git a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/EnumConverterTest.php b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/EnumConverterTest.php
index 032fa2613a79..fdcbf95766bc 100644
--- a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/EnumConverterTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/EnumConverterTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Property\TypeConverter;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Extbase\Property\PropertyMapper;
 use TYPO3\CMS\Extbase\Tests\Functional\Property\Fixtures\IntegerBackedEnum;
 use TYPO3\CMS\Extbase\Tests\Functional\Property\Fixtures\StringBackedEnum;
@@ -27,10 +29,8 @@ final class EnumConverterTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     * @dataProvider convertEnumDataProvider
-     */
+    #[DataProvider('convertEnumDataProvider')]
+    #[Test]
     public function convertEnum(string $enumClass, float|int|string $input, ?object $expected): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
diff --git a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/FileConverterTest.php b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/FileConverterTest.php
index 9a7a75ed2f7a..01558d346211 100644
--- a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/FileConverterTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/FileConverterTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Property\TypeConverter;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Extbase\Domain\Model\File;
 use TYPO3\CMS\Extbase\Property\PropertyMapper;
@@ -24,9 +25,7 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class FileConverterTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function convertReturnsFileObject(): void
     {
         $GLOBALS['BE_USER'] = new BackendUserAuthentication();
diff --git a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/FloatConverterTest.php b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/FloatConverterTest.php
index e8688d38dd86..498921950a81 100644
--- a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/FloatConverterTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/FloatConverterTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Property\TypeConverter;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Extbase\Property\PropertyMapper;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -24,9 +25,7 @@ final class FloatConverterTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertToFloat(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
diff --git a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/IntegerConverterTest.php b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/IntegerConverterTest.php
index 2e2575d0db48..832cfb6fedf3 100644
--- a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/IntegerConverterTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/IntegerConverterTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Property\TypeConverter;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Extbase\Property\PropertyMapper;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -24,9 +25,7 @@ final class IntegerConverterTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertToInteger(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
diff --git a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/ObjectConverterTest.php b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/ObjectConverterTest.php
index e3efe0878029..cd3a3849cf1f 100644
--- a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/ObjectConverterTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/ObjectConverterTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Property\TypeConverter;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
 use TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface;
 use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
@@ -32,9 +33,7 @@ final class ObjectConverterTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertToObject(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -58,9 +57,7 @@ final class ObjectConverterTest extends FunctionalTestCase
         self::assertSame('John Doe', $object->_getProperty('name'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertToObjectViaTypeInArray(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -84,9 +81,7 @@ final class ObjectConverterTest extends FunctionalTestCase
         self::assertSame('John Doe', $object->getName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTypeOfChildPropertyReturnsTypeDefinedByPropertyMappingConfiguration(): void
     {
         $class = new class () {
@@ -114,9 +109,7 @@ final class ObjectConverterTest extends FunctionalTestCase
         self::assertSame('foo', $result->name);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTypeOfChildPropertyReturnsTypeDefinedByConstructorArgument(): void
     {
         $class = new class ('') {
@@ -144,9 +137,7 @@ final class ObjectConverterTest extends FunctionalTestCase
         self::assertSame('foo', $result->getName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function collectionTypesAreConsideredInMapping(): void
     {
         $class = new class () {
@@ -189,9 +180,7 @@ final class ObjectConverterTest extends FunctionalTestCase
         self::assertSame('Lion', $result->getCollection()->current()->getName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTypeOfChildPropertyReturnsTypeDefinedBySetter(): void
     {
         $class = new class () {
@@ -219,9 +208,7 @@ final class ObjectConverterTest extends FunctionalTestCase
         self::assertSame('foo', $result->getName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTypeOfChildPropertyThrowsInvalidTargetExceptionIfPropertyIsNotAccessible(): void
     {
         $class = new class () {};
@@ -244,9 +231,7 @@ final class ObjectConverterTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTypeOfChildPropertyThrowsInvalidTargetExceptionIfPropertyTypeCannotBeDerivedFromNonExistingConstructorArgument(): void
     {
         $class = new class () {
@@ -271,9 +256,7 @@ final class ObjectConverterTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTypeOfChildPropertyThrowsInvalidTargetExceptionIfPropertyTypeCannotBeDerivedFromExistingConstructorArgument(): void
     {
         $class = new class () {
@@ -298,9 +281,7 @@ final class ObjectConverterTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTypeOfChildPropertyThrowsInvalidTargetExceptionIfPropertySetterDoesNotDefineAType(): void
     {
         $this->expectException(Exception::class);
@@ -322,9 +303,7 @@ final class ObjectConverterTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertFromThrowsInvalidTargetExceptionIfPropertiesCannotBeSet(): void
     {
         $this->expectException(Exception::class);
@@ -354,9 +333,7 @@ final class ObjectConverterTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function buildObjectUsesDefaultValueOfOptionalConstructorArguments(): void
     {
         $class = new class ('', '') {
@@ -378,9 +355,7 @@ final class ObjectConverterTest extends FunctionalTestCase
         self::assertSame('red', $result->color);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function buildObjectThrowsInvalidTargetExceptionIfMandatoryConstructorArgumentIsMissing(): void
     {
         $this->expectException(Exception::class);
@@ -403,9 +378,7 @@ final class ObjectConverterTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTargetTypeForSourceThrowsInvalidPropertyMappingConfigurationExceptionIfTargetTypeOverridingIsNotAllowed(): void
     {
         $this->expectException(Exception::class);
@@ -420,9 +393,7 @@ final class ObjectConverterTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTargetTypeForSourceThrowsInvalidDataTypeExceptionIfOverriddenTargetTypeIsNotASubtypeOfOriginalTargetType(): void
     {
         $this->expectException(Exception::class);
@@ -446,9 +417,7 @@ final class ObjectConverterTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertWithRegisteredSubclassReturnsInstanceOfRegisteredSubclass(): void
     {
         // XCLASS the animal class
diff --git a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/ObjectStorageConverterTest.php b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/ObjectStorageConverterTest.php
index 8050e339412d..e7c1ea072ecc 100644
--- a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/ObjectStorageConverterTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/ObjectStorageConverterTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Property\TypeConverter;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
 use TYPO3\CMS\Extbase\Property\PropertyMapper;
 use TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration;
@@ -27,9 +28,7 @@ final class ObjectStorageConverterTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertReturnsObjectStorage(): void
     {
         $propertyMapperConfiguration = new PropertyMappingConfiguration();
@@ -54,9 +53,7 @@ final class ObjectStorageConverterTest extends FunctionalTestCase
         self::assertSame('black', $cat->getColor());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getSourceChildPropertiesToBeConvertedReturnsEmptyArrayIfSourceIsAString(): void
     {
         $propertyMapperConfiguration = new PropertyMappingConfiguration();
diff --git a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/PersistentObjectConverterTest.php b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/PersistentObjectConverterTest.php
index 80b5070feb4d..3186aaaaf622 100644
--- a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/PersistentObjectConverterTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/PersistentObjectConverterTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Property\TypeConverter;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Beuser\Domain\Model\BackendUser;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -41,9 +42,7 @@ final class PersistentObjectConverterTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function converterReturnsNullWithEmptyStringsOrIntegers(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -52,9 +51,7 @@ final class PersistentObjectConverterTest extends FunctionalTestCase
         self::assertNull($propertyMapper->convert('', BackendUser::class));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fetchObjectFromPersistenceThrowsInvalidSourceExceptionIfSourceIANonNumericString(): void
     {
         $this->expectException(Exception::class);
@@ -64,9 +61,7 @@ final class PersistentObjectConverterTest extends FunctionalTestCase
         $this->get(PropertyMapper::class)->convert('foo', BackendUser::class);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fetchObjectFromPersistenceThrowsTargetNotFoundExceptionIfObjectIsNotToBeFoundInThePersistence(): void
     {
         $this->expectException(TargetNotFoundException::class);
@@ -76,9 +71,7 @@ final class PersistentObjectConverterTest extends FunctionalTestCase
         $this->get(PropertyMapper::class)->convert(2, BackendUser::class);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function converterFetchesObjectFromPersistenceIfSourceIsAnInteger(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -89,9 +82,7 @@ final class PersistentObjectConverterTest extends FunctionalTestCase
         self::assertSame(1, $backendUser->getUid());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function converterFetchesObjectFromPersistenceIfSourceIsANumericString(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -102,9 +93,7 @@ final class PersistentObjectConverterTest extends FunctionalTestCase
         self::assertSame(1, $backendUser->getUid());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function converterBuildsEmptyObjectIfSourceIsAnEmptyArray(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -115,9 +104,7 @@ final class PersistentObjectConverterTest extends FunctionalTestCase
         self::assertNull($backendUser->getUid());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function converterFetchesObjectFromPersistenceIfSourceIsAnArrayWithIdentityKey(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -128,9 +115,7 @@ final class PersistentObjectConverterTest extends FunctionalTestCase
         self::assertSame(1, $backendUser->getUid());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function handleArrayDataThrowsInvalidPropertyMappingConfigurationExceptionIfCreationOfObjectsIsNotAllowed(): void
     {
         $this->expectException(Exception::class);
@@ -151,9 +136,7 @@ final class PersistentObjectConverterTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function converterRespectsAndSetsProperties(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
@@ -165,9 +148,7 @@ final class PersistentObjectConverterTest extends FunctionalTestCase
         self::assertSame('johndoe', $backendUser->getUserName());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTypeOfChildPropertyThrowsInvalidTargetExceptionIfPropertyIsNonExistant(): void
     {
         $this->expectException(Exception::class);
@@ -177,9 +158,7 @@ final class PersistentObjectConverterTest extends FunctionalTestCase
         $this->get(PropertyMapper::class)->convert(['nonExistant' => 'johndoe'], BackendUser::class);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertFromThrowsInvalidTargetExceptionIfSourceContainsANonSettableProperty(): void
     {
         $this->expectException(Exception::class);
diff --git a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/StringConverterTest.php b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/StringConverterTest.php
index ae85a536cf9b..2299860e6d47 100644
--- a/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/StringConverterTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Property/TypeConverter/StringConverterTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Property\TypeConverter;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Extbase\Property\PropertyMapper;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -24,9 +25,7 @@ final class StringConverterTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function convertToString(): void
     {
         $propertyMapper = $this->get(PropertyMapper::class);
diff --git a/typo3/sysext/extbase/Tests/Functional/Service/ExtensionServiceTest.php b/typo3/sysext/extbase/Tests/Functional/Service/ExtensionServiceTest.php
index 41c6d7c18f93..a416f0449a4e 100644
--- a/typo3/sysext/extbase/Tests/Functional/Service/ExtensionServiceTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Service/ExtensionServiceTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Service;
 
+use PHPUnit\Framework\Attributes\Test;
 use PHPUnit\Framework\MockObject\MockObject;
 use Psr\Container\ContainerInterface;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
@@ -44,9 +45,7 @@ final class ExtensionServiceTest extends FunctionalTestCase
         $this->extensionService = new ExtensionService();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPluginNameByActionDetectsPluginNameFromGlobalExtensionConfigurationArray(): void
     {
         $this->frontendConfigurationManager->method('getConfiguration')->with(self::anything())->willReturn([]);
@@ -59,9 +58,7 @@ final class ExtensionServiceTest extends FunctionalTestCase
         self::assertSame('Blogs', $pluginName);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTargetPidByPluginSignatureDeterminesTheTargetPidIfDefaultPidIsAuto(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Service/Fixtures/tt_content_with_single_plugin.csv');
@@ -76,9 +73,7 @@ final class ExtensionServiceTest extends FunctionalTestCase
         self::assertEquals($expectedResult, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTargetPidByPluginSignatureReturnsNullIfTargetPidCouldNotBeDetermined(): void
     {
         $this->frontendConfigurationManager->method('getConfiguration')->with(self::anything())->willReturn(['view' => ['defaultPid' => 'auto']]);
@@ -90,9 +85,7 @@ final class ExtensionServiceTest extends FunctionalTestCase
         self::assertNull($result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTargetPidByPluginSignatureThrowsExceptionIfMoreThanOneTargetPidsWereFound(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Service/Fixtures/tt_content_with_two_plugins.csv');
diff --git a/typo3/sysext/extbase/Tests/Functional/Utility/LocalizationUtilityTest.php b/typo3/sysext/extbase/Tests/Functional/Utility/LocalizationUtilityTest.php
index 4252bc1a07ea..05d3ed4de8f9 100644
--- a/typo3/sysext/extbase/Tests/Functional/Utility/LocalizationUtilityTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Utility/LocalizationUtilityTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Utility;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -29,9 +31,7 @@ final class LocalizationUtilityTest extends FunctionalTestCase
 {
     protected array $testExtensionsToLoad = ['typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/label_test'];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function implodeTypoScriptLabelArrayWorks(): void
     {
         $reflectionClass = new \ReflectionClass(LocalizationUtility::class);
@@ -59,17 +59,13 @@ final class LocalizationUtilityTest extends FunctionalTestCase
         self::assertSame($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateForEmptyStringKeyReturnsNull(): void
     {
         self::assertNull(LocalizationUtility::translate('', 'extbase'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateForEmptyStringKeyWithArgumentsReturnsNull(): void
     {
         self::assertNull(LocalizationUtility::translate('', 'extbase', ['argument']));
@@ -98,10 +94,8 @@ final class LocalizationUtilityTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider translateDataProvider
-     * @test
-     */
+    #[DataProvider('translateDataProvider')]
+    #[Test]
     public function translateTestWithBackendUserLanguage(string $key, string $languageKey, string $expected, array $altLanguageKeys = [], array $arguments = null): void
     {
         // No TypoScript overrides
@@ -117,10 +111,8 @@ final class LocalizationUtilityTest extends FunctionalTestCase
         self::assertSame($expected, LocalizationUtility::translate($key, 'label_test', $arguments, alternativeLanguageKeys: $altLanguageKeys));
     }
 
-    /**
-     * @dataProvider translateDataProvider
-     * @test
-     */
+    #[DataProvider('translateDataProvider')]
+    #[Test]
     public function translateTestWithExplicitLanguageParameters(
         string $key,
         string $languageKey,
@@ -141,9 +133,8 @@ final class LocalizationUtilityTest extends FunctionalTestCase
 
     /**
      * Tests whether labels from XLF are overwritten by TypoScript labels
-     *
-     * @test
      */
+    #[Test]
     public function loadTypoScriptLabels(): void
     {
         $GLOBALS['TYPO3_REQUEST'] = new ServerRequest();
@@ -181,9 +172,7 @@ final class LocalizationUtilityTest extends FunctionalTestCase
         self::assertSame('key3.subkey2.subsubkey value from TypoScript', LocalizationUtility::translate('key3.subkey2.subsubkey', 'label_test', languageKey: 'da'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function clearLabelWithTypoScript(): void
     {
         $GLOBALS['TYPO3_REQUEST'] = new ServerRequest();
@@ -209,9 +198,7 @@ final class LocalizationUtilityTest extends FunctionalTestCase
         self::assertSame('', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateThrowsExceptionWithEmptyExtensionNameIfKeyIsNotPrefixedWithLLL(): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -219,9 +206,7 @@ final class LocalizationUtilityTest extends FunctionalTestCase
         LocalizationUtility::translate('foo/bar', '');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateWillReturnLabelsFromTsEvenIfNoXlfFileExists(): void
     {
         $GLOBALS['TYPO3_REQUEST'] = new ServerRequest();
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/AlphanumericValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/AlphanumericValidatorTest.php
index e2b7329cdf32..5b132103274d 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/AlphanumericValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/AlphanumericValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -33,9 +34,7 @@ final class AlphanumericValidatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function alphanumericValidatorShouldReturnNoErrorsForAnAlphanumericString(): void
     {
         $subject = new AlphanumericValidator();
@@ -43,9 +42,7 @@ final class AlphanumericValidatorTest extends FunctionalTestCase
         self::assertFalse($subject->validate('12ssDF34daweidf')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function alphanumericValidatorReturnsErrorsForAStringWithSpecialCharacters(): void
     {
         $subject = new AlphanumericValidator();
@@ -53,9 +50,7 @@ final class AlphanumericValidatorTest extends FunctionalTestCase
         self::assertTrue($subject->validate('adsf%&/$jklsfdö')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function alphanumericValidatorCreatesTheCorrectErrorForAnInvalidSubject(): void
     {
         $subject = new AlphanumericValidator();
@@ -63,9 +58,7 @@ final class AlphanumericValidatorTest extends FunctionalTestCase
         self::assertCount(1, $subject->validate('adsf%&/$jklsfdö')->getErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function alphanumericValidatorShouldReturnNoErrorsForAnAlphanumericUnicodeString(): void
     {
         $subject = new AlphanumericValidator();
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/BooleanValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/BooleanValidatorTest.php
index c259ef264602..1d0d9bb76ea6 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/BooleanValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/BooleanValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -33,9 +34,7 @@ final class BooleanValidatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function booleanValidatorReturnsNoErrorForAFalseStringExpectation(): void
     {
         $options = ['is' => 'false'];
@@ -44,9 +43,7 @@ final class BooleanValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate(false)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function booleanValidatorReturnsNoErrorForATrueStringExpectation(): void
     {
         $options = ['is' => 'true'];
@@ -55,9 +52,7 @@ final class BooleanValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate(true)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function booleanValidatorReturnsNoErrorForATrueExpectation(): void
     {
         $options = ['is' => true];
@@ -66,9 +61,7 @@ final class BooleanValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate(true)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function booleanValidatorReturnsNoErrorForAFalseExpectation(): void
     {
         $options = ['is' => false];
@@ -77,9 +70,7 @@ final class BooleanValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate(false)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function booleanValidatorReturnsErrorForTrueWhenFalseExpected(): void
     {
         $options = ['is' => false];
@@ -88,9 +79,7 @@ final class BooleanValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate(true)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function booleanValidatorReturnsErrorForFalseWhenTrueExpected(): void
     {
         $options = ['is' => true];
@@ -99,9 +88,7 @@ final class BooleanValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate(false)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function booleanValidatorReturnsErrorForAString(): void
     {
         $options = ['is' => true];
@@ -110,9 +97,7 @@ final class BooleanValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate('a string')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function booleanValidatorReturnsTrueIfNoParameterIsGiven(): void
     {
         $options = [];
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/CollectionValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/CollectionValidatorTest.php
index 59506a2d278f..0cab77ac621e 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/CollectionValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/CollectionValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -42,9 +43,7 @@ final class CollectionValidatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function collectionValidatorReturnsNoErrorsForANullValue(): void
     {
         $subject = $this->get(CollectionValidator::class);
@@ -52,9 +51,7 @@ final class CollectionValidatorTest extends FunctionalTestCase
         self::assertFalse($subject->validate(null)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function collectionValidatorFailsForAValueNotBeingACollection(): void
     {
         $subject = $this->get(CollectionValidator::class);
@@ -62,9 +59,7 @@ final class CollectionValidatorTest extends FunctionalTestCase
         self::assertTrue($subject->validate(new \stdClass())->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function collectionValidatorValidatesEveryElementOfACollectionWithTheGivenElementValidator(): void
     {
         $mockValidatorResolver = $this->getAccessibleMock(
@@ -94,9 +89,7 @@ final class CollectionValidatorTest extends FunctionalTestCase
         self::assertCount(2, $result->getFlattenedErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function collectionValidatorValidatesNestedObjectStructuresWithoutEndlessLooping(): void
     {
         $A = new class () {
@@ -139,9 +132,7 @@ final class CollectionValidatorTest extends FunctionalTestCase
         self::assertEquals(1221560494, $result['b.0'][0]->getCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function collectionValidatorCallsCollectionElementValidatorWhenValidatingObjectStorages(): void
     {
         $entity = new Entity('Foo');
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/ConjunctionValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/ConjunctionValidatorTest.php
index 0af997ea8d3f..6b078990dbd4 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/ConjunctionValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/ConjunctionValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Extbase\Error\Error;
 use TYPO3\CMS\Extbase\Error\Result;
@@ -33,9 +34,7 @@ final class ConjunctionValidatorTest extends FunctionalTestCase
         $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->create('default');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addingValidatorsToAJunctionValidatorWorks(): void
     {
         $conjunctionValidator = new ConjunctionValidator();
@@ -45,9 +44,7 @@ final class ConjunctionValidatorTest extends FunctionalTestCase
         self::assertTrue($conjunctionValidator->getValidators()->contains($mockValidator));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function allValidatorsInTheConjunctionAreCalledEvenIfOneReturnsError(): void
     {
         $validatorConjunction = new ConjunctionValidator();
@@ -72,9 +69,7 @@ final class ConjunctionValidatorTest extends FunctionalTestCase
         $validatorConjunction->validate('some subject');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validatorConjunctionReturnsNoErrorsIfAllJunctionedValidatorsReturnNoErrors(): void
     {
         $validatorConjunction = new ConjunctionValidator();
@@ -92,9 +87,7 @@ final class ConjunctionValidatorTest extends FunctionalTestCase
         self::assertFalse($validatorConjunction->validate('some subject')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validatorConjunctionReturnsErrorsIfOneValidatorReturnsErrors(): void
     {
         $validatorConjunction = new ConjunctionValidator();
@@ -109,9 +102,7 @@ final class ConjunctionValidatorTest extends FunctionalTestCase
         self::assertTrue($validatorConjunction->validate('some subject')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removingAValidatorOfTheValidatorConjunctionWorks(): void
     {
         $validatorConjunction = new ConjunctionValidator();
@@ -129,9 +120,7 @@ final class ConjunctionValidatorTest extends FunctionalTestCase
         self::assertTrue($validatorConjunction->getValidators()->contains($validator2));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removingANotExistingValidatorIndexThrowsException(): void
     {
         $this->expectException(NoSuchValidatorException::class);
@@ -144,9 +133,7 @@ final class ConjunctionValidatorTest extends FunctionalTestCase
         $validatorConjunction->removeValidator($validator);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function countReturnsTheNumberOfValidatorsContainedInTheConjunction(): void
     {
         $validatorConjunction = new ConjunctionValidator();
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/DateTimeValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/DateTimeValidatorTest.php
index 6c13c3b42467..e659d28fb361 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/DateTimeValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/DateTimeValidatorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -51,10 +53,8 @@ final class DateTimeValidatorTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider acceptsDateTimeValuesDataProvider
-     */
+    #[DataProvider('acceptsDateTimeValuesDataProvider')]
+    #[Test]
     public function acceptsDateTimeValues($value): void
     {
         $validator = new DateTimeValidator();
@@ -62,9 +62,7 @@ final class DateTimeValidatorTest extends FunctionalTestCase
         self::assertFalse($result->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function addsErrorForInvalidValue(): void
     {
         $validator = new DateTimeValidator();
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/EmailAddressValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/EmailAddressValidatorTest.php
index 8ffc4b0f5334..19006ca0a727 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/EmailAddressValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/EmailAddressValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -33,9 +34,7 @@ final class EmailAddressValidatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function emailAddressValidatorReturnsNoErrorsForAValidEmailAddress(): void
     {
         $subject = new EmailAddressValidator();
@@ -43,9 +42,7 @@ final class EmailAddressValidatorTest extends FunctionalTestCase
         self::assertFalse($subject->validate('valid.email@example.com')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function emailAddressValidatorReturnsFalseForAnInvalidEmailAddress(): void
     {
         $subject = new EmailAddressValidator();
@@ -53,9 +50,7 @@ final class EmailAddressValidatorTest extends FunctionalTestCase
         self::assertTrue($subject->validate('@typo3.org')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function emailAddressValidatorReturnsFalseForNonStringAddress(): void
     {
         $subject = new EmailAddressValidator();
@@ -63,9 +58,7 @@ final class EmailAddressValidatorTest extends FunctionalTestCase
         self::assertTrue($subject->validate(123)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function emailValidatorCreatesTheCorrectErrorForAnInvalidEmailAddress(): void
     {
         $subject = new EmailAddressValidator();
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/FloatValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/FloatValidatorTest.php
index d76886ddd3a5..7a7ba8b0467b 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/FloatValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/FloatValidatorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -45,10 +47,8 @@ final class FloatValidatorTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider validFloats
-     */
+    #[DataProvider('validFloats')]
+    #[Test]
     public function floatValidatorReturnsNoErrorsForAValidFloat(float|string $float): void
     {
         $validator = new FloatValidator();
@@ -65,10 +65,8 @@ final class FloatValidatorTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider invalidFloats
-     */
+    #[DataProvider('invalidFloats')]
+    #[Test]
     public function floatValidatorReturnsErrorForAnInvalidFloat(int|string $float): void
     {
         $validator = new FloatValidator();
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/IntegerValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/IntegerValidatorTest.php
index 7accc4dbba60..3825b30fb5b5 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/IntegerValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/IntegerValidatorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -46,10 +48,8 @@ final class IntegerValidatorTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider validIntegers
-     */
+    #[DataProvider('validIntegers')]
+    #[Test]
     public function integerValidatorReturnsNoErrorsForAValidInteger(int|string $integer): void
     {
         $validator = new IntegerValidator();
@@ -69,10 +69,8 @@ final class IntegerValidatorTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider invalidIntegers
-     */
+    #[DataProvider('invalidIntegers')]
+    #[Test]
     public function integerValidatorReturnsErrorForAnInvalidInteger(float|string $invalidInteger): void
     {
         $validator = new IntegerValidator();
@@ -80,9 +78,7 @@ final class IntegerValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate($invalidInteger)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function integerValidatorCreatesTheCorrectErrorForAnInvalidSubject(): void
     {
         $validator = new IntegerValidator();
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/NotEmptyValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/NotEmptyValidatorTest.php
index 3d3623be85aa..724200787fb9 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/NotEmptyValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/NotEmptyValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -33,9 +34,7 @@ final class NotEmptyValidatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notEmptyValidatorReturnsNoErrorForASimpleString(): void
     {
         $validator = new NotEmptyValidator();
@@ -43,9 +42,7 @@ final class NotEmptyValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate('a not empty string')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notEmptyValidatorReturnsErrorForAnEmptyString(): void
     {
         $validator = new NotEmptyValidator();
@@ -53,9 +50,7 @@ final class NotEmptyValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate('')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notEmptyValidatorReturnsErrorForANullValue(): void
     {
         $validator = new NotEmptyValidator();
@@ -63,9 +58,7 @@ final class NotEmptyValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate(null)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notEmptyValidatorCreatesTheCorrectErrorForAnEmptySubject(): void
     {
         $validator = new NotEmptyValidator();
@@ -73,9 +66,7 @@ final class NotEmptyValidatorTest extends FunctionalTestCase
         self::assertCount(1, $validator->validate('')->getErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notEmptyValidatorCreatesTheCorrectErrorForANullValue(): void
     {
         $validator = new NotEmptyValidator();
@@ -83,9 +74,7 @@ final class NotEmptyValidatorTest extends FunctionalTestCase
         self::assertCount(1, $validator->validate(null)->getErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notEmptyValidatorWorksForEmptyArrays(): void
     {
         $validator = new NotEmptyValidator();
@@ -94,9 +83,7 @@ final class NotEmptyValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate([1 => 2])->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notEmptyValidatorWorksForEmptyCountableObjects(): void
     {
         $validator = new NotEmptyValidator();
@@ -104,9 +91,7 @@ final class NotEmptyValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate(new \SplObjectStorage())->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function notEmptyValidatorWorksForNotEmptyCountableObjects(): void
     {
         $countableObject = new \SplObjectStorage();
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/NumberRangeValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/NumberRangeValidatorTest.php
index 1fa7570a730d..c3ad5ba9c18e 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/NumberRangeValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/NumberRangeValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -33,9 +34,7 @@ final class NumberRangeValidatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function numberRangeValidatorReturnsNoErrorForASimpleIntegerInRange(): void
     {
         $options = ['minimum' => 0, 'maximum' => 1000];
@@ -44,9 +43,7 @@ final class NumberRangeValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate(10.5)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function numberRangeValidatorReturnsErrorForANumberOutOfRange(): void
     {
         $options = ['minimum' => 0, 'maximum' => 1000];
@@ -55,9 +52,7 @@ final class NumberRangeValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate(1000.1)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function numberRangeValidatorReturnsNoErrorForANumberInReversedRange(): void
     {
         $options = ['minimum' => 1000, 'maximum' => 0];
@@ -66,9 +61,7 @@ final class NumberRangeValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate(100)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function numberRangeValidatorReturnsErrorForAString(): void
     {
         $options = ['minimum' => 0, 'maximum' => 1000];
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/NumberValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/NumberValidatorTest.php
index 757b72058efe..aa2b4f97fef6 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/NumberValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/NumberValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -35,9 +36,7 @@ final class NumberValidatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function numberValidatorReturnsTrueForASimpleInteger(): void
     {
         $subject = new NumberValidator();
@@ -45,9 +44,7 @@ final class NumberValidatorTest extends FunctionalTestCase
         self::assertFalse($subject->validate(1029437)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function numberValidatorReturnsFalseForAString(): void
     {
         $subject = new NumberValidator();
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/RegularExpressionValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/RegularExpressionValidatorTest.php
index e7bd02a20933..ec6e411e5ded 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/RegularExpressionValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/RegularExpressionValidatorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -34,9 +36,7 @@ final class RegularExpressionValidatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function regularExpressionValidatorMatchesABasicExpressionCorrectly(): void
     {
         $options = ['regularExpression' => '/^simple[0-9]expression$/'];
@@ -46,9 +46,7 @@ final class RegularExpressionValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate('simple1expressions')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function regularExpressionValidatorCreatesTheCorrectErrorIfTheExpressionDidNotMatch(): void
     {
         $options = ['regularExpression' => '/^simple[0-9]expression$/'];
@@ -59,9 +57,7 @@ final class RegularExpressionValidatorTest extends FunctionalTestCase
         self::assertEquals([new Error('The given subject did not match the pattern.', 1221565130)], $errors);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function customErrorMessageIsRespected(): void
     {
         $options = [
@@ -94,10 +90,8 @@ final class RegularExpressionValidatorTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider customErrorMessagesDataProvider
-     */
+    #[DataProvider('customErrorMessagesDataProvider')]
+    #[Test]
     public function translatableErrorMessageContainsDefaultValue(string $input, string $expected): void
     {
         $options = [
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/StringLengthValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/StringLengthValidatorTest.php
index 8b2d93cad57a..2999cfb7a4f0 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/StringLengthValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/StringLengthValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -34,25 +35,19 @@ final class StringLengthValidatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validateReturnsNoErrorIfTheGivenValueIsNull(): void
     {
         self::assertFalse((new StringLengthValidator())->validate(null)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validateReturnsNoErrorIfTheGivenValueIsAnEmptyString(): void
     {
         self::assertFalse((new StringLengthValidator())->validate('')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringLengthValidatorReturnsNoErrorForAStringShorterThanMaxLengthAndLongerThanMinLength(): void
     {
         $validator = new StringLengthValidator();
@@ -60,9 +55,7 @@ final class StringLengthValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate('this is a very simple string')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringLengthValidatorReturnsErrorForAStringShorterThanThanMinLength(): void
     {
         $validator = new StringLengthValidator();
@@ -70,9 +63,7 @@ final class StringLengthValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate('this is a very short string')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringLengthValidatorReturnsErrorsForAStringLongerThanThanMaxLength(): void
     {
         $validator = new StringLengthValidator();
@@ -80,9 +71,7 @@ final class StringLengthValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate('this is a very short string')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringLengthValidatorReturnsNoErrorsForAStringLongerThanThanMinLengthAndMaxLengthNotSpecified(): void
     {
         $validator = new StringLengthValidator();
@@ -90,9 +79,7 @@ final class StringLengthValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate('this is a very short string')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringLengthValidatorReturnsNoErrorsForAStringShorterThanThanMaxLengthAndMinLengthNotSpecified(): void
     {
         $validator = new StringLengthValidator();
@@ -100,9 +87,7 @@ final class StringLengthValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate('this is a very short string')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringLengthValidatorReturnsNoErrorsForAStringLengthEqualToMaxLengthAndMinLengthNotSpecified(): void
     {
         $validator = new StringLengthValidator();
@@ -110,9 +95,7 @@ final class StringLengthValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate('1234567890')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringLengthValidatorReturnsNoErrorForAStringLengthEqualToMinLengthAndMaxLengthNotSpecified(): void
     {
         $validator = new StringLengthValidator();
@@ -120,9 +103,7 @@ final class StringLengthValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate('1234567890')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringLengthValidatorReturnsNoErrorIfMinLengthAndMaxLengthAreEqualAndTheGivenStringMatchesThisValue(): void
     {
         $validator = new StringLengthValidator();
@@ -130,9 +111,7 @@ final class StringLengthValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate('1234567890')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringLengthValidatorReturnsNoErrorsIfTheStringLengthIsEqualToMaxLength(): void
     {
         $validator = new StringLengthValidator();
@@ -140,9 +119,7 @@ final class StringLengthValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate('1234567890')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringLengthValidatorReturnsNoErrorIfTheStringLengthIsEqualToMinLength(): void
     {
         $validator = new StringLengthValidator();
@@ -150,9 +127,7 @@ final class StringLengthValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate('1234567890')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringLengthValidatorThrowsAnExceptionIfMinLengthIsGreaterThanMaxLength(): void
     {
         $this->expectException(InvalidValidationOptionsException::class);
@@ -162,9 +137,7 @@ final class StringLengthValidatorTest extends FunctionalTestCase
         $validator->validate('1234567890');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringLengthValidatorInsertsAnErrorObjectIfValidationFails(): void
     {
         $validator = new StringLengthValidator();
@@ -172,9 +145,7 @@ final class StringLengthValidatorTest extends FunctionalTestCase
         self::assertCount(1, $validator->validate('this is a very short string')->getErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringLengthValidatorCanHandleAnObjectWithAToStringMethod(): void
     {
         $validator = new StringLengthValidator();
@@ -188,9 +159,7 @@ final class StringLengthValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate($object)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validateReturnsErrorsIfTheGivenObjectCanNotBeConvertedToAString(): void
     {
         $validator = new StringLengthValidator();
@@ -205,9 +174,7 @@ final class StringLengthValidatorTest extends FunctionalTestCase
         self::assertSame(1238110957, $error->getCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validateRegardsMultibyteStringsCorrectly(): void
     {
         $validator = new StringLengthValidator();
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/StringValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/StringValidatorTest.php
index e46e565147a3..b61d9f4bd7ab 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/StringValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/StringValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -33,9 +34,7 @@ final class StringValidatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringValidatorShouldValidateString(): void
     {
         $subject = new StringValidator();
@@ -43,9 +42,7 @@ final class StringValidatorTest extends FunctionalTestCase
         self::assertFalse($subject->validate('Hello World')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringValidatorShouldReturnErrorIfNumberIsGiven(): void
     {
         $subject = new StringValidator();
@@ -53,9 +50,7 @@ final class StringValidatorTest extends FunctionalTestCase
         self::assertTrue($subject->validate(42)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stringValidatorShouldReturnErrorIfObjectWithToStringMethodStringIsGiven(): void
     {
         $subject = new StringValidator();
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/TextValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/TextValidatorTest.php
index 757bc9a3c5dd..e52dc2112cbb 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/TextValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/TextValidatorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -88,10 +90,8 @@ final class TextValidatorTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider isValidDataProvider
-     */
+    #[DataProvider('isValidDataProvider')]
+    #[Test]
     public function isValidHasNoError(bool $expectation, string $testString): void
     {
         $validator = new TextValidator();
@@ -99,9 +99,7 @@ final class TextValidatorTest extends FunctionalTestCase
         self::assertSame($expectation, $validator->validate($testString)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function textValidatorCreatesTheCorrectErrorIfTheSubjectContainsHtmlEntities(): void
     {
         $validator = new TextValidator();
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/UrlValidatorTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/UrlValidatorTest.php
index 455100db8aba..53f53254059d 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/Validator/UrlValidatorTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/Validator/UrlValidatorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation\Validator;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -107,10 +109,8 @@ final class UrlValidatorTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider urlDataProvider
-     */
+    #[DataProvider('urlDataProvider')]
+    #[Test]
     public function urlValidatorDetectsUrlsCorrectly($value, $expected): void
     {
         $validator = new UrlValidator();
diff --git a/typo3/sysext/extbase/Tests/Functional/Validation/ValidatorResolverTest.php b/typo3/sysext/extbase/Tests/Functional/Validation/ValidatorResolverTest.php
index 07fd395e4a5e..8250d7dbd88d 100644
--- a/typo3/sysext/extbase/Tests/Functional/Validation/ValidatorResolverTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Validation/ValidatorResolverTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\Functional\Validation;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Extbase\Reflection\ReflectionService;
 use TYPO3\CMS\Extbase\Validation\Validator\CollectionValidator;
@@ -38,9 +39,7 @@ final class ValidatorResolverTest extends FunctionalTestCase
         'typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/test_validators',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function createValidatorSetsOptionsAndDependenciesAreInjected(): void
     {
         $subject = $this->get(ValidatorResolver::class);
@@ -51,9 +50,7 @@ final class ValidatorResolverTest extends FunctionalTestCase
         self::assertInstanceOf(IconFactory::class, $validator->iconFactory);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function buildBaseValidatorConjunctionAddsValidatorsDefinedByAnnotationsInTheClassToTheReturnedConjunction(): void
     {
         $subject = $this->getAccessibleMock(
diff --git a/typo3/sysext/extbase/Tests/FunctionalDeprecated/Utility/LocalizationUtilityTest.php b/typo3/sysext/extbase/Tests/FunctionalDeprecated/Utility/LocalizationUtilityTest.php
index a4765ffd5791..295deb387c86 100644
--- a/typo3/sysext/extbase/Tests/FunctionalDeprecated/Utility/LocalizationUtilityTest.php
+++ b/typo3/sysext/extbase/Tests/FunctionalDeprecated/Utility/LocalizationUtilityTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Extbase\Tests\FunctionalDeprecated\Utility;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use PHPUnit\Framework\MockObject\MockObject;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -44,10 +46,8 @@ final class LocalizationUtilityTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider translateDataProvider
-     * @test
-     */
+    #[DataProvider('translateDataProvider')]
+    #[Test]
     public function translateTestWithBackendUserLanguage(
         string $key,
         string $languageKey,
@@ -68,10 +68,8 @@ final class LocalizationUtilityTest extends FunctionalTestCase
         self::assertSame($expected, LocalizationUtility::translate($key, 'label_test', $arguments, alternativeLanguageKeys: $altLanguageKeys));
     }
 
-    /**
-     * @dataProvider translateDataProvider
-     * @test
-     */
+    #[DataProvider('translateDataProvider')]
+    #[Test]
     public function translateTestWithExplicitLanguageParameters(
         string $key,
         string $languageKey,
diff --git a/typo3/sysext/felogin/Tests/Functional/Domain/Repository/FrontendUserGroupRepositoryTest.php b/typo3/sysext/felogin/Tests/Functional/Domain/Repository/FrontendUserGroupRepositoryTest.php
index ec73fd499eec..59d257d5e72e 100644
--- a/typo3/sysext/felogin/Tests/Functional/Domain/Repository/FrontendUserGroupRepositoryTest.php
+++ b/typo3/sysext/felogin/Tests/Functional/Domain/Repository/FrontendUserGroupRepositoryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\FrontendLogin\Tests\Functional\Domain\Repository;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
@@ -41,17 +42,13 @@ final class FrontendUserGroupRepositoryTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/fe_groups.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTable(): void
     {
         self::assertSame('fe_groups', $this->repository->getTable());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findRedirectPageIdByGroupId(): void
     {
         self::assertNull($this->repository->findRedirectPageIdByGroupId(99));
diff --git a/typo3/sysext/felogin/Tests/Functional/Domain/Repository/FrontendUserRepositoryTest.php b/typo3/sysext/felogin/Tests/Functional/Domain/Repository/FrontendUserRepositoryTest.php
index 632339dd5ac1..c7b6a39eca2e 100644
--- a/typo3/sysext/felogin/Tests/Functional/Domain/Repository/FrontendUserRepositoryTest.php
+++ b/typo3/sysext/felogin/Tests/Functional/Domain/Repository/FrontendUserRepositoryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\FrontendLogin\Tests\Functional\Domain\Repository;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
@@ -42,17 +43,13 @@ final class FrontendUserRepositoryTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/fe_users.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTable(): void
     {
         self::assertSame('fe_users', $this->repository->getTable());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findUserByUsernameOrEmailOnPages(): void
     {
         self::assertNull($this->repository->findUserByUsernameOrEmailOnPages(''));
@@ -67,18 +64,14 @@ final class FrontendUserRepositoryTest extends FunctionalTestCase
         self::assertSame(1, $userByEmail['uid'] ?? 0);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function existsUserWithHash(): void
     {
         self::assertFalse($this->repository->existsUserWithHash('non-existent-hash'));
         self::assertTrue($this->repository->existsUserWithHash('cf8edd6fa435b4a9fcbb953f81bd84f2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findOneByForgotPasswordHash(): void
     {
         self::assertNull($this->repository->findOneByForgotPasswordHash(''));
@@ -86,18 +79,14 @@ final class FrontendUserRepositoryTest extends FunctionalTestCase
         self::assertIsArray($this->repository->findOneByForgotPasswordHash('cf8edd6fa435b4a9fcbb953f81bd84f2'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findRedirectIdPageByUserId(): void
     {
         self::assertNull($this->repository->findRedirectIdPageByUserId(99));
         self::assertSame(10, $this->repository->findRedirectIdPageByUserId(1));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function updateForgotHashForUserByUid(): void
     {
         $uid = 1;
@@ -121,9 +110,7 @@ final class FrontendUserRepositoryTest extends FunctionalTestCase
         self::assertSame($newPasswordHash, $query->executeQuery()->fetchOne());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function updatePasswordAndInvalidateHash(): void
     {
         $this->repository->updatePasswordAndInvalidateHash('cf8edd6fa435b4a9fcbb953f81bd84f2', 'new-password');
diff --git a/typo3/sysext/felogin/Tests/Functional/Tca/ContentVisibleFieldsTest.php b/typo3/sysext/felogin/Tests/Functional/Tca/ContentVisibleFieldsTest.php
index 8d81c42caf7e..f82c285a99f0 100644
--- a/typo3/sysext/felogin/Tests/Functional/Tca/ContentVisibleFieldsTest.php
+++ b/typo3/sysext/felogin/Tests/Functional/Tca/ContentVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\FrontendLogin\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -43,9 +44,7 @@ final class ContentVisibleFieldsTest extends FunctionalTestCase
         'pi_flexform',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function loginFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/filemetadata/Tests/Functional/Tca/FileMetadataVisibleFieldsTest.php b/typo3/sysext/filemetadata/Tests/Functional/Tca/FileMetadataVisibleFieldsTest.php
index 624eeb7f22a1..baad16a88078 100644
--- a/typo3/sysext/filemetadata/Tests/Functional/Tca/FileMetadataVisibleFieldsTest.php
+++ b/typo3/sysext/filemetadata/Tests/Functional/Tca/FileMetadataVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Filemetadata\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Resource\File;
@@ -142,9 +143,7 @@ final class FileMetadataVisibleFieldsTest extends FunctionalTestCase
         ],
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fileMetadataFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/fluid/Tests/Functional/EscapeChildrenRenderingStandaloneTest.php b/typo3/sysext/fluid/Tests/Functional/EscapeChildrenRenderingStandaloneTest.php
index e08de2d9a9ba..f9676ef2a2c8 100644
--- a/typo3/sysext/fluid/Tests/Functional/EscapeChildrenRenderingStandaloneTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/EscapeChildrenRenderingStandaloneTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -115,10 +117,8 @@ final class EscapeChildrenRenderingStandaloneTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider viewHelperTemplateSourcesDataProvider
-     */
+    #[DataProvider('viewHelperTemplateSourcesDataProvider')]
+    #[Test]
     public function renderingTest(string $viewHelperTemplate, string $expectedOutput): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/EscapeChildrenRenderingTest.php b/typo3/sysext/fluid/Tests/Functional/EscapeChildrenRenderingTest.php
index a8629ca23d48..f4eee817e9e7 100644
--- a/typo3/sysext/fluid/Tests/Functional/EscapeChildrenRenderingTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/EscapeChildrenRenderingTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\View\TemplateView;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -114,10 +116,8 @@ final class EscapeChildrenRenderingTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider viewHelperTemplateSourcesDataProvider
-     */
+    #[DataProvider('viewHelperTemplateSourcesDataProvider')]
+    #[Test]
     public function renderingTest(string $viewHelperTemplate, string $expectedOutput): void
     {
         $view = new TemplateView();
diff --git a/typo3/sysext/fluid/Tests/Functional/View/TemplatesPathsTest.php b/typo3/sysext/fluid/Tests/Functional/View/TemplatesPathsTest.php
index a9ca3d1c8f0a..db7e163f28c8 100644
--- a/typo3/sysext/fluid/Tests/Functional/View/TemplatesPathsTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/View/TemplatesPathsTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\View;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -140,13 +142,13 @@ final class TemplatesPathsTest extends FunctionalTestCase
     }
 
     /**
-     * @test
      * @param string $overrideType
      * @param string $expectedTemplate
      * @param string $expectedPartial
      * @param string $expectedLayout
-     * @dataProvider differentOverrideScenariosDataProvider
      */
+    #[DataProvider('differentOverrideScenariosDataProvider')]
+    #[Test]
     public function baseRenderingWorksForCObject($overrideType, $expectedTemplate, $expectedPartial, $expectedLayout): void
     {
         $requestArguments = [
@@ -163,13 +165,13 @@ final class TemplatesPathsTest extends FunctionalTestCase
     }
 
     /**
-     * @test
      * @param string $overrideType
      * @param string $expectedTemplate
      * @param string $expectedPartial
      * @param string $expectedLayout
-     * @dataProvider differentOverrideScenariosDataProvider
      */
+    #[DataProvider('differentOverrideScenariosDataProvider')]
+    #[Test]
     public function baseRenderingWorksForControllerAsGlobalUsage($overrideType, $expectedTemplate, $expectedPartial, $expectedLayout): void
     {
         $requestArguments = [
@@ -186,13 +188,13 @@ final class TemplatesPathsTest extends FunctionalTestCase
     }
 
     /**
-     * @test
      * @param string $overrideType
      * @param string $expectedTemplate
      * @param string $expectedPartial
      * @param string $expectedLayout
-     * @dataProvider differentOverrideScenariosDataProvider
      */
+    #[DataProvider('differentOverrideScenariosDataProvider')]
+    #[Test]
     public function baseRenderingWorksForControllerAsPluginUsage($overrideType, $expectedTemplate, $expectedPartial, $expectedLayout): void
     {
         $requestArguments = [
@@ -210,13 +212,13 @@ final class TemplatesPathsTest extends FunctionalTestCase
     }
 
     /**
-     * @test
      * @param string $overrideType
      * @param string $expectedTemplate
      * @param string $expectedPartial
      * @param string $expectedLayout
-     * @dataProvider differentOverrideScenariosDataProvider
      */
+    #[DataProvider('differentOverrideScenariosDataProvider')]
+    #[Test]
     public function baseRenderingWorksForControllerAsPluginUsageWithPluginConfig($overrideType, $expectedTemplate, $expectedPartial, $expectedLayout): void
     {
         $requestArguments = [
@@ -233,9 +235,7 @@ final class TemplatesPathsTest extends FunctionalTestCase
         self::assertStringContainsString($expectedLayout, $content);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function baseRenderingWorksForControllerAsPluginUsageWithIncompleteConfig(): void
     {
         $requestArguments = [
@@ -252,9 +252,7 @@ final class TemplatesPathsTest extends FunctionalTestCase
         self::assertStringContainsString('Default Partial', $content);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function baseRenderingWorksForControllerWithTwoPlugins(): void
     {
         $requestArguments = [
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Asset/CssViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Asset/CssViewHelperTest.php
index 244a0aacc406..aaa29b8a1bd5 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Asset/CssViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Asset/CssViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Asset;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Page\AssetCollector;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -37,10 +39,8 @@ final class CssViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider sourceDataProvider
-     */
+    #[DataProvider('sourceDataProvider')]
+    #[Test]
     public function sourceStringIsNotHtmlEncodedBeforePassedToAssetCollector(string $href): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -53,9 +53,7 @@ final class CssViewHelperTest extends FunctionalTestCase
         self::assertSame([], $collectedStyleSheets['test']['attributes']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function booleanAttributesAreProperlyConverted(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -122,10 +120,8 @@ final class CssViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider childNodeRenderingIsCorrectDataProvider
-     */
+    #[DataProvider('childNodeRenderingIsCorrectDataProvider')]
+    #[Test]
     public function childNodeRenderingIsCorrect(string $value, string $source, string $expectation): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Asset/ScriptViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Asset/ScriptViewHelperTest.php
index 2b39d3778028..23ab123cbe20 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Asset/ScriptViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Asset/ScriptViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Asset;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Page\AssetCollector;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\CMS\Fluid\View\TemplateView;
@@ -37,10 +39,8 @@ final class ScriptViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider sourceDataProvider
-     */
+    #[DataProvider('sourceDataProvider')]
+    #[Test]
     public function sourceStringIsNotHtmlEncodedBeforePassedToAssetCollector(string $src): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -53,9 +53,7 @@ final class ScriptViewHelperTest extends FunctionalTestCase
         self::assertSame([], $collectedJavaScripts['test']['attributes']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function booleanAttributesAreProperlyConverted(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/LinkViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/LinkViewHelperTest.php
index 7edffdcd5b9b..3b3b162a5f85 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/LinkViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/LinkViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Be;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Routing\Router;
 use TYPO3\CMS\Backend\Routing\UriBuilder;
 use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
@@ -31,9 +32,7 @@ final class LinkViewHelperTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderRendersTagWithHrefFromRoute(): void
     {
         // Mock Uribuilder in this functional test so we don't have to work with existing routes
@@ -51,9 +50,7 @@ final class LinkViewHelperTest extends FunctionalTestCase
         self::assertEquals('<a href="theUri">foo</a>', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderPassesEmptyArrayToUriBuilderForNoParameters(): void
     {
         // Mock Uribuilder in this functional test so we don't have to work with existing routes
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/Menus/ActionMenuItemViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/Menus/ActionMenuItemViewHelperTest.php
index 83dfa4444ec2..8c6f61c2cad4 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/Menus/ActionMenuItemViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/Menus/ActionMenuItemViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Be\Menus;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters;
@@ -60,10 +62,8 @@ final class ActionMenuItemViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider isRenderedDataProvider
-     */
+    #[DataProvider('isRenderedDataProvider')]
+    #[Test]
     public function isRendered(string $source, array $variables, string $expectation): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/Security/IfAuthenticatedViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/Security/IfAuthenticatedViewHelperTest.php
index a50c3da60827..5313584051b6 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/Security/IfAuthenticatedViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/Security/IfAuthenticatedViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Be\Security;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -25,9 +26,7 @@ final class IfAuthenticatedViewHelperTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperRendersThenChildIfBeUserIsLoggedIn(): void
     {
         $GLOBALS['BE_USER'] = new \stdClass();
@@ -39,9 +38,7 @@ final class IfAuthenticatedViewHelperTest extends FunctionalTestCase
         self::assertEquals('then child', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperRendersElseChildIfBeUserIsNotLoggedIn(): void
     {
         $GLOBALS['BE_USER'] = new \stdClass();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/Security/IfHasRoleViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/Security/IfHasRoleViewHelperTest.php
index a7b81e38b7f2..2c8d2326d261 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/Security/IfHasRoleViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/Security/IfHasRoleViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Be\Security;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -41,9 +42,7 @@ final class IfHasRoleViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperRendersThenChildIfBeUserWithSpecifiedRoleIsLoggedIn(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -53,9 +52,7 @@ final class IfHasRoleViewHelperTest extends FunctionalTestCase
         self::assertEquals('then child', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperRendersElseChildIfBeUserWithSpecifiedRoleIsNotLoggedIn(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -65,9 +62,7 @@ final class IfHasRoleViewHelperTest extends FunctionalTestCase
         self::assertEquals('else child', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperRendersElseChildIfBeUserWithSpecifiedRoleIdIsNotLoggedIn(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/UriViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/UriViewHelperTest.php
index 87540eb4395c..02de29b460a2 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/UriViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Be/UriViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Be;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Routing\Router;
 use TYPO3\CMS\Backend\Routing\UriBuilder;
 use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
@@ -31,9 +32,7 @@ final class UriViewHelperTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderRendersTagWithHrefFromRoute(): void
     {
         // Mock Uribuilder in this functional test so we don't have to work with existing routes
@@ -51,9 +50,7 @@ final class UriViewHelperTest extends FunctionalTestCase
         self::assertEquals('theUri', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderPassesEmptyArrayToUriBuilderForNoParameters(): void
     {
         // Mock Uribuilder in this functional test so we don't have to work with existing routes
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/CObjectViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/CObjectViewHelperTest.php
index 804f8da796f9..7dd600abd238 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/CObjectViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/CObjectViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
@@ -51,9 +52,7 @@ final class CObjectViewHelperTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperAcceptsDataParameter(): void
     {
         (new ConnectionPool())->getConnectionForTable('sys_template')->insert('sys_template', [
@@ -75,9 +74,7 @@ EOT
         self::assertStringContainsString('foo', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperAcceptsChildrenClosureAsData(): void
     {
         (new ConnectionPool())->getConnectionForTable('sys_template')->insert('sys_template', [
@@ -99,9 +96,7 @@ EOT
         self::assertStringContainsString('foo', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionIfTypoScriptObjectPathDoesNotExist(): void
     {
         (new ConnectionPool())->getConnectionForTable('sys_template')->insert('sys_template', [
@@ -122,9 +117,7 @@ EOT
         $this->executeFrontendSubRequest((new InternalRequest())->withPageId(1));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionIfNestedTypoScriptObjectPathDoesNotExist(): void
     {
         (new ConnectionPool())->getConnectionForTable('sys_template')->insert('sys_template', [
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/FlashMessagesViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/FlashMessagesViewHelperTest.php
index ade679e36143..18627870e278 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/FlashMessagesViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/FlashMessagesViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
@@ -30,9 +31,7 @@ use TYPO3Fluid\Fluid\View\TemplateView;
 
 final class FlashMessagesViewHelperTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsEmptyStringIfNoFlashMessagesAreInQueue(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -44,9 +43,7 @@ final class FlashMessagesViewHelperTest extends FunctionalTestCase
         self::assertEmpty((new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsEmptyStringFromSpecificEmptyQueue(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -54,9 +51,7 @@ final class FlashMessagesViewHelperTest extends FunctionalTestCase
         self::assertEmpty((new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsRenderedFlashMessage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/ButtonViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/ButtonViewHelperTest.php
index eda7a6780042..aaebff1617d2 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/ButtonViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/ButtonViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Form;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -25,9 +26,7 @@ final class ButtonViewHelperTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCorrectlySetsTagNameAndDefaultAttributes(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -35,9 +34,7 @@ final class ButtonViewHelperTest extends FunctionalTestCase
         self::assertSame('<button type="submit" name="" value="">Button Content</button>', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function closingTagIsEnforcedOnEmptyContent(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/CheckboxViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/CheckboxViewHelperTest.php
index f294c7b1fa6d..cb8d3cf2b8ef 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/CheckboxViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/CheckboxViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Form;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Error\Error;
@@ -43,10 +45,8 @@ final class CheckboxViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -56,9 +56,7 @@ final class CheckboxViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderIgnoresValueOfBoundPropertyIfCheckedIsSet(): void
     {
         $formObject = new \stdClass();
@@ -74,9 +72,7 @@ final class CheckboxViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="hidden" name="myFieldPrefix[myObjectName][someProperty]" value="" /><input type="checkbox" name="myFieldPrefix[myObjectName][someProperty]" value="foo" checked="checked" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderSetsCheckedAttributeIfCheckboxIsBoundToAPropertyOfTypeBoolean(): void
     {
         $formObject = new \stdClass();
@@ -92,9 +88,7 @@ final class CheckboxViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="hidden" name="myFieldPrefix[myObjectName][someProperty]" value="" /><input type="checkbox" name="myFieldPrefix[myObjectName][someProperty]" value="foo" checked="checked" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderAppendsSquareBracketsToNameAttributeIfBoundToAPropertyOfTypeArray(): void
     {
         $formObject = new \stdClass();
@@ -110,9 +104,7 @@ final class CheckboxViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="hidden" name="myFieldPrefix[myObjectName][someProperty]" value="" /><input type="checkbox" name="myFieldPrefix[myObjectName][someProperty][]" value="foo" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderSetsCheckedAttributeIfCheckboxIsBoundToAPropertyOfTypeArray(): void
     {
         $formObject = new \stdClass();
@@ -128,9 +120,7 @@ final class CheckboxViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="hidden" name="myFieldPrefix[myObjectName][someProperty]" value="" /><input type="checkbox" name="myFieldPrefix[myObjectName][someProperty][]" value="foo" checked="checked" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderSetsCheckedAttributeIfCheckboxIsBoundToAPropertyOfTypeArrayObject(): void
     {
         $formObject = new \ArrayObject(['someProperty' => true]);
@@ -145,9 +135,7 @@ final class CheckboxViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="hidden" name="myFieldPrefix[myObjectName][someProperty]" value="" /><input type="checkbox" name="myFieldPrefix[myObjectName][someProperty]" value="bar" checked="checked" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderSetsCheckedAttributeIfBoundPropertyIsNotNull(): void
     {
         $formObject = new \stdClass();
@@ -163,9 +151,7 @@ final class CheckboxViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="hidden" name="myFieldPrefix[myObjectName][someProperty]" value="" /><input type="checkbox" name="myFieldPrefix[myObjectName][someProperty]" value="foo" checked="checked" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderDoesNotSetsCheckedAttributeIfBoundPropertyIsNull(): void
     {
         $formObject = new \stdClass();
@@ -181,9 +167,7 @@ final class CheckboxViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="hidden" name="myFieldPrefix[myObjectName][someProperty]" value="" /><input type="checkbox" name="myFieldPrefix[myObjectName][someProperty]" value="foo" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCallSetsErrorClassAttribute(): void
     {
         // Create an extbase request that contains mapping results of the form object property we're working with.
@@ -208,9 +192,7 @@ final class CheckboxViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="checkbox" name="myFieldPrefix[myObjectName][someProperty]" value="foo" class="myError" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCallSetsStandardErrorClassAttributeIfNonIsSpecified(): void
     {
         // Create an extbase request that contains mapping results of the form object property we're working with.
@@ -235,9 +217,7 @@ final class CheckboxViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="checkbox" name="myFieldPrefix[myObjectName][someProperty]" value="foo" class="f3-form-error" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCallExtendsClassAttributeWithErrorClass(): void
     {
         // Create an extbase request that contains mapping results of the form object property we're working with.
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/CountrySelectViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/CountrySelectViewHelperTest.php
index aa2a0015a4fe..09f4893a8d4a 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/CountrySelectViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/CountrySelectViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Form;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters;
 use TYPO3\CMS\Extbase\Mvc\Request;
@@ -28,9 +29,7 @@ final class CountrySelectViewHelperTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCorrectlySetsTagNameAndDefaultAttributes(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -42,9 +41,7 @@ final class CountrySelectViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<option value="ES">Spain</option>', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCorrectlyPreselectsAValidValue(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -55,9 +52,7 @@ final class CountrySelectViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<option value="KW" selected="selected">Koweït</option>', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCorrectlyUsesLocalizedNames(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -68,9 +63,7 @@ final class CountrySelectViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<option value="ES">Espagne</option>', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderShowsPrioritizedCountriesFirst(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -82,9 +75,7 @@ final class CountrySelectViewHelperTest extends FunctionalTestCase
 <option value="GB">United Kingdom</option><option value="US" selected="selected">United States</option><option value="CA">Canada</option><option value="AD">Andorra</option>', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function rendersSortsByOptionLabel(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -95,9 +86,7 @@ final class CountrySelectViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<option value="DE">Germany</option><option value="GH">Ghana</option>', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function rendersSortsByOptionLabelWithLocalizedOfficialName(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -108,9 +97,7 @@ final class CountrySelectViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<option value="BD">Volksrepublik Bangladesh</option><option value="CN">Volksrepublik China</option>', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderExcludesCountries(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -121,9 +108,7 @@ final class CountrySelectViewHelperTest extends FunctionalTestCase
         self::assertStringNotContainsString('<option value="CN">Volksrepublik China</option>', $result);
         self::assertStringNotContainsString('<option value="RU">', $result);
     }
-    /**
-     * @test
-     */
+    #[Test]
     public function renderOnlyListsWantedCountries(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/HiddenViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/HiddenViewHelperTest.php
index fe5962de53d8..a1eb346b9aa9 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/HiddenViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/HiddenViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Form;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters;
 use TYPO3\CMS\Extbase\Mvc\Request;
@@ -28,9 +29,7 @@ final class HiddenViewHelperTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCorrectlySetsTagNameAndDefaultAttributes(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/PasswordViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/PasswordViewHelperTest.php
index 9629fc8b2dc6..7666c7985d75 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/PasswordViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/PasswordViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Form;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters;
 use TYPO3\CMS\Extbase\Mvc\Request;
@@ -28,9 +29,7 @@ final class PasswordViewHelperTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCorrectlySetsTagName(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -40,9 +39,7 @@ final class PasswordViewHelperTest extends FunctionalTestCase
         self::assertSame('<input type="password" name="" value="" />', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCorrectlySetsTypeNameAndValueAttributes(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -52,9 +49,7 @@ final class PasswordViewHelperTest extends FunctionalTestCase
         self::assertSame('<input type="password" name="NameOfTextbox" value="Current value" />', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCorrectlySetsAutocompleteTagAttribute(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/RadioViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/RadioViewHelperTest.php
index e2a1dc940145..3690c8d37023 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/RadioViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/RadioViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Form;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Error\Error;
@@ -43,10 +45,8 @@ final class RadioViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -56,9 +56,7 @@ final class RadioViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderIgnoresBoundPropertyIfCheckedIsSet(): void
     {
         $formObject = new \stdClass();
@@ -74,9 +72,7 @@ final class RadioViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="radio" name="myFieldPrefix[myObjectName][someProperty]" value="foo" checked="checked" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCorrectlySetsCheckedAttributeIfCheckboxIsBoundToAPropertyOfTypeBoolean(): void
     {
         $formObject = new \stdClass();
@@ -92,9 +88,7 @@ final class RadioViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="radio" name="myFieldPrefix[myObjectName][someProperty]" value="foo" checked="checked" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderDoesNotAppendSquareBracketsToNameAttributeIfBoundToAPropertyOfTypeArray(): void
     {
         $formObject = new \stdClass();
@@ -110,9 +104,7 @@ final class RadioViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="radio" name="myFieldPrefix[myObjectName][someProperty]" value="foo" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderSetsCheckedAttributeIfCheckboxIsBoundToAPropertyOfTypeString(): void
     {
         $formObject = new \stdClass();
@@ -128,9 +120,7 @@ final class RadioViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="radio" name="myFieldPrefix[myObjectName][someProperty]" value="foo" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderDoesNotSetsCheckedAttributeIfBoundPropertyIsNull(): void
     {
         $formObject = new \stdClass();
@@ -146,9 +136,7 @@ final class RadioViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="radio" name="myFieldPrefix[myObjectName][someProperty]" value="foo" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCallSetsErrorClassAttribute(): void
     {
         // Create an extbase request that contains mapping results of the form object property we're working with.
@@ -173,9 +161,7 @@ final class RadioViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="radio" name="myFieldPrefix[myObjectName][someProperty]" value="foo" class="myError" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCallSetsStandardErrorClassAttributeIfNonIsSpecified(): void
     {
         $mappingResult = new Result();
@@ -198,9 +184,7 @@ final class RadioViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString('<input type="radio" name="myFieldPrefix[myObjectName][someProperty]" value="foo" class="f3-form-error" />', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCallExtendsClassAttributeWithErrorClass(): void
     {
         $mappingResult = new Result();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/Select/OptionViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/Select/OptionViewHelperTest.php
index 79545a81df89..6fc9b6b24da2 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/Select/OptionViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/Select/OptionViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Form\Select;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters;
 use TYPO3\CMS\Extbase\Mvc\Request;
@@ -28,9 +30,7 @@ final class OptionViewHelperTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function optionTagNameIsSet(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -40,9 +40,7 @@ final class OptionViewHelperTest extends FunctionalTestCase
         self::assertSame('<option selected="selected" value="" />', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function childrenContentIsUsedAsValueAndLabelByDefault(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -52,9 +50,7 @@ final class OptionViewHelperTest extends FunctionalTestCase
         self::assertSame('<option value="Option Label">Option Label</option>', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function valueCanBeOverwrittenByArgument(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -64,9 +60,7 @@ final class OptionViewHelperTest extends FunctionalTestCase
         self::assertSame('<option value="value">Option Label</option>', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectedIsAddedToSelectedOptionForNoSelectionOverride(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -103,10 +97,8 @@ final class OptionViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider selectedIsAddedToSelectedOptionForProvidedValueDataProvider
-     */
+    #[DataProvider('selectedIsAddedToSelectedOptionForProvidedValueDataProvider')]
+    #[Test]
     public function selectedIsAddedToSelectedOptionForProvidedValue($value, $selected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -122,9 +114,7 @@ final class OptionViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectedIsNotAddedToUnselectedOptionForNoSelectionOverride(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -156,10 +146,8 @@ final class OptionViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider selectedIsNotAddedToSelectedOptionForProvidedValueDataProvider
-     */
+    #[DataProvider('selectedIsNotAddedToSelectedOptionForProvidedValueDataProvider')]
+    #[Test]
     public function selectedIsNotAddedToSelectedOptionForProvidedValue($value, $selected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -175,9 +163,7 @@ final class OptionViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectedIsNotAddedToOptionForExplicitOverride(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -188,9 +174,7 @@ final class OptionViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectedIsAddedToOptionForExplicitOverride(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/SelectViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/SelectViewHelperTest.php
index 52b2b015ed8c..614d376cb0f4 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/SelectViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/SelectViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Form;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -35,9 +36,7 @@ use TYPO3Fluid\Fluid\View\TemplateView;
 
 final class SelectViewHelperTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function selectCorrectlySetsTagName(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -47,9 +46,7 @@ final class SelectViewHelperTest extends FunctionalTestCase
         self::assertSame('<select name=""></select>', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectCreatesExpectedOptions(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -60,9 +57,7 @@ final class SelectViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectShouldSetTheRequiredAttribute(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -73,9 +68,7 @@ final class SelectViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectCreatesExpectedOptionsWithArraysAndOptionValueFieldAndOptionLabelFieldSet(): void
     {
         $options = [
@@ -110,9 +103,7 @@ EOT;
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectThrowsExceptionIfEitherOptionValueFieldIsNotSet(): void
     {
         $options = [
@@ -145,9 +136,7 @@ EOT;
         $view->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectThrowsExceptionIfEitherOptionLabelFieldIsNotSet(): void
     {
         $options = [
@@ -180,9 +169,7 @@ EOT;
         $view->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectCreatesExpectedOptionsWithStdClassesAndOptionValueFieldAndOptionLabelFieldSet(): void
     {
         $obj1 = new \stdClass();
@@ -217,9 +204,7 @@ EOT;
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectCreatesExpectedOptionsWithArrayObjectsAndOptionValueFieldAndOptionLabelFieldSet(): void
     {
         $options = new \ArrayObject([
@@ -254,9 +239,7 @@ EOT;
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function OrderOfOptionsIsNotAlteredByDefault(): void
     {
         $options = [
@@ -279,9 +262,7 @@ EOT;
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function optionsAreSortedByLabelIfSortByOptionLabelIsSet(): void
     {
         $options = [
@@ -304,9 +285,7 @@ EOT;
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function multipleSelectCreatesExpectedOptions(): void
     {
         $options = [
@@ -331,9 +310,7 @@ EOT;
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function multipleSelectWithoutOptionsCreatesExpectedOptions(): void
     {
         $value = ['value3', 'value1'];
@@ -347,9 +324,7 @@ EOT;
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectOnDomainObjectsCreatesExpectedOptions(): void
     {
         $user_is = new UserDomainClass(1, 'Ingmar', 'Schlecht');
@@ -376,9 +351,7 @@ EOT;
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function multipleSelectOnDomainObjectsCreatesExpectedOptions(): void
     {
         $user_is = new UserDomainClass(1, 'Ingmar', 'Schlecht');
@@ -405,9 +378,7 @@ EOT;
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function multipleSelectOnDomainObjectsCreatesExpectedOptionsWithoutOptionValueField(): void
     {
         $user_is = new UserDomainClass(1, 'Ingmar', 'Schlecht');
@@ -446,9 +417,7 @@ EOT;
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectWithoutFurtherConfigurationOnDomainObjectsUsesUuidForValueAndLabel(): void
     {
         $user_is = new UserDomainClass(1, 'Ingmar', 'Schlecht');
@@ -475,9 +444,7 @@ EOT;
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectWithoutFurtherConfigurationOnDomainObjectsUsesToStringForLabelIfAvailable(): void
     {
         $user_is = new UserDomainClassToString(1, 'Ingmar', 'Schlecht');
@@ -504,9 +471,7 @@ EOT;
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectOnDomainObjectsThrowsExceptionIfNoValueCanBeFound(): void
     {
         $user_is = new UserDomainClass(1, 'Ingmar', 'Schlecht');
@@ -533,9 +498,7 @@ EOT;
         $view->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCallsSetErrorClassAttribute(): void
     {
         // Create an extbase request that contains mapping results of the form object property we're working with.
@@ -561,9 +524,7 @@ EOT;
         self::assertStringContainsString('<select name="myFieldPrefix[myObjectName][someProperty]" class="myError"></select>', $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function allOptionsAreSelectedIfSelectAllIsTrue(): void
     {
         $options = [
@@ -586,9 +547,7 @@ EOT;
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function selectAllHasNoEffectIfValueIsSet(): void
     {
         $options = [
@@ -612,9 +571,7 @@ EOT;
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function optionsContainPrependedItemWithEmptyValueIfPrependOptionLabelIsSet(): void
     {
         $options = [
@@ -639,9 +596,7 @@ EOT;
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function optionsContainPrependedItemWithCorrectValueIfPrependOptionLabelAndPrependOptionValueAreSet(): void
     {
         $options = [
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/SubmitViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/SubmitViewHelperTest.php
index 7adcf8992a9d..fa2ab45d5595 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/SubmitViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/SubmitViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Form;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -25,9 +26,7 @@ final class SubmitViewHelperTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCorrectlySetsTagNameAndDefaultAttributes(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/TextareaViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/TextareaViewHelperTest.php
index 03e30586fd72..a770f01fea10 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/TextareaViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/TextareaViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Form;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Error\Error;
@@ -59,10 +61,8 @@ final class TextareaViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -72,9 +72,7 @@ final class TextareaViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCallsSetErrorClassAttribute(): void
     {
         // Create an extbase request that contains mapping results of the form object property we're working with.
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/TextfieldViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/TextfieldViewHelperTest.php
index 06f8db402169..861c49534bcb 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/TextfieldViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/TextfieldViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Form;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Error\Error;
@@ -51,10 +53,8 @@ final class TextfieldViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -64,9 +64,7 @@ final class TextfieldViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCallsSetErrorClassAttribute(): void
     {
         // Create an extbase request that contains mapping results of the form object property we're working with.
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/UploadViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/UploadViewHelperTest.php
index 55681a4dfb36..4221d4ca673c 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/UploadViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Form/UploadViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Form;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Error\Error;
@@ -29,9 +30,7 @@ use TYPO3Fluid\Fluid\View\TemplateView;
 
 final class UploadViewHelperTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCorrectlySetsTagName(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -39,9 +38,7 @@ final class UploadViewHelperTest extends FunctionalTestCase
         self::assertSame('<input type="file" name="" />', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCorrectlySetsTypeNameAttributes(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -49,9 +46,7 @@ final class UploadViewHelperTest extends FunctionalTestCase
         self::assertSame('<input type="file" name="someName" />', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderSetsAttributeNameAsArrayIfMultipleIsGiven(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -59,9 +54,7 @@ final class UploadViewHelperTest extends FunctionalTestCase
         self::assertSame('<input multiple="multiple" type="file" name="someName[]" />', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCorrectlySetsAcceptAttribute(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -69,9 +62,7 @@ final class UploadViewHelperTest extends FunctionalTestCase
         self::assertSame('<input accept=".jpg,.png" type="file" name="" />', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCallsSetErrorClassAttribute(): void
     {
         // Create an extbase request that contains mapping results of the form object property we're working with.
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/FormViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/FormViewHelperTest.php
index 765377b5b87e..226e341b3e91 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/FormViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/FormViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\ServerRequestInterface;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Domain\Repository\PageRepository;
@@ -68,10 +70,8 @@ final class FormViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider isRenderedDataProvider
-     */
+    #[DataProvider('isRenderedDataProvider')]
+    #[Test]
     public function isRendered(string $source, array $variables, string $expectation): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -89,9 +89,7 @@ final class FormViewHelperTest extends FunctionalTestCase
         self::assertSame($expectation, $actual);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderHiddenIdentityFieldReturnsAHiddenInputFieldContainingTheObjectsUID(): void
     {
         $extendsAbstractEntity = new ExtendsAbstractEntity();
@@ -107,9 +105,7 @@ final class FormViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setFormActionUriRespectsOverriddenArgument(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -121,9 +117,7 @@ final class FormViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString($expected, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function nameArgumentIsUsedFormHiddenIdentityName(): void
     {
         $extendsAbstractEntity = new ExtendsAbstractEntity();
@@ -139,9 +133,7 @@ final class FormViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function objectNameArgumentOverrulesNameArgument(): void
     {
         $extendsAbstractEntity = new ExtendsAbstractEntity();
@@ -157,9 +149,7 @@ final class FormViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderWrapsHiddenFieldsWithDivForXhtmlCompatibilityWithRewrittenPropertyMapper(): void
     {
         $extendsAbstractEntity = new ExtendsAbstractEntity();
@@ -175,9 +165,7 @@ final class FormViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderWrapsHiddenFieldsWithDivAndAnAdditionalClassForXhtmlCompatibilityWithRewrittenPropertyMapper(): void
     {
         $extendsAbstractEntity = new ExtendsAbstractEntity();
@@ -193,9 +181,7 @@ final class FormViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderHiddenReferrerFieldsAddCurrentControllerAndActionAsHiddenFields(): void
     {
         $extbaseRequestParameters = new ExtbaseRequestParameters();
@@ -227,9 +213,7 @@ final class FormViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderHiddenReferrerFieldsAddCurrentControllerAndActionAsHiddenFields111(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/pages.csv');
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/BytesViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/BytesViewHelperTest.php
index 63b301291604..d0b79ca68118 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/BytesViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/BytesViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Format;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -77,10 +79,8 @@ final class BytesViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderConvertsAValueDataProvider
-     */
+    #[DataProvider('renderConvertsAValueDataProvider')]
+    #[Test]
     public function renderConvertsAValue(string $src, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/CaseViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/CaseViewHelperTest.php
index d9596df71a39..b4ac36f62f92 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/CaseViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/CaseViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Format;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\Core\ViewHelper\Exception;
@@ -80,10 +82,8 @@ final class CaseViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderConvertsAValueDataProvider
-     */
+    #[DataProvider('renderConvertsAValueDataProvider')]
+    #[Test]
     public function renderConvertsAValue(string $src, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -91,9 +91,7 @@ final class CaseViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperThrowsExceptionIfIncorrectModeIsGiven(): void
     {
         $this->expectException(Exception::class);
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/CropViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/CropViewHelperTest.php
index d518e2361597..b4a2d579bad4 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/CropViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/CropViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Format;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -51,10 +53,8 @@ final class CropViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderConvertsAValueDataProvider
-     */
+    #[DataProvider('renderConvertsAValueDataProvider')]
+    #[Test]
     public function renderConvertsAValue(string $src, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/CurrencyViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/CurrencyViewHelperTest.php
index 5a6fce0d9cca..41bba4cd22a3 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/CurrencyViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/CurrencyViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Format;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -91,10 +93,8 @@ final class CurrencyViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderConvertsAValueDataProvider
-     */
+    #[DataProvider('renderConvertsAValueDataProvider')]
+    #[Test]
     public function renderConvertsAValue(string $src, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/DateViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/DateViewHelperTest.php
index ebb958178914..b73fed6a0aec 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/DateViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/DateViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Format;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\Core\ViewHelper\Exception;
@@ -44,9 +46,7 @@ final class DateViewHelperTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperFormatsDateCorrectly(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -54,9 +54,7 @@ final class DateViewHelperTest extends FunctionalTestCase
         self::assertSame('1980-12-13', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperRespectsCustomFormat(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -64,9 +62,7 @@ final class DateViewHelperTest extends FunctionalTestCase
         self::assertSame('01.02.1980', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperAcceptsStrftimeFormat(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -74,9 +70,7 @@ final class DateViewHelperTest extends FunctionalTestCase
         self::assertSame('1980-02-01', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperReturnsEmptyStringIfChildrenIsEmpty(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -84,9 +78,7 @@ final class DateViewHelperTest extends FunctionalTestCase
         self::assertSame('', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperReturnsCurrentDateIfEmptyStringIsGiven(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -94,9 +86,7 @@ final class DateViewHelperTest extends FunctionalTestCase
         self::assertSame(date('Y-m-d', $GLOBALS['EXEC_TIME']), (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperUsesDefaultIfNoSystemFormatIsAvailable(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] = '';
@@ -105,9 +95,7 @@ final class DateViewHelperTest extends FunctionalTestCase
         self::assertSame('2014-02-08', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperUsesSystemFormat(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] = 'l, j. M y';
@@ -118,8 +106,8 @@ final class DateViewHelperTest extends FunctionalTestCase
 
     /**
      * No deprecation notice using PHP 8.1 should be thrown when format is null
-     * @test
      */
+    #[Test]
     public function viewHelperUsesSystemFormatWhenFormatWithNullValueIsGiven(): void
     {
         $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] = 'l, j. M y';
@@ -128,9 +116,7 @@ final class DateViewHelperTest extends FunctionalTestCase
         self::assertSame('Thursday, 17. Feb 22', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperThrowsExceptionWithOriginalMessageIfDateStringCantBeParsed(): void
     {
         $this->expectException(Exception::class);
@@ -140,9 +126,7 @@ final class DateViewHelperTest extends FunctionalTestCase
         (new TemplateView($context))->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperUsesChildNodesWithTimestamp(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -150,9 +134,7 @@ final class DateViewHelperTest extends FunctionalTestCase
         self::assertEquals('2013-02-03', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function dateArgumentHasPriorityOverChildNodes(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -160,9 +142,7 @@ final class DateViewHelperTest extends FunctionalTestCase
         self::assertEquals('1980-12-12', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function relativeDateCalculationWorksWithoutBase(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -170,9 +150,7 @@ final class DateViewHelperTest extends FunctionalTestCase
         self::assertEquals(date('Y'), (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function baseArgumentIsConsideredForRelativeDate(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -180,9 +158,7 @@ final class DateViewHelperTest extends FunctionalTestCase
         self::assertEquals('2016', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function baseArgumentDoesNotAffectAbsoluteTime(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -204,10 +180,8 @@ final class DateViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider viewHelperRespectsDefaultTimezoneForIntegerTimestampDataProvider
-     */
+    #[DataProvider('viewHelperRespectsDefaultTimezoneForIntegerTimestampDataProvider')]
+    #[Test]
     public function viewHelperRespectsDefaultTimezoneForIntegerTimestamp(string $timezone, string $expected): void
     {
         date_default_timezone_set($timezone);
@@ -243,10 +217,8 @@ final class DateViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider viewHelperRespectsDefaultTimezoneForStringTimestampDataProvider
-     */
+    #[DataProvider('viewHelperRespectsDefaultTimezoneForStringTimestampDataProvider')]
+    #[Test]
     public function viewHelperRespectsDefaultTimezoneForStringTimestamp(string $timeZone, string $date, string $expected): void
     {
         date_default_timezone_set($timeZone);
@@ -273,10 +245,8 @@ final class DateViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider viewHelperUsesIcuBasedPatternDataProvider
-     */
+    #[DataProvider('viewHelperUsesIcuBasedPatternDataProvider')]
+    #[Test]
     public function viewHelperUsesIcuBasedPattern(string $expected, string|int $pattern, ?string $locale = null): void
     {
         $date = '03/Oct/2000:14:55:36 +0400';
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/HtmlViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/HtmlViewHelperTest.php
index b908cbc226ed..4e168d8a21ae 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/HtmlViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/HtmlViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Format;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
@@ -69,10 +71,8 @@ final class HtmlViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider contentIsRenderedDataProvider
-     */
+    #[DataProvider('contentIsRenderedDataProvider')]
+    #[Test]
     public function contentIsRendered(string $fluidTemplateSource, string $expected): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/pages.csv');
@@ -103,10 +103,8 @@ final class HtmlViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider invalidInvocationIsDeterminedDataProvider
-     */
+    #[DataProvider('invalidInvocationIsDeterminedDataProvider')]
+    #[Test]
     public function invalidInvocationIsDetermined(string $fluidTemplateSource): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/pages.csv');
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/HtmlentitiesDecodeViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/HtmlentitiesDecodeViewHelperTest.php
index 98b9b60da955..0ee9e59e1930 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/HtmlentitiesDecodeViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/HtmlentitiesDecodeViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Format;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -25,9 +26,7 @@ final class HtmlentitiesDecodeViewHelperTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderUsesValueAsSourceIfSpecified(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -35,9 +34,7 @@ final class HtmlentitiesDecodeViewHelperTest extends FunctionalTestCase
         self::assertEquals('Some string', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderUsesChildnodesAsSourceIfSpecified(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -45,9 +42,7 @@ final class HtmlentitiesDecodeViewHelperTest extends FunctionalTestCase
         self::assertEquals('Some string', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderDoesNotModifyValueIfItDoesNotContainSpecialCharacters(): void
     {
         $source = 'This is a sample text without special characters. <> &©"\'';
@@ -56,9 +51,7 @@ final class HtmlentitiesDecodeViewHelperTest extends FunctionalTestCase
         self::assertEquals($source, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderDecodesSimpleString(): void
     {
         $source = 'Some special characters: &amp; &quot; \' &lt; &gt; *';
@@ -68,9 +61,7 @@ final class HtmlentitiesDecodeViewHelperTest extends FunctionalTestCase
         self::assertEquals($expectedResult, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderRespectsKeepQuoteArgument(): void
     {
         $source = 'Some special characters: &amp; &quot; \' &lt; &gt; *';
@@ -80,9 +71,7 @@ final class HtmlentitiesDecodeViewHelperTest extends FunctionalTestCase
         self::assertEquals($expectedResult, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderRespectsEncodingArgument(): void
     {
         $source = 'Some special characters: &amp; &quot; \' &lt; &gt; *';
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/HtmlentitiesViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/HtmlentitiesViewHelperTest.php
index 61d6aa9efb66..08a5a0d06970 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/HtmlentitiesViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/HtmlentitiesViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Format;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -25,9 +26,7 @@ final class HtmlentitiesViewHelperTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderUsesValueAsSourceIfSpecified(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -35,9 +34,7 @@ final class HtmlentitiesViewHelperTest extends FunctionalTestCase
         self::assertEquals('Some string', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderUsesChildnodesAsSourceIfSpecified(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -45,9 +42,7 @@ final class HtmlentitiesViewHelperTest extends FunctionalTestCase
         self::assertEquals('Some string', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderDoesNotModifyValueIfItDoesNotContainSpecialCharacters(): void
     {
         $source = 'This is a sample text without special characters.';
@@ -56,9 +51,7 @@ final class HtmlentitiesViewHelperTest extends FunctionalTestCase
         self::assertEquals($source, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderEncodesSimpleString(): void
     {
         $source = 'Some special characters: &©"\'';
@@ -68,9 +61,7 @@ final class HtmlentitiesViewHelperTest extends FunctionalTestCase
         self::assertEquals($expectedResult, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderRespectsKeepQuoteArgument(): void
     {
         $source = 'Some special characters: &©"\'';
@@ -80,9 +71,7 @@ final class HtmlentitiesViewHelperTest extends FunctionalTestCase
         self::assertEquals($expectedResult, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderRespectsEncodingArgument(): void
     {
         $source = mb_convert_encoding('Some special characters: &©"\'', 'ISO-8859-1', 'UTF-8');
@@ -92,9 +81,7 @@ final class HtmlentitiesViewHelperTest extends FunctionalTestCase
         self::assertEquals($expectedResult, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderConvertsAlreadyConvertedEntitiesByDefault(): void
     {
         $source = 'already &quot;encoded&quot;';
@@ -104,9 +91,7 @@ final class HtmlentitiesViewHelperTest extends FunctionalTestCase
         self::assertEquals($expectedResult, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderDoesNotConvertAlreadyConvertedEntitiesIfDoubleQuoteIsFalse(): void
     {
         $source = 'already &quot;encoded&quot;';
@@ -116,9 +101,7 @@ final class HtmlentitiesViewHelperTest extends FunctionalTestCase
         self::assertEquals($expectedResult, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderEscapesObjectIfPossible(): void
     {
         $toStringClass = new class () {
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/Nl2brViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/Nl2brViewHelperTest.php
index 539ab01ef624..2f33455267d2 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/Nl2brViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/Nl2brViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Format;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -43,10 +45,8 @@ final class Nl2brViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/NumberViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/NumberViewHelperTest.php
index 7b19f6e89643..64d6db2b9603 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/NumberViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/NumberViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Format;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -51,10 +53,8 @@ final class NumberViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/PaddingViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/PaddingViewHelperTest.php
index edb120418077..83cf0edf31ef 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/PaddingViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/PaddingViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Format;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -51,10 +53,8 @@ final class PaddingViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -62,9 +62,7 @@ final class PaddingViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function integersAreRespectedAsValue(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/StripTagsViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/StripTagsViewHelperTest.php
index 299941094789..b73aab593655 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/StripTagsViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/StripTagsViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Format;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -55,10 +57,8 @@ final class StripTagsViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -69,9 +69,8 @@ final class StripTagsViewHelperTest extends FunctionalTestCase
     /**
      * Ensures that objects are handled properly:
      * + class having __toString() method gets tags stripped off
-     *
-     * @test
      */
+    #[Test]
     public function renderEscapesObjectIfPossible(): void
     {
         $toStringClass = new class () {
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/TrimViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/TrimViewHelperTest.php
index 35be01ce59a0..d4452b8a7993 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/TrimViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/TrimViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Format;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\Core\ViewHelper\Exception;
@@ -98,10 +100,8 @@ final class TrimViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderConvertsAValueDataProvider
-     */
+    #[DataProvider('renderConvertsAValueDataProvider')]
+    #[Test]
     public function renderTrimAValue(string $src, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -109,9 +109,7 @@ final class TrimViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperThrowsExceptionIfIncorrectModeIsGiven(): void
     {
         $this->expectException(Exception::class);
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/UrlencodeViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/UrlencodeViewHelperTest.php
index da90333560d5..cb4c1b879457 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/UrlencodeViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Format/UrlencodeViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Format;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -47,10 +49,8 @@ final class UrlencodeViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -61,9 +61,8 @@ final class UrlencodeViewHelperTest extends FunctionalTestCase
     /**
      * Ensures that objects are handled properly:
      * + class having __toString() method gets tags stripped off
-     *
-     * @test
      */
+    #[Test]
     public function renderEscapesObjectIfPossible(): void
     {
         $toStringClass = new class () {
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/ImageViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/ImageViewHelperTest.php
index a970a94f1367..89cda5625721 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/ImageViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/ImageViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Resource\File;
@@ -81,10 +83,8 @@ final class ImageViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider invalidArgumentsDataProvider
-     */
+    #[DataProvider('invalidArgumentsDataProvider')]
+    #[Test]
     public function renderThrowsExceptionOnInvalidArguments(string $template, int $expectedExceptionCode, string $message): void
     {
         $this->expectException(Exception::class);
@@ -132,10 +132,8 @@ final class ImageViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider invalidArgumentsWithContentObjectPresentDataProvider
-     */
+    #[DataProvider('invalidArgumentsWithContentObjectPresentDataProvider')]
+    #[Test]
     public function renderThrowsExceptionWithContentObjectPresentOnInvalidArguments(string $template, int $expectedExceptionCode, string $message): void
     {
         $this->expectException(Exception::class);
@@ -177,10 +175,8 @@ final class ImageViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderReturnsExpectedMarkupDataProvider
-     */
+    #[DataProvider('renderReturnsExpectedMarkupDataProvider')]
+    #[Test]
     public function renderReturnsExpectedMarkup(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -188,9 +184,7 @@ final class ImageViewHelperTest extends FunctionalTestCase
         self::assertMatchesRegularExpression($expected, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderReturnsCorrectAltAttribute(): void
     {
         $imageServiceMock = $this->createMock(ImageService::class);
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/ActionViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/ActionViewHelperTest.php
index 0c9940cfb4e5..7c98f3f27ae9 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/ActionViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/ActionViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Link;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Domain\Repository\PageRepository;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -50,9 +52,7 @@ final class ActionViewHelperTest extends FunctionalTestCase
         ],
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionWithoutARequest(): void
     {
         $this->expectException(\RuntimeException::class);
@@ -63,9 +63,7 @@ final class ActionViewHelperTest extends FunctionalTestCase
         $view->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInFrontendCoreContextThrowsExceptionWithIncompleteArguments(): void
     {
         $request = new ServerRequest();
@@ -79,9 +77,7 @@ final class ActionViewHelperTest extends FunctionalTestCase
         $view->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendCoreContextThrowsExceptionWithIncompleteArguments(): void
     {
         $request = new ServerRequest('http://localhost/typo3/');
@@ -138,10 +134,8 @@ final class ActionViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderInFrontendWithCoreContextAndAllNecessaryExtbaseArgumentsDataProvider
-     */
+    #[DataProvider('renderInFrontendWithCoreContextAndAllNecessaryExtbaseArgumentsDataProvider')]
+    #[Test]
     public function renderInFrontendWithCoreContextAndAllNecessaryExtbaseArguments(string $template, string $expected, array $frontendTypoScriptSetupArray = [], array $tsfeConfigArray = []): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/pages.csv');
@@ -250,10 +244,8 @@ final class ActionViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderInFrontendWithExtbaseContextDataProvider
-     */
+    #[DataProvider('renderInFrontendWithExtbaseContextDataProvider')]
+    #[Test]
     public function renderInFrontendWithExtbaseContext(string $template, string $expected, array $frontendTypoScriptSetupArray = [], array $tsfeConfigArray = []): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/pages.csv');
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/EmailViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/EmailViewHelperTest.php
index cb03ccdd0e18..9082248abed8 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/EmailViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/EmailViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Link;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
@@ -32,9 +34,7 @@ final class EmailViewHelperTest extends FunctionalTestCase
         'EN' => ['id' => 0, 'title' => 'English', 'locale' => 'en_US.UTF8'],
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCreatesProperMarkupInBackend(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -42,9 +42,7 @@ final class EmailViewHelperTest extends FunctionalTestCase
         self::assertEquals('<a href="mailto:foo@example.com">send mail</a>', (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderCreatesProperMarkupInBackendWithEmptyChild(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -102,10 +100,8 @@ final class EmailViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderEncodesEmailInFrontendDataProvider
-     */
+    #[DataProvider('renderEncodesEmailInFrontendDataProvider')]
+    #[Test]
     public function renderEncodesEmailInFrontend(string $template, array $typoScript, string $expected): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/pages.csv');
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/ExternalViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/ExternalViewHelperTest.php
index 8a34ae0efa67..8e5e8e437652 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/ExternalViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/ExternalViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Link;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -43,10 +45,8 @@ final class ExternalViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/FileViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/FileViewHelperTest.php
index bdc63e6333fa..28713be67bee 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/FileViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/FileViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Link;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Resource\File;
@@ -69,9 +70,7 @@ final class FileViewHelperTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function throwsExceptionOnMissingFile(): void
     {
         $this->expectException(Exception::class);
@@ -82,9 +81,7 @@ final class FileViewHelperTest extends FunctionalTestCase
         (new TemplateView($context))->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderTagsForPublicFileTest(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -107,9 +104,7 @@ final class FileViewHelperTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderTagsForNonPublicFileTest(): void
     {
         // Set storage to non-public
@@ -137,9 +132,7 @@ final class FileViewHelperTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderTagsForPublicFileReferenceTest(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -162,9 +155,7 @@ final class FileViewHelperTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderTagsForNonPublicFileReferenceTest(): void
     {
         // Set storage to non-public
@@ -192,9 +183,7 @@ final class FileViewHelperTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderTagsForPublicProcessedFileTest(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -217,9 +206,7 @@ final class FileViewHelperTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderTagsForNonPublicProcessedFileTest(): void
     {
         // Set storage to non-public
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/PageViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/PageViewHelperTest.php
index 4c1aca80c5e9..7671b67982be 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/PageViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/PageViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Link;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Routing\Route;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Domain\Repository\PageRepository;
@@ -51,9 +53,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         ],
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionWithoutRequest(): void
     {
         $this->expectException(\RuntimeException::class);
@@ -64,9 +64,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         $view->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendCoreContextCreatesNoLinkWithoutRoute(): void
     {
         $request = new ServerRequest();
@@ -78,9 +76,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame('foo', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendCoreContextCreatesLinkWithRouteFromQueryString(): void
     {
         $request = new ServerRequest();
@@ -93,9 +89,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame('<a href="/typo3/module/web/layout?token=dummyToken&amp;id=42">foo</a>', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendCoreContextCreatesLinkWithRouteFromAdditionalParams(): void
     {
         $request = new ServerRequest();
@@ -107,9 +101,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame('<a href="/typo3/module/web/layout?token=dummyToken&amp;id=42">foo</a>', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendCoreContextCreatesLinkWithRouteFromRequest(): void
     {
         $request = new ServerRequest();
@@ -122,9 +114,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame('<a href="/typo3/module/web/layout?token=dummyToken&amp;id=42">foo</a>', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendCoreContextAddsSection(): void
     {
         $request = new ServerRequest('http://localhost/typo3/');
@@ -137,9 +127,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame('<a href="/typo3/module/web/layout?token=dummyToken&amp;id=42#mySection">foo</a>', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendCoreContextCreatesAbsoluteLink(): void
     {
         $request = new ServerRequest('http://localhost/typo3/', null, 'php://input', [], ['HTTP_HOST' => 'localhost', 'SCRIPT_NAME' => 'typo3/index.php']);
@@ -153,9 +141,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame('<a href="http://localhost/typo3/module/web/layout?token=dummyToken&amp;id=42">foo</a>', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendExtbaseContextCreatesLinkWithId(): void
     {
         $request = new ServerRequest('http://localhost/typo3/');
@@ -171,9 +157,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame('<a href="/typo3/module/web/layout?token=dummyToken&amp;id=42">foo</a>', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendExtbaseContextCreatesAbsoluteLinkWithId(): void
     {
         $request = new ServerRequest('http://localhost/typo3/', null, 'php://input', [], ['HTTP_HOST' => 'localhost', 'SCRIPT_NAME' => 'typo3/index.php']);
@@ -256,10 +240,8 @@ final class PageViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function renderInFrontendWithCoreContext(string $template, string $expected, array $frontendTypoScriptSetupArray = [], array $tsfeConfigArray = []): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/pages.csv');
@@ -287,10 +269,8 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, $result);
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function renderInFrontendWithExtbaseContext(string $template, string $expected, array $frontendTypoScriptSetupArray = [], array $tsfeConfigArray = []): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/pages.csv');
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/TypolinkViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/TypolinkViewHelperTest.php
index 232f06255b3d..27a8d1197a8e 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/TypolinkViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Link/TypolinkViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Link;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -138,10 +140,8 @@ final class TypolinkViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/pages.csv');
@@ -209,10 +209,8 @@ EOT
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderWithAssignedParametersDataProvider
-     */
+    #[DataProvider('renderWithAssignedParametersDataProvider')]
+    #[Test]
     public function renderWithAssignedParameters(string $template, array $assigns, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/MediaViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/MediaViewHelperTest.php
index 1a6d6889effb..91739ca184bf 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/MediaViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/MediaViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Resource\ResourceFactory;
 use TYPO3\CMS\Fluid\ViewHelpers\MediaViewHelper;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -48,10 +50,8 @@ final class MediaViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderReturnsExpectedMarkupDataProvider
-     */
+    #[DataProvider('renderReturnsExpectedMarkupDataProvider')]
+    #[Test]
     public function renderReturnsExpectedMarkup(string $file, array $arguments, string $expected): void
     {
         $file = $this->get(ResourceFactory::class)->getFileObjectFromCombinedIdentifier($file);
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/PageRendererViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/PageRendererViewHelperTest.php
index 376a14ffa76e..3f2b1f7150d0 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/PageRendererViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/PageRendererViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -59,10 +61,8 @@ final class PageRendererViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -76,9 +76,7 @@ final class PageRendererViewHelperTest extends FunctionalTestCase
         self::assertStringContainsString($expected, $pageRenderer->renderResponse()->getBody()->__toString());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderResolvesLabelWithExtbaseRequest(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Sanitize/HtmlViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Sanitize/HtmlViewHelperTest.php
index d30a4597c104..14237548f74f 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Sanitize/HtmlViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Sanitize/HtmlViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Sanitize;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Log\LogLevel;
 use TYPO3\CMS\Core\Log\LogRecord;
 use TYPO3\CMS\Core\Tests\Functional\Fixtures\Log\DummyWriter;
@@ -56,10 +58,8 @@ final class HtmlViewHelperTest extends FunctionalTestCase
         return DefaultSanitizerBuilderTest::isSanitizedDataProvider();
     }
 
-    /**
-     * @test
-     * @dataProvider isSanitizedDataProvider
-     */
+    #[DataProvider('isSanitizedDataProvider')]
+    #[Test]
     public function isSanitizedUsingNodeInstruction(string $payload, string $expectation): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -67,10 +67,8 @@ final class HtmlViewHelperTest extends FunctionalTestCase
         self::assertSame($expectation, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     * @dataProvider isSanitizedDataProvider
-     */
+    #[DataProvider('isSanitizedDataProvider')]
+    #[Test]
     public function isSanitizedUsingInlineInstruction(string $payload, string $expectation): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -80,9 +78,7 @@ final class HtmlViewHelperTest extends FunctionalTestCase
         self::assertSame($expectation, $view->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function incidentIsLogged(): void
     {
         $templatePath = __DIR__ . '/Fixtures/Template.html';
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Security/IfAuthenticatedViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Security/IfAuthenticatedViewHelperTest.php
index 9a32f8285e4a..a5d0e3e8c219 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Security/IfAuthenticatedViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Security/IfAuthenticatedViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Security;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\UserAspect;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -29,9 +30,7 @@ final class IfAuthenticatedViewHelperTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperRendersThenChildIfFeUserIsLoggedIn(): void
     {
         $user = new FrontendUserAuthentication();
@@ -45,9 +44,7 @@ final class IfAuthenticatedViewHelperTest extends FunctionalTestCase
         self::assertEquals('then child', (new TemplateView($renderingContext))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function viewHelperRendersElseChildIfFeUserIsNotLoggedIn(): void
     {
         $context = new Context();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Security/IfHasRoleViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Security/IfHasRoleViewHelperTest.php
index 139f4f93ff0f..cbba5ce99043 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Security/IfHasRoleViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Security/IfHasRoleViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Security;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\UserAspect;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -65,10 +67,8 @@ final class IfHasRoleViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Transform/HtmlViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Transform/HtmlViewHelperTest.php
index 11ff6b59209e..2fc2ac0a6aa6 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Transform/HtmlViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Transform/HtmlViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Transform;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Site\Entity\NullSite;
@@ -108,10 +110,8 @@ final class HtmlViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider isTransformedDataProvider
-     */
+    #[DataProvider('isTransformedDataProvider')]
+    #[Test]
     public function isTransformed(string $payload, string $expectation): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -145,10 +145,8 @@ final class HtmlViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider isTransformedWithSelectorDataProvider
-     */
+    #[DataProvider('isTransformedWithSelectorDataProvider')]
+    #[Test]
     public function isTransformedWithSelector(string $selector, string $payload, string $expectation): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -192,10 +190,8 @@ final class HtmlViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider isTransformedWithOnFailureDataProvider
-     */
+    #[DataProvider('isTransformedWithOnFailureDataProvider')]
+    #[Test]
     public function isTransformedWithOnFailure(?string $onFailure, string $payload, string $expectation): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/TranslateViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/TranslateViewHelperTest.php
index 3b9aee7fbe72..1d43d1edaaf7 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/TranslateViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/TranslateViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -45,9 +47,7 @@ final class TranslateViewHelperTest extends FunctionalTestCase
         'typo3/sysext/fluid/Tests/Functional/Fixtures/Extensions/test_translate',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionIfNoKeyOrIdParameterIsGiven(): void
     {
         $this->expectException(Exception::class);
@@ -57,9 +57,7 @@ final class TranslateViewHelperTest extends FunctionalTestCase
         (new TemplateView($context))->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionIfOnlyDefaultValueIsGiven(): void
     {
         $this->expectException(Exception::class);
@@ -69,9 +67,7 @@ final class TranslateViewHelperTest extends FunctionalTestCase
         (new TemplateView($context))->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionInNonExtbaseContextWithoutExtensionNameAndDefaultValue(): void
     {
         $this->expectException(\RuntimeException::class);
@@ -163,10 +159,8 @@ final class TranslateViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderReturnsStringInNonExtbaseContextDataProvider
-     */
+    #[DataProvider('renderReturnsStringInNonExtbaseContextDataProvider')]
+    #[Test]
     public function renderReturnsStringInNonExtbaseContext(string $template, string $expected): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -217,10 +211,9 @@ final class TranslateViewHelperTest extends FunctionalTestCase
     /**
      * Analyzes that the frontend request can resolve the locale from the frontend request,
      * both LLL: prefix and extensionName + id combinations.
-     *
-     * @test
-     * @dataProvider fallbackChainInNonExtbaseContextDataProvider
      */
+    #[DataProvider('fallbackChainInNonExtbaseContextDataProvider')]
+    #[Test]
     public function renderInNonExtbaseContextHandlesLocaleFromFrontendRequest(string $template, string $expected): void
     {
         $request = new ServerRequest();
@@ -233,9 +226,7 @@ final class TranslateViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInNonExtbaseContextHandlesLocaleObjectAsLanguageKey(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -247,9 +238,7 @@ final class TranslateViewHelperTest extends FunctionalTestCase
         self::assertSame('DE label', $templateView->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInNonExtbaseContextHandlesLocaleObjectAsLanguageKeyWithFallback(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -261,9 +250,7 @@ final class TranslateViewHelperTest extends FunctionalTestCase
         self::assertSame('DE label', $templateView->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInNonExtbaseContextHandlesLocaleObjectAsLanguageKeyWithoutFallback(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -353,10 +340,8 @@ final class TranslateViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderReturnsStringInExtbaseContextDataProvider
-     */
+    #[DataProvider('renderReturnsStringInExtbaseContextDataProvider')]
+    #[Test]
     public function renderReturnsStringInExtbaseContext(string $template, string $expected): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -372,9 +357,7 @@ final class TranslateViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, (new TemplateView($context))->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInExtbaseContextHandlesLocaleObjectAsLanguageKey(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -391,9 +374,7 @@ final class TranslateViewHelperTest extends FunctionalTestCase
         self::assertSame('DE label', $templateView->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInExtbaseContextHandlesLocaleObjectAsLanguageKeyWithFallback(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -410,9 +391,7 @@ final class TranslateViewHelperTest extends FunctionalTestCase
         self::assertSame('DE label', $templateView->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInExtbaseContextHandlesLocaleObjectAsLanguageKeyWithoutFallback(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
@@ -429,9 +408,7 @@ final class TranslateViewHelperTest extends FunctionalTestCase
         self::assertSame('DE_AT label', $templateView->render());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInExtbaseFrontendContextHandlesLabelOverrideWithTypoScriptInDefaultLanguage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/pages.csv');
@@ -458,9 +435,7 @@ EOT
 
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInExtbaseFrontendContextHandlesLabelOverrideWithTypoScriptInLocalizedPage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/pages.csv');
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ActionViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ActionViewHelperTest.php
index 96a2d61d7351..e0148ffac38a 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ActionViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ActionViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Uri;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Domain\Repository\PageRepository;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -50,9 +52,7 @@ final class ActionViewHelperTest extends FunctionalTestCase
         ],
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionWithoutARequest(): void
     {
         $this->expectException(\RuntimeException::class);
@@ -63,9 +63,7 @@ final class ActionViewHelperTest extends FunctionalTestCase
         $view->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInFrontendCoreContextThrowsExceptionWithIncompleteArguments(): void
     {
         $request = new ServerRequest();
@@ -79,9 +77,7 @@ final class ActionViewHelperTest extends FunctionalTestCase
         $view->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendCoreContextThrowsExceptionWithIncompleteArguments(): void
     {
         $request = new ServerRequest('http://localhost/typo3/');
@@ -113,10 +109,8 @@ final class ActionViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderInFrontendWithCoreContextAndAllNecessaryExtbaseArgumentsDataProvider
-     */
+    #[DataProvider('renderInFrontendWithCoreContextAndAllNecessaryExtbaseArgumentsDataProvider')]
+    #[Test]
     public function renderInFrontendWithCoreContextAndAllNecessaryExtbaseArguments(string $template, string $expected): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/pages.csv');
@@ -190,10 +184,8 @@ final class ActionViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderInFrontendWithExtbaseContextDataProvider
-     */
+    #[DataProvider('renderInFrontendWithExtbaseContextDataProvider')]
+    #[Test]
     public function renderInFrontendWithExtbaseContext(string $template, string $expected): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/pages.csv');
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ExternalViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ExternalViewHelperTest.php
index da5bd77b04c4..d78fc018abf2 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ExternalViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ExternalViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Uri;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -47,10 +49,8 @@ final class ExternalViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ImageViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ImageViewHelperTest.php
index 235b82f5e7c6..0a1019996dc5 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ImageViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ImageViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Uri;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters;
@@ -76,10 +78,8 @@ final class ImageViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider invalidArgumentsDataProvider
-     */
+    #[DataProvider('invalidArgumentsDataProvider')]
+    #[Test]
     public function renderThrowsExceptionOnInvalidArguments(string $template, int $expectedExceptionCode, string $message): void
     {
         $this->expectException(Exception::class);
@@ -127,10 +127,8 @@ final class ImageViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider invalidArgumentsWithContentObjectPresentDataProvider
-     */
+    #[DataProvider('invalidArgumentsWithContentObjectPresentDataProvider')]
+    #[Test]
     public function renderThrowsExceptionWithContentObjectPresentOnInvalidArguments(string $template, int $expectedExceptionCode, string $message): void
     {
         $this->expectException(Exception::class);
@@ -172,10 +170,8 @@ final class ImageViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderReturnsExpectedMarkupDataProvider
-     */
+    #[DataProvider('renderReturnsExpectedMarkupDataProvider')]
+    #[Test]
     public function renderReturnsExpectedMarkup(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/PageViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/PageViewHelperTest.php
index 64a63c633e01..3b11d63252ad 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/PageViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/PageViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Uri;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Routing\Route;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Domain\Repository\PageRepository;
@@ -48,9 +50,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         ],
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionWithoutRequest(): void
     {
         $this->expectException(\RuntimeException::class);
@@ -61,9 +61,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         $view->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendCoreContextCreatesNoUriWithoutRoute(): void
     {
         $request = new ServerRequest('http://localhost/typo3/');
@@ -75,9 +73,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame('', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendCoreContextCreatesUriWithRouteFromQueryString(): void
     {
         $request = new ServerRequest('http://localhost/typo3/');
@@ -90,9 +86,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame('/typo3/module/web/layout?token=dummyToken&amp;id=42', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendCoreContextCreatesUriWithRouteFromAdditionalParams(): void
     {
         $request = new ServerRequest('http://localhost/typo3/');
@@ -104,9 +98,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame('/typo3/module/web/layout?token=dummyToken&amp;id=42', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendCoreContextCreatesUriWithRouteFromRequest(): void
     {
         $request = new ServerRequest('http://localhost/typo3/');
@@ -119,9 +111,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame('/typo3/module/web/layout?token=dummyToken&amp;id=42', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendCoreContextAddsSection(): void
     {
         $request = new ServerRequest('http://localhost/typo3/');
@@ -134,9 +124,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame('/typo3/module/web/layout?token=dummyToken&amp;id=42#mySection', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendCoreContextCreatesAbsoluteUri(): void
     {
         $request = new ServerRequest('http://localhost/typo3/', null, 'php://input', [], ['HTTP_HOST' => 'localhost', 'SCRIPT_NAME' => 'typo3/index.php']);
@@ -150,9 +138,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame('http://localhost/typo3/module/web/layout?token=dummyToken&amp;id=42', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendExtbaseContextCreatesUriWithId(): void
     {
         $request = new ServerRequest('http://localhost/typo3/');
@@ -168,9 +154,7 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame('/typo3/module/web/layout?token=dummyToken&amp;id=42', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderInBackendExtbaseContextCreatesAbsoluteUriWithId(): void
     {
         $request = new ServerRequest('http://localhost/typo3/', null, 'php://input', [], ['HTTP_HOST' => 'localhost', 'SCRIPT_NAME' => 'typo3/index.php']);
@@ -228,10 +212,8 @@ final class PageViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function renderInFrontendWithCoreContext(string $template, string $expected): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/pages.csv');
@@ -253,10 +235,8 @@ final class PageViewHelperTest extends FunctionalTestCase
         self::assertSame($expected, $result);
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function renderInFrontendWithExtbaseContext(string $template, string $expected): void
     {
         $this->importCSVDataSet(__DIR__ . '/../../Fixtures/pages.csv');
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ResourceViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ResourceViewHelperTest.php
index e4dac65246dc..d7f51b693240 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ResourceViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/ResourceViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Uri;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters;
 use TYPO3\CMS\Extbase\Mvc\Request;
@@ -28,9 +30,7 @@ final class ResourceViewHelperTest extends FunctionalTestCase
 {
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderingFailsWithNonExtSyntaxWithoutExtensionNameWithPsr7Request()
     {
         $this->expectException(\RuntimeException::class);
@@ -41,9 +41,7 @@ final class ResourceViewHelperTest extends FunctionalTestCase
         (new TemplateView($context))->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderingFailsWhenExtensionNameNotSetInExtbaseRequest(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -71,10 +69,8 @@ final class ResourceViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderWithoutRequestDataProvider
-     */
+    #[DataProvider('renderWithoutRequestDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
@@ -106,10 +102,8 @@ final class ResourceViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderWithExtbaseRequestDataProvider
-     */
+    #[DataProvider('renderWithExtbaseRequestDataProvider')]
+    #[Test]
     public function renderWithExtbaseRequest(string $template, string $expected): void
     {
         $extbaseRequestParameters = new ExtbaseRequestParameters();
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/TypolinkViewHelperTest.php b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/TypolinkViewHelperTest.php
index 05fa426e1390..57c3eeb3b8b9 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/TypolinkViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewHelpers/Uri/TypolinkViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional\ViewHelpers\Uri;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
@@ -108,10 +110,8 @@ final class TypolinkViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderDataProvider
-     */
+    #[DataProvider('renderDataProvider')]
+    #[Test]
     public function render(string $template, string $expected): void
     {
         (new ConnectionPool())->getConnectionForTable('sys_template')->insert('sys_template', [
diff --git a/typo3/sysext/fluid/Tests/Functional/ViewhelperLibraryTest.php b/typo3/sysext/fluid/Tests/Functional/ViewhelperLibraryTest.php
index 1409f3e2db7d..e987e666805c 100644
--- a/typo3/sysext/fluid/Tests/Functional/ViewhelperLibraryTest.php
+++ b/typo3/sysext/fluid/Tests/Functional/ViewhelperLibraryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\Functional;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\View\TemplateView;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -29,9 +30,8 @@ final class ViewhelperLibraryTest extends FunctionalTestCase
      * Fluid ViewHelper classes. These libraries usually don't use TYPO3's
      * dependency injection container and thus need to be supported separately
      * in TYPO3's ViewHelperResolver implementation.
-     *
-     * @test
      */
+    #[Test]
     public function viewhelperLibraryCanBeLoadedTest(): void
     {
         $view = new TemplateView();
diff --git a/typo3/sysext/fluid/Tests/FunctionalDeprecated/ViewHelpers/Be/Labels/CshViewHelperTest.php b/typo3/sysext/fluid/Tests/FunctionalDeprecated/ViewHelpers/Be/Labels/CshViewHelperTest.php
index 6597e28e4515..d273bc356e72 100644
--- a/typo3/sysext/fluid/Tests/FunctionalDeprecated/ViewHelpers/Be/Labels/CshViewHelperTest.php
+++ b/typo3/sysext/fluid/Tests/FunctionalDeprecated/ViewHelpers/Be/Labels/CshViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Fluid\Tests\FunctionalDeprecated\ViewHelpers\Be\Labels;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
@@ -73,10 +75,8 @@ final class CshViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider isRenderedDataProvider
-     */
+    #[DataProvider('isRenderedDataProvider')]
+    #[Test]
     public function isRendered(string $source, array $variables, string $expectation): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/fluid_styled_content/Tests/Functional/Rendering/SecureHtmlRenderingTest.php b/typo3/sysext/fluid_styled_content/Tests/Functional/Rendering/SecureHtmlRenderingTest.php
index a41ed8324c94..df9d1991ec34 100644
--- a/typo3/sysext/fluid_styled_content/Tests/Functional/Rendering/SecureHtmlRenderingTest.php
+++ b/typo3/sysext/fluid_styled_content/Tests/Functional/Rendering/SecureHtmlRenderingTest.php
@@ -15,6 +15,8 @@
 
 namespace TYPO3\CMS\FluidStyledContent\Tests\Functional\Rendering;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\ResponseInterface;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
@@ -120,10 +122,8 @@ final class SecureHtmlRenderingTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider defaultParseFuncRteAvoidsCrossSiteScriptingDataProvider
-     */
+    #[DataProvider('defaultParseFuncRteAvoidsCrossSiteScriptingDataProvider')]
+    #[Test]
     public function defaultParseFuncRteAvoidCrossSiteScripting(string $payload, string $expectation): void
     {
         $instructions = [
@@ -200,10 +200,8 @@ final class SecureHtmlRenderingTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider htmlViewHelperAvoidsCrossSiteScriptingDataProvider
-     */
+    #[DataProvider('htmlViewHelperAvoidsCrossSiteScriptingDataProvider')]
+    #[Test]
     public function htmlViewHelperAvoidsCrossSiteScripting(string $type, string $payload, string $expectation): void
     {
         $instructions = [
@@ -252,10 +250,9 @@ final class SecureHtmlRenderingTest extends FunctionalTestCase
 
     /**
      * Uses a custom parseFunc that does not have `parseFunc.htmlSanitize` defined (which is deprecated).
-     *
-     * @test
-     * @dataProvider customParseFuncAvoidsCrossSiteScriptingDataProvider
      */
+    #[DataProvider('customParseFuncAvoidsCrossSiteScriptingDataProvider')]
+    #[Test]
     public function customParseFuncAvoidCrossSiteScripting(string $payload, string $expectation): void
     {
         $instructions = [
diff --git a/typo3/sysext/fluid_styled_content/Tests/Functional/Tca/ContentVisibleFieldsTest.php b/typo3/sysext/fluid_styled_content/Tests/Functional/Tca/ContentVisibleFieldsTest.php
index e40ddfb5d6a6..47fc40c78166 100644
--- a/typo3/sysext/fluid_styled_content/Tests/Functional/Tca/ContentVisibleFieldsTest.php
+++ b/typo3/sysext/fluid_styled_content/Tests/Functional/Tca/ContentVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\FluidStyledContent\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -54,9 +55,7 @@ final class ContentVisibleFieldsTest extends FunctionalTestCase
         'categories',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function contentFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/form/Tests/Functional/Domain/Model/Renderable/AbstractRenderableTest.php b/typo3/sysext/form/Tests/Functional/Domain/Model/Renderable/AbstractRenderableTest.php
index 8026996b23cd..2f42c1b34c67 100644
--- a/typo3/sysext/form/Tests/Functional/Domain/Model/Renderable/AbstractRenderableTest.php
+++ b/typo3/sysext/form/Tests/Functional/Domain/Model/Renderable/AbstractRenderableTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Form\Tests\Functional\Domain\Model\Renderable;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -42,9 +43,7 @@ final class AbstractRenderableTest extends FunctionalTestCase
         $this->subject = $this->buildAbstractRenderable();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setOptionsResetsValidatorsIfDefined(): void
     {
         $this->subject->setOptions(['validators' => [
diff --git a/typo3/sysext/form/Tests/Functional/Domain/Runtime/FormRuntimeTest.php b/typo3/sysext/form/Tests/Functional/Domain/Runtime/FormRuntimeTest.php
index a23e368c59d2..b01383a07ba0 100644
--- a/typo3/sysext/form/Tests/Functional/Domain/Runtime/FormRuntimeTest.php
+++ b/typo3/sysext/form/Tests/Functional/Domain/Runtime/FormRuntimeTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Form\Tests\Functional\Domain\Runtime;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters;
@@ -49,9 +50,7 @@ final class FormRuntimeTest extends FunctionalTestCase
         $this->request = $this->buildExtbaseRequest();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionIfFormDefinitionReturnsNoRendererClassName(): void
     {
         $formDefinition = $this->buildFormDefinition();
@@ -64,9 +63,7 @@ final class FormRuntimeTest extends FunctionalTestCase
         $formRuntime->render();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionIfRendererClassNameInstanceDoesNotImplementRendererInterface(): void
     {
         $formDefinition = $this->buildFormDefinition();
diff --git a/typo3/sysext/form/Tests/Functional/Mvc/Validation/CountValidatorTest.php b/typo3/sysext/form/Tests/Functional/Mvc/Validation/CountValidatorTest.php
index 787d9eb0c7a8..fcdb5186ad29 100644
--- a/typo3/sysext/form/Tests/Functional/Mvc/Validation/CountValidatorTest.php
+++ b/typo3/sysext/form/Tests/Functional/Mvc/Validation/CountValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Form\Tests\Functional\Mvc\Validation;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -34,9 +35,7 @@ final class CountValidatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function CountValidatorReturnsFalseIfInputItemsCountIsEqualToMaximum(): void
     {
         $options = ['minimum' => 1, 'maximum' => 2];
@@ -49,9 +48,7 @@ final class CountValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate($input)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function CountValidatorReturnsFalseIfInputItemsCountIsEqualToMinimum(): void
     {
         $options = ['minimum' => 2, 'maximum' => 3];
@@ -64,9 +61,7 @@ final class CountValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate($input)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function CountValidatorReturnsFalseIfInputItemsCountIsEqualToMinimumAndMaximum(): void
     {
         $options = ['minimum' => 2, 'maximum' => 2];
@@ -79,9 +74,7 @@ final class CountValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate($input)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function CountValidatorReturnsTrueIfInputCountHasMoreItemsAsMaximumValue(): void
     {
         $options = ['minimum' => 1, 'maximum' => 2];
@@ -95,9 +88,7 @@ final class CountValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate($input)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function CountValidatorReturnsTrueIfInputCountHasLessItemsAsMinimumValue(): void
     {
         $options = ['minimum' => 2, 'maximum' => 3];
diff --git a/typo3/sysext/form/Tests/Functional/Mvc/Validation/DateRangeValidatorTest.php b/typo3/sysext/form/Tests/Functional/Mvc/Validation/DateRangeValidatorTest.php
index d59abb3b5b84..b6c5a77d9749 100644
--- a/typo3/sysext/form/Tests/Functional/Mvc/Validation/DateRangeValidatorTest.php
+++ b/typo3/sysext/form/Tests/Functional/Mvc/Validation/DateRangeValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Form\Tests\Functional\Mvc\Validation;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -35,9 +36,7 @@ final class DateRangeValidatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validateOptionsThrowsExceptionIfMinimumOptionIsInvalid(): void
     {
         $this->expectException(InvalidValidationOptionsException::class);
@@ -48,9 +47,7 @@ final class DateRangeValidatorTest extends FunctionalTestCase
         $validator->validate(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validateOptionsThrowsExceptionIfMaximumOptionIsInvalid(): void
     {
         $this->expectException(InvalidValidationOptionsException::class);
@@ -61,9 +58,7 @@ final class DateRangeValidatorTest extends FunctionalTestCase
         $validator->validate(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function DateRangeValidatorReturnsTrueIfInputIsNoDateTime(): void
     {
         $options = ['minimum' => '2018-03-17', 'maximum' => '2018-03-17'];
@@ -72,9 +67,7 @@ final class DateRangeValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate(true)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function DateRangeValidatorReturnsTrueIfInputIsLowerThanMinimumOption(): void
     {
         $input = \DateTime::createFromFormat('Y-m-d', '2018-03-17');
@@ -84,9 +77,7 @@ final class DateRangeValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate($input)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function DateRangeValidatorReturnsFalseIfInputIsEqualsMinimumOption(): void
     {
         $input = \DateTime::createFromFormat('Y-m-d', '2018-03-18');
@@ -96,9 +87,7 @@ final class DateRangeValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate($input)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function DateRangeValidatorReturnsFalseIfInputIsGreaterThanMinimumOption(): void
     {
         $input = \DateTime::createFromFormat('Y-m-d', '2018-03-19');
@@ -108,9 +97,7 @@ final class DateRangeValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate($input)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function DateRangeValidatorReturnsFalseIfInputIsLowerThanMaximumOption(): void
     {
         $input = \DateTime::createFromFormat('Y-m-d', '2018-03-17');
@@ -120,9 +107,7 @@ final class DateRangeValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate($input)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function DateRangeValidatorReturnsFalseIfInputIsEqualsMaximumOption(): void
     {
         $input = \DateTime::createFromFormat('Y-m-d', '2018-03-18');
@@ -132,9 +117,7 @@ final class DateRangeValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate($input)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function DateRangeValidatorReturnsTrueIfInputIsGreaterThanMaximumOption(): void
     {
         $input = \DateTime::createFromFormat('Y-m-d', '2018-03-19');
diff --git a/typo3/sysext/form/Tests/Functional/Mvc/Validation/EmptyValidatorTest.php b/typo3/sysext/form/Tests/Functional/Mvc/Validation/EmptyValidatorTest.php
index 115de40f31ec..9539283d07c2 100644
--- a/typo3/sysext/form/Tests/Functional/Mvc/Validation/EmptyValidatorTest.php
+++ b/typo3/sysext/form/Tests/Functional/Mvc/Validation/EmptyValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Form\Tests\Functional\Mvc\Validation;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -34,9 +35,7 @@ final class EmptyValidatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function EmptyValidatorReturnsFalseIfInputIsEmptyString(): void
     {
         $validator = new EmptyValidator();
@@ -45,9 +44,7 @@ final class EmptyValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate($input)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function EmptyValidatorReturnsFalseIfInputIsNull(): void
     {
         $validator = new EmptyValidator();
@@ -56,9 +53,7 @@ final class EmptyValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate($input)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function EmptyValidatorReturnsFalseIfInputIsEmptyArray(): void
     {
         $validator = new EmptyValidator();
@@ -67,9 +62,7 @@ final class EmptyValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate($input)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function EmptyValidatorReturnsFalseIfInputIsZero(): void
     {
         $validator = new EmptyValidator();
@@ -78,9 +71,7 @@ final class EmptyValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate($input)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function EmptyValidatorReturnsFalseIfInputIsZeroAsString(): void
     {
         $validator = new EmptyValidator();
@@ -89,9 +80,7 @@ final class EmptyValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate($input)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function EmptyValidatorReturnsTrueIfInputIsNonEmptyString(): void
     {
         $validator = new EmptyValidator();
@@ -100,9 +89,7 @@ final class EmptyValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate($input)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function EmptyValidatorReturnsTrueIfInputIsNonEmptyArray(): void
     {
         $validator = new EmptyValidator();
diff --git a/typo3/sysext/form/Tests/Functional/Mvc/Validation/FileSizeValidatorTest.php b/typo3/sysext/form/Tests/Functional/Mvc/Validation/FileSizeValidatorTest.php
index 9d21665664c2..bd76a038cdfd 100644
--- a/typo3/sysext/form/Tests/Functional/Mvc/Validation/FileSizeValidatorTest.php
+++ b/typo3/sysext/form/Tests/Functional/Mvc/Validation/FileSizeValidatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Form\Tests\Functional\Mvc\Validation;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -37,9 +38,7 @@ final class FileSizeValidatorTest extends FunctionalTestCase
         $GLOBALS['TYPO3_REQUEST'] = $request;
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function FileSizeValidatorThrowsExceptionIfMinimumOptionIsInvalid(): void
     {
         $this->expectException(InvalidValidationOptionsException::class);
@@ -50,9 +49,7 @@ final class FileSizeValidatorTest extends FunctionalTestCase
         $validator->validate(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function FileSizeValidatorThrowsExceptionIfMaximumOptionIsInvalid(): void
     {
         $this->expectException(InvalidValidationOptionsException::class);
@@ -63,9 +60,7 @@ final class FileSizeValidatorTest extends FunctionalTestCase
         $validator->validate(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function FileSizeValidatorHasErrorsIfFileResourceSizeIsToSmall(): void
     {
         $options = ['minimum' => '1M', 'maximum' => '10M'];
@@ -76,9 +71,7 @@ final class FileSizeValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate($file)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function FileSizeValidatorHasErrorsIfFileResourceSizeIsToBig(): void
     {
         $options = ['minimum' => '1M', 'maximum' => '1M'];
@@ -89,9 +82,7 @@ final class FileSizeValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate($file)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function FileSizeValidatorHasNoErrorsIfInputIsEmptyString(): void
     {
         $options = ['minimum' => '0B', 'maximum' => '1M'];
@@ -100,9 +91,7 @@ final class FileSizeValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate('')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function FileSizeValidatorHasErrorsIfInputIsNoFileResource(): void
     {
         $options = ['minimum' => '0B', 'maximum' => '1M'];
diff --git a/typo3/sysext/form/Tests/Functional/Mvc/Validation/MimeTypeValidatorTest.php b/typo3/sysext/form/Tests/Functional/Mvc/Validation/MimeTypeValidatorTest.php
index 15e7b5bc675d..ec0d0f1a1ce7 100644
--- a/typo3/sysext/form/Tests/Functional/Mvc/Validation/MimeTypeValidatorTest.php
+++ b/typo3/sysext/form/Tests/Functional/Mvc/Validation/MimeTypeValidatorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Form\Tests\Functional\Mvc\Validation;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -53,9 +55,7 @@ final class MimeTypeValidatorTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function MimeTypeValidatorThrowsExceptionIfAllowedMimeTypesOptionIsString(): void
     {
         $this->expectException(InvalidValidationOptionsException::class);
@@ -66,9 +66,7 @@ final class MimeTypeValidatorTest extends FunctionalTestCase
         $validator->validate(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function MimeTypeValidatorThrowsExceptionIfAllowedMimeTypesOptionIsEmptyArray(): void
     {
         $this->expectException(InvalidValidationOptionsException::class);
@@ -79,9 +77,7 @@ final class MimeTypeValidatorTest extends FunctionalTestCase
         $validator->validate(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function MimeTypeValidatorReturnsTrueIfFileResourceIsNotAllowedMimeType(): void
     {
         $options = ['allowedMimeTypes' => ['image/jpeg']];
@@ -92,9 +88,7 @@ final class MimeTypeValidatorTest extends FunctionalTestCase
         self::assertTrue($validator->validate($file)->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function MimeTypeValidatorReturnsFalseIfInputIsEmptyString(): void
     {
         $options = ['allowedMimeTypes' => ['fake']];
@@ -103,9 +97,7 @@ final class MimeTypeValidatorTest extends FunctionalTestCase
         self::assertFalse($validator->validate('')->hasErrors());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function MimeTypeValidatorReturnsTrueIfInputIsNoFileResource(): void
     {
         $options = ['allowedMimeTypes' => ['fake']];
@@ -126,10 +118,8 @@ final class MimeTypeValidatorTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider fileExtensionMatchesMimeTypesDataProvider
-     */
+    #[DataProvider('fileExtensionMatchesMimeTypesDataProvider')]
+    #[Test]
     public function fileExtensionMatchesMimeTypes(string $fileName, string $fileMimeType, array $allowedMimeTypes, bool $isValid): void
     {
         $options = ['allowedMimeTypes' => $allowedMimeTypes];
@@ -200,9 +190,9 @@ final class MimeTypeValidatorTest extends FunctionalTestCase
      * @param array<string, int|string> $uploadData
      * @param List<string> $allowedMimeTypes
      * @param List<int> $expectedErrorCodes
-     * @test
-     * @dataProvider validateHandlesMimeTypesOfFilesDataProvider
      */
+    #[DataProvider('validateHandlesMimeTypesOfFilesDataProvider')]
+    #[Test]
     public function validateHandlesMimeTypesOfFiles(array $uploadData, array $allowedMimeTypes, array $expectedErrorCodes = []): void
     {
         $uploadData['tmp_name'] = $this->instancePath . '/tmp/' . $uploadData['tmp_name'];
diff --git a/typo3/sysext/form/Tests/Functional/RequestHandling/RequestHandlingTest.php b/typo3/sysext/form/Tests/Functional/RequestHandling/RequestHandlingTest.php
index 69657474bb43..e7d051de49fa 100644
--- a/typo3/sysext/form/Tests/Functional/RequestHandling/RequestHandlingTest.php
+++ b/typo3/sysext/form/Tests/Functional/RequestHandling/RequestHandlingTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Form\Tests\Functional\RequestHandling;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\Mailer\SentMessage;
 use TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend;
 use TYPO3\CMS\Core\Cache\Frontend\VariableFrontend;
@@ -231,10 +233,8 @@ final class RequestHandlingTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider theCachingBehavesTheSameForAllFormIntegrationVariantsDataProvider
-     */
+    #[DataProvider('theCachingBehavesTheSameForAllFormIntegrationVariantsDataProvider')]
+    #[Test]
     public function theCachingBehavesTheSameForAllFormIntegrationVariants(string $formIdentifier, string $formNamePrefix): void
     {
         $uri = static::ROOT_PAGE_BASE_URI . '/form';
@@ -366,10 +366,8 @@ final class RequestHandlingTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider formRendersUncachedIfTheActionTargetIsCalledViaHttpGetDataProvider
-     */
+    #[DataProvider('formRendersUncachedIfTheActionTargetIsCalledViaHttpGetDataProvider')]
+    #[Test]
     public function formRendersUncachedIfTheActionTargetIsCalledViaHttpGet(string $formIdentifier): void
     {
         $uri = static::ROOT_PAGE_BASE_URI . '/form';
@@ -461,10 +459,8 @@ final class RequestHandlingTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider theHoneypotElementChangesWithEveryCallOfTheFirstFormStepDataProvider
-     */
+    #[DataProvider('theHoneypotElementChangesWithEveryCallOfTheFirstFormStepDataProvider')]
+    #[Test]
     public function theHoneypotElementChangesWithEveryCallOfTheFirstFormStep(string $formIdentifier): void
     {
         $uri = static::ROOT_PAGE_BASE_URI . '/form';
diff --git a/typo3/sysext/form/Tests/Functional/Service/TranslationServiceTest.php b/typo3/sysext/form/Tests/Functional/Service/TranslationServiceTest.php
index 4a8ad6481242..d2d6ea8d1a71 100644
--- a/typo3/sysext/form/Tests/Functional/Service/TranslationServiceTest.php
+++ b/typo3/sysext/form/Tests/Functional/Service/TranslationServiceTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Form\Tests\Functional\Service;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Localization\Locales;
 use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
@@ -44,9 +45,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateReturnsExistingDefaultLanguageKeyIfFullExtDefaultLanguageKeyIsRequested(): void
     {
         $xlfPath = 'EXT:form_labels/Resources/Private/Language/locallang_form.xlf';
@@ -55,9 +54,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         ));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateReturnsExistingDefaultLanguageKeyIfFullLLLExtDefaultLanguageKeyIsRequested(): void
     {
         $xlfPath = 'EXT:form_labels/Resources/Private/Language/locallang_form.xlf';
@@ -66,9 +63,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         ));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateReturnsExistingDefaultLanguageKeyIfDefaultLanguageKeyIsRequestedAndDefaultValueIsGiven(): void
     {
         $xlfPath = 'EXT:form_labels/Resources/Private/Language/locallang_form.xlf';
@@ -81,9 +76,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         ));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateReturnsEmptyStringIfNonExistingDefaultLanguageKeyIsRequested(): void
     {
         $xlfPath = 'EXT:form_labels/Resources/Private/Language/locallang_form.xlf';
@@ -92,9 +85,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         ));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateReturnsDefaultValueIfNonExistingDefaultLanguageKeyIsRequestedAndDefaultValueIsGiven(): void
     {
         $xlfPath = 'EXT:form_labels/Resources/Private/Language/locallang_form.xlf';
@@ -107,9 +98,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         ));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateReturnsExistingLanguageKeyForLanguageIfExtPathLanguageKeyIsRequested(): void
     {
         $xlfPath = 'EXT:form_labels/Resources/Private/Language/locallang_form.xlf';
@@ -121,9 +110,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         ));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateReturnsDefaultValueIfNonExistingLanguageKeyForLanguageIsRequestedAndDefaultValueIsGiven(): void
     {
         $xlfPath = 'EXT:form_labels/Resources/Private/Language/locallang_form.xlf';
@@ -136,9 +123,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         ));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateReturnsEmptyStringIfNonExistingLanguageKeyForLanguageIsRequested(): void
     {
         $xlfPath = 'EXT:form_labels/Resources/Private/Language/locallang_form.xlf';
@@ -150,9 +135,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         ));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateReturnsExistingDefaultLanguageKeyIfDefaultLanguageKeyIsRequestedAndExtFilePathIsGiven(): void
     {
         $xlfPath = 'EXT:form_labels/Resources/Private/Language/locallang_form.xlf';
@@ -163,9 +146,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         ));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateReturnsExistingDefaultLanguageKeyIfDefaultLanguageKeyIsRequestedAndLLLExtFilePathIsGiven(): void
     {
         $xlfPath = 'EXT:form_labels/Resources/Private/Language/locallang_form.xlf';
@@ -176,9 +157,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         ));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateValuesRecursiveTranslateRecursive(): void
     {
         $xlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -205,9 +184,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateValuesRecursive($input, $xlfPaths));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementValueTranslateLabelForConcreteFormAndConcreteElementIfElementRenderingOptionsContainsATranslationFilesAndElementLabelIsNotEmptyAndPropertyShouldBeTranslatedAndTranslationExists(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -244,9 +221,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFormElementValue($formElement, ['label'], $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementValueTranslateLabelForConcreteFormAndConcreteElementIfElementRenderingOptionsContainsATranslationFilesAndElementLabelIsEmptyAndPropertyShouldBeTranslatedAndTranslationExists(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -283,9 +258,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFormElementValue($formElement, ['label'], $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementValueNotTranslateLabelForConcreteFormAndConcreteElementIfElementRenderingOptionsContainsATranslationFilesAndElementLabelIsEmptyAndPropertyShouldNotBeTranslatedAndTranslationExists(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -321,9 +294,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals('', $this->subject->translateFormElementValue($formElement, ['label'], $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementValueTranslateLabelForConcreteFormElementIfElementRenderingOptionsContainsATranslationFilesAndElementLabelIsNotEmptyAndPropertyShouldBeTranslatedAndTranslationExists(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -359,9 +330,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals('form-element-identifier LABEL EN 1', $this->subject->translateFormElementValue($formElement, ['label'], $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementValueTranslateLabelForFormElementTypeIfElementRenderingOptionsContainsATranslationFilesAndElementLabelIsNotEmptyAndPropertyShouldBeTranslatedAndTranslationExists(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -398,9 +367,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFormElementValue($formElement, ['label'], $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementValueTranslatePropertyForConcreteFormAndConcreteElementIfElementRenderingOptionsContainsATranslationFilesAndElementPropertyIsNotEmptyAndPropertyShouldBeTranslatedAndTranslationExists(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -441,9 +408,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFormElementValue($formElement, ['placeholder'], $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementValueNotTranslatePropertyForConcreteFormAndConcreteElementIfElementRenderingOptionsContainsATranslationFilesAndElementPropertyIsNotEmptyAndPropertyShouldBeTranslatedAndTranslationNotExists(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -484,9 +449,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFormElementValue($formElement, ['placeholder'], $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementValueTranslateRenderingOptionForConcreteFormAndConcreteSectionElementIfElementRenderingOptionsContainsATranslationFilesAndElementRenderingOptionIsNotEmptyAndRenderingOptionShouldBeTranslatedAndTranslationExists(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -523,9 +486,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFormElementValue($formElement, ['nextButtonLabel'], $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementValueTranslateOptionsPropertyForConcreteFormAndConcreteElementIfElementRenderingOptionsContainsATranslationFilesAndElementOptionsPropertyIsAnArrayAndPropertyShouldBeTranslatedAndTranslationExists(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -572,9 +533,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFormElementValue($formElement, ['options'], $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementValueTranslateOptionsPropertyForConcreteElementIfElementRenderingOptionsContainsATranslationFilesAndElementOptionsPropertyIsAnArrayAndPropertyShouldBeTranslatedAndTranslationExists(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -621,9 +580,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFormElementValue($formElement, ['options'], $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFinisherOptionTranslateOptionForConcreteFormIfFinisherTranslationOptionsContainsATranslationFilesAndFinisherOptionIsNotEmptyAndPropertyShouldBeTranslatedAndTranslationExists(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -652,9 +609,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFinisherOption($mockFormRuntime, $finisherIdentifier, 'subject', 'subject value', $finisherRenderingOptions));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFinisherOptionTranslateOptionIfFinisherTranslationOptionsContainsATranslationFilesAndFinisherOptionIsNotEmptyAndPropertyShouldBeTranslatedAndTranslationExists(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -683,9 +638,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFinisherOption($mockFormRuntime, $finisherIdentifier, 'subject', 'subject value', $finisherRenderingOptions));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementValueTranslateLabelForConcreteFormAndConcreteElementFromFormRuntimeTranslationFilesIfElementRenderingOptionsContainsNoTranslationFilesAndElementLabelIsNotEmptyAndPropertyShouldBeTranslatedAndTranslationExists(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -714,9 +667,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFormElementValue($formElement, ['label'], $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function supportsArgumentsForFormElementValueTranslations(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -749,9 +700,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals('See this or that', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFinisherOptionTranslateOptionForConcreteFormFromFormRuntimeIfFinisherTranslationOptionsContainsNoTranslationFilesAndFinisherOptionIsNotEmptyAndPropertyShouldBeTranslatedAndTranslationExists(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -774,9 +723,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFinisherOption($mockFormRuntime, $finisherIdentifier, 'subject', 'subject value'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFinisherOptionSkipsTranslationIfTranslationShouldBeSkipped(): void
     {
         $finisherRenderingOptions = [
@@ -793,9 +740,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function supportsArgumentsForFinisherOptionTranslations(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -820,9 +765,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals('My awesome subject', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementValueTranslateLabelFromAdditionalTranslationForConcreteFormAndConcreteElementIfElementRenderingOptionsContainsATranslationFilesAndElementLabelIsNotEmptyAndPropertyShouldBeTranslatedAndTranslationExists(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_form.xlf'];
@@ -863,9 +806,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFormElementValue($formElement, ['label'], $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementTranslateFormWithContentElementUidIfFormContainsNoOriginalIdentifier(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_ceuid_suffix_01.xlf'];
@@ -899,9 +840,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFormElementValue($formElement, ['label'], $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementTranslateFormWithContentElementUidIfFormContainsOriginalIdentifier(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_ceuid_suffix_02.xlf'];
@@ -936,9 +875,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFormElementValue($formElement, ['label'], $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementErrorTranslateErrorFromFormWithContentElementUidIfFormContainsNoOriginalIdentifier(): void
     {
         self::markTestSkipped('translateFormElementError() calls getProperties() on RootRenderableInterface, which fails. See #100477');
@@ -973,9 +910,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFormElementError($formElement, 123, [], 'default value', $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementErrorTranslateErrorFromFormWithContentElementUidIfFormContainsOriginalIdentifier(): void
     {
         self::markTestSkipped('translateFormElementError() calls getProperties() on RootRenderableInterface, which fails. See #100477');
@@ -1011,9 +946,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFormElementError($formElement, 123, [], 'default value', $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFinisherOptionTranslateOptionFromFormWithContentElementUidIfFormContainsNoOriginalIdentifier(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_ceuid_suffix_01.xlf'];
@@ -1037,9 +970,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFinisherOption($mockFormRuntime, 'Foo', 'test', 'value', []));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFinisherOptionTranslateOptionFromFormWithContentElementUidIfFormContainsOriginalIdentifier(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_ceuid_suffix_02.xlf'];
@@ -1064,9 +995,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals($expected, $this->subject->translateFinisherOption($mockFormRuntime, 'Foo', 'test', 'value', []));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementErrorTranslatesErrorsWithEmptyTranslatedValues(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_empty_values.xlf'];
@@ -1098,9 +1027,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals('default value', $this->subject->translateFormElementError($formElement, 124, [], 'default value', $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFormElementTranslatesFormElementsWithEmptyTranslatedValues(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_empty_values.xlf'];
@@ -1132,9 +1059,7 @@ final class TranslationServiceTest extends FunctionalTestCase
         self::assertEquals('test', $this->subject->translateFormElementValue($formElement, ['label'], $mockFormRuntime));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function translateFinisherOptionTranslatesFinisherOptionsWithEmptyTranslatedValues(): void
     {
         $formRuntimeXlfPaths = ['EXT:form_labels/Resources/Private/Language/locallang_empty_values.xlf'];
diff --git a/typo3/sysext/form/Tests/Functional/ViewHelpers/UploadedResourceViewHelperTest.php b/typo3/sysext/form/Tests/Functional/ViewHelpers/UploadedResourceViewHelperTest.php
index 3cfa82f6e507..39cd06e6f8db 100644
--- a/typo3/sysext/form/Tests/Functional/ViewHelpers/UploadedResourceViewHelperTest.php
+++ b/typo3/sysext/form/Tests/Functional/ViewHelpers/UploadedResourceViewHelperTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Form\Tests\Functional\ViewHelpers;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 use TYPO3Fluid\Fluid\View\TemplateView;
@@ -27,9 +28,7 @@ final class UploadedResourceViewHelperTest extends FunctionalTestCase
 
     protected bool $initializeDatabase = false;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function accpetAttributeIsAdded(): void
     {
         $context = $this->get(RenderingContextFactory::class)->create();
diff --git a/typo3/sysext/frontend/Tests/Functional/Authentication/FrontendUserAuthenticationTest.php b/typo3/sysext/frontend/Tests/Functional/Authentication/FrontendUserAuthenticationTest.php
index 2c4df6d7d9f8..485e5c205a66 100644
--- a/typo3/sysext/frontend/Tests/Functional/Authentication/FrontendUserAuthenticationTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Authentication/FrontendUserAuthenticationTest.php
@@ -18,6 +18,7 @@ declare(strict_types=1);
 namespace TYPO3\CMS\Frontend\Tests\Functional\Authentication;
 
 use GuzzleHttp\Cookie\SetCookie;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Log\NullLogger;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Http\NormalizedParams;
@@ -49,9 +50,7 @@ final class FrontendUserAuthenticationTest extends FunctionalTestCase
         $this->setUpFrontendRootPage(self::ROOT_PAGE_ID, ['typo3/sysext/frontend/Tests/Functional/Fixtures/TypoScript/page.typoscript']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function feSessionsAreNotStoredForAnonymousSessions(): void
     {
         $response = $this->executeFrontendSubRequest((new InternalRequest())->withPageId(self::ROOT_PAGE_ID));
@@ -60,9 +59,7 @@ final class FrontendUserAuthenticationTest extends FunctionalTestCase
         $this->assertCSVDataSet(__DIR__ . '/Fixtures/fe_sessions_empty.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canCreateNewAndExistingSessionWithValidRequestToken(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/fe_users.csv');
diff --git a/typo3/sysext/frontend/Tests/Functional/Cache/CacheLifetimeCalculatorTest.php b/typo3/sysext/frontend/Tests/Functional/Cache/CacheLifetimeCalculatorTest.php
index 89d4f7a99133..ac1cb0c6f212 100644
--- a/typo3/sysext/frontend/Tests/Functional/Cache/CacheLifetimeCalculatorTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Cache/CacheLifetimeCalculatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\Cache;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Frontend\Cache\CacheLifetimeCalculator;
@@ -30,9 +31,7 @@ final class CacheLifetimeCalculatorTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/fixtures.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFirstTimeValueForRecordReturnCorrectData(): void
     {
         $subject = new class ($this->get('cache.core'), $this->get(EventDispatcherInterface::class), $this->get(ConnectionPool::class)) extends CacheLifetimeCalculator {
diff --git a/typo3/sysext/frontend/Tests/Functional/ContentObject/ContentObjectRendererGetDataPageLayoutTest.php b/typo3/sysext/frontend/Tests/Functional/ContentObject/ContentObjectRendererGetDataPageLayoutTest.php
index bd5bd97ac3a4..f46437d64b95 100644
--- a/typo3/sysext/frontend/Tests/Functional/ContentObject/ContentObjectRendererGetDataPageLayoutTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/ContentObject/ContentObjectRendererGetDataPageLayoutTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\ContentObject;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -42,9 +43,7 @@ final class ContentObjectRendererGetDataPageLayoutTest extends FunctionalTestCas
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageLayoutResolvedForBackendLayoutOnRootPage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/ContentObjectRendererGetDataPageLayout/backendLayoutOnRootPage.csv');
@@ -58,9 +57,7 @@ final class ContentObjectRendererGetDataPageLayoutTest extends FunctionalTestCas
         self::assertStringContainsString('pagets__default', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageLayoutNotResolvedForBackendLayoutNextLevelOnRootPage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/ContentObjectRendererGetDataPageLayout/backendLayoutNextLevelOnRootPage.csv');
@@ -74,9 +71,7 @@ final class ContentObjectRendererGetDataPageLayoutTest extends FunctionalTestCas
         self::assertStringNotContainsString('pagets__default', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageLayoutResolvedForBackendLayoutNextLevelInheritedOnSubpageLevel1(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/ContentObjectRendererGetDataPageLayout/backendLayoutAndNextLevelOnRootPage.csv');
@@ -90,9 +85,7 @@ final class ContentObjectRendererGetDataPageLayoutTest extends FunctionalTestCas
         self::assertStringContainsString('pagets__inherit', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageLayoutResolvedForBackendLayoutNextLevelInheritedOnSubpageLevel2(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/ContentObjectRendererGetDataPageLayout/backendLayoutAndNextLevelOnRootPageSubOverride1.csv');
@@ -106,9 +99,7 @@ final class ContentObjectRendererGetDataPageLayoutTest extends FunctionalTestCas
         self::assertStringContainsString('pagets__inherit', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageLayoutResolvedForBackendLayoutOnSubpageLevel3(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/ContentObjectRendererGetDataPageLayout/backendLayoutAndNextLevelOnRootPageSubOverride2.csv');
@@ -122,9 +113,7 @@ final class ContentObjectRendererGetDataPageLayoutTest extends FunctionalTestCas
         self::assertStringContainsString('pagets__bar', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageLayoutResolvedForBackendLayoutNextLevelOverrideOnSubpageLevel3(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/ContentObjectRendererGetDataPageLayout/backendLayoutAndNextLevelOnRootPageSubOverride3.csv');
diff --git a/typo3/sysext/frontend/Tests/Functional/ContentObject/ContentObjectRendererTest.php b/typo3/sysext/frontend/Tests/Functional/ContentObject/ContentObjectRendererTest.php
index fae1ed990f0d..eed04fc9888e 100644
--- a/typo3/sysext/frontend/Tests/Functional/ContentObject/ContentObjectRendererTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/ContentObject/ContentObjectRendererTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\ContentObject;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use Psr\Http\Message\ServerRequestInterface;
 use Psr\Log\NullLogger;
@@ -190,10 +192,9 @@ final class ContentObjectRendererTest extends FunctionalTestCase
 
     /**
      * Check if sanitizeSelectPart works as expected
-     *
-     * @dataProvider getQueryDataProvider
-     * @test
      */
+    #[DataProvider('getQueryDataProvider')]
+    #[Test]
     public function getQuery(string $table, array $conf, array $expected): void
     {
         $GLOBALS['TCA'] = [
@@ -239,9 +240,7 @@ final class ContentObjectRendererTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function typolinkLinkResultIsInstanceOfLinkResultInterface(): void
     {
         $subject = new ContentObjectRenderer();
@@ -250,9 +249,7 @@ final class ContentObjectRendererTest extends FunctionalTestCase
         self::assertInstanceOf(LinkResultInterface::class, $linkResult);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function typoLinkReturnsOnlyLinkTextIfNoLinkResolvingIsPossible(): void
     {
         $linkService = $this->getMockBuilder(LinkService::class)->disableOriginalConstructor()->getMock();
@@ -265,9 +262,7 @@ final class ContentObjectRendererTest extends FunctionalTestCase
         self::assertSame('foo', $subject->typoLink('foo', ['parameter' => 'foo']));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function typoLinkLogsErrorIfNoLinkResolvingIsPossible(): void
     {
         $linkService = $this->getMockBuilder(LinkService::class)->disableOriginalConstructor()->getMock();
@@ -556,10 +551,8 @@ final class ContentObjectRendererTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider typolinkReturnsCorrectLinksDataProvider
-     */
+    #[DataProvider('typolinkReturnsCorrectLinksDataProvider')]
+    #[Test]
     public function typolinkReturnsCorrectLinksAndUrls(string $linkText, array $configuration, string $expectedResult): void
     {
         $subject = new ContentObjectRenderer();
@@ -663,10 +656,8 @@ final class ContentObjectRendererTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider typolinkReturnsCorrectLinkForSpamEncryptedEmailsDataProvider
-     */
+    #[DataProvider('typolinkReturnsCorrectLinkForSpamEncryptedEmailsDataProvider')]
+    #[Test]
     public function typolinkReturnsCorrectLinkForSpamEncryptedEmails(array $tsfeConfig, string $linkText, string $parameter, string $expected): void
     {
         $tsfe = $this->getMockBuilder(TypoScriptFrontendController::class)->disableOriginalConstructor()->getMock();
@@ -794,10 +785,8 @@ final class ContentObjectRendererTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider typolinkReturnsCorrectLinksForFilesWithAbsRefPrefixDataProvider
-     */
+    #[DataProvider('typolinkReturnsCorrectLinksForFilesWithAbsRefPrefixDataProvider')]
+    #[Test]
     public function typolinkReturnsCorrectLinksForFilesWithAbsRefPrefix(string $linkText, array $configuration, string $absRefPrefix, string $expectedResult): void
     {
         $tsfe = $this->getMockBuilder(TypoScriptFrontendController::class)->disableOriginalConstructor()->getMock();
@@ -875,10 +864,8 @@ final class ContentObjectRendererTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider typoLinkProperlyEncodesLinkResultDataProvider
-     * @test
-     */
+    #[DataProvider('typoLinkProperlyEncodesLinkResultDataProvider')]
+    #[Test]
     public function typoLinkProperlyEncodesLinkResult(string $linkText, array $configuration, string $expectedResult): void
     {
         $subject = new ContentObjectRenderer();
@@ -886,9 +873,7 @@ final class ContentObjectRendererTest extends FunctionalTestCase
         self::assertEquals($expectedResult, $subject->typoLink($linkText, $configuration));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function searchWhereWithTooShortSearchWordWillReturnValidWhereStatement(): void
     {
         $tsfe = $this->getMockBuilder(TypoScriptFrontendController::class)->disableOriginalConstructor()->getMock();
@@ -901,9 +886,7 @@ final class ContentObjectRendererTest extends FunctionalTestCase
         self::assertEquals($expected, $actual);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function libParseFuncProperlyKeepsTagsUnescaped(): void
     {
         $tsfe = $this->getMockBuilder(TypoScriptFrontendController::class)->disableOriginalConstructor()->getMock();
@@ -1005,10 +988,8 @@ And another one';
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider checkIfReturnsExpectedValuesDataProvider
-     */
+    #[DataProvider('checkIfReturnsExpectedValuesDataProvider')]
+    #[Test]
     public function checkIfReturnsExpectedValues(array $configuration, bool $expected): void
     {
         $subject = GeneralUtility::makeInstance(ContentObjectRenderer::class);
@@ -1182,10 +1163,8 @@ And another one';
         ];
     }
 
-    /**
-     * @dataProvider imageLinkWrapWrapsTheContentAsConfiguredDataProvider
-     * @test
-     */
+    #[DataProvider('imageLinkWrapWrapsTheContentAsConfiguredDataProvider')]
+    #[Test]
     public function imageLinkWrapWrapsTheContentAsConfigured(string $content, array $configuration, array $expected, array $expectedParams = []): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/FileReferences.csv');
@@ -1229,9 +1208,7 @@ And another one';
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getImgResourceRespectsFileReferenceObjectCropData(): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/FileReferences.csv');
diff --git a/typo3/sysext/frontend/Tests/Functional/ContentObject/FilesContentObjectTest.php b/typo3/sysext/frontend/Tests/Functional/ContentObject/FilesContentObjectTest.php
index 279fae39b660..b885a4efcf02 100644
--- a/typo3/sysext/frontend/Tests/Functional/ContentObject/FilesContentObjectTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/ContentObject/FilesContentObjectTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\ContentObject;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Domain\Repository\PageRepository;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -186,10 +188,8 @@ final class FilesContentObjectTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderReturnsFilesForFileReferencesDataProvider
-     */
+    #[DataProvider('renderReturnsFilesForFileReferencesDataProvider')]
+    #[Test]
     public function renderReturnsFilesForFileReferences(array $configuration, string $expected): void
     {
         self::assertSame($expected, $this->subject->render($configuration));
@@ -331,10 +331,8 @@ final class FilesContentObjectTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderReturnsFilesForFilesDataProvider
-     */
+    #[DataProvider('renderReturnsFilesForFilesDataProvider')]
+    #[Test]
     public function renderReturnsFilesForFiles(array $configuration, string $expected): void
     {
         self::assertSame($expected, $this->subject->render($configuration));
@@ -513,10 +511,8 @@ final class FilesContentObjectTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderReturnsFilesForCollectionsDataProvider
-     */
+    #[DataProvider('renderReturnsFilesForCollectionsDataProvider')]
+    #[Test]
     public function renderReturnsFilesForCollections(array $configuration, string $expected): void
     {
         self::assertSame($expected, $this->subject->render($configuration));
@@ -724,10 +720,8 @@ final class FilesContentObjectTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderReturnsFilesForFoldersDataProvider
-     */
+    #[DataProvider('renderReturnsFilesForFoldersDataProvider')]
+    #[Test]
     public function renderReturnsFilesForFolders(array $configuration, string $expected): void
     {
         self::assertSame($expected, $this->subject->render($configuration));
@@ -854,10 +848,8 @@ final class FilesContentObjectTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider renderReturnsFilesForReferencesAsArrayDataProvider
-     */
+    #[DataProvider('renderReturnsFilesForReferencesAsArrayDataProvider')]
+    #[Test]
     public function renderReturnsFilesForReferencesAsArray(array $configuration, array $data, string $table, string $expected): void
     {
         $this->subject->getContentObjectRenderer()->start($data, $table);
diff --git a/typo3/sysext/frontend/Tests/Functional/ContentObject/FluidTemplateContentObjectTest.php b/typo3/sysext/frontend/Tests/Functional/ContentObject/FluidTemplateContentObjectTest.php
index f9903ea91583..f1057c0981a3 100644
--- a/typo3/sysext/frontend/Tests/Functional/ContentObject/FluidTemplateContentObjectTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/ContentObject/FluidTemplateContentObjectTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\ContentObject;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -44,9 +45,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderWorksWithNestedFluidTemplate(): void
     {
         $this->setUpFrontendRootPage(
@@ -59,9 +58,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('ABC', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderWorksWithNestedFluidTemplateWithLayouts(): void
     {
         $this->setUpFrontendRootPage(
@@ -76,9 +73,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('LayoutOverride', $responseBody);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stdWrapAppliesForTemplateRootPaths(): void
     {
         $this->setUpFrontendRootPage(
@@ -91,9 +86,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('Foobar', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function optionFileIsUsedAsTemplate(): void
     {
         $this->setUpFrontendRootPage(
@@ -106,9 +99,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('Foobar', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function optionTemplateIsUsedAsCObjTemplate(): void
     {
         $this->setUpFrontendRootPage(
@@ -121,9 +112,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('My fluid template', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function optionTemplateNameIsUsedAsHtmlFileInTemplateRootPaths(): void
     {
         $this->setUpFrontendRootPage(
@@ -136,9 +125,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('Foobar', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stdWrapIsAppliedOnOptionTemplateName(): void
     {
         $this->setUpFrontendRootPage(
@@ -151,9 +138,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('Foobar', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function layoutIsFoundInLayoutRootPath(): void
     {
         $this->setUpFrontendRootPage(
@@ -168,9 +153,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('Alternative Template', $responseBody);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function layoutRootPathHasStdWrapSupport(): void
     {
         $this->setUpFrontendRootPage(
@@ -185,9 +168,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('Alternative Template', $responseBody);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function layoutRootPathsHasStdWrapSupport(): void
     {
         $this->setUpFrontendRootPage(
@@ -202,9 +183,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('Alternative Template', $responseBody);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fallbacksForLayoutRootPathsAreApplied(): void
     {
         $this->setUpFrontendRootPage(
@@ -219,9 +198,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('Main Template', $responseBody);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fallbacksForLayoutRootPathAreAppendedToLayoutRootPath(): void
     {
         $this->setUpFrontendRootPage(
@@ -236,9 +213,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('Main Template', $responseBody);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function partialsInPartialRootPathAreFound(): void
     {
         $this->setUpFrontendRootPage(
@@ -251,9 +226,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('Template with Partial', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function partialRootPathHasStdWrapSupport(): void
     {
         $this->setUpFrontendRootPage(
@@ -266,9 +239,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('Template with Partial', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function partialRootPathsHasStdWrapSupport(): void
     {
         $this->setUpFrontendRootPage(
@@ -281,9 +252,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('Template with Partial', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fallbacksForPartialRootPathsAreApplied(): void
     {
         $this->setUpFrontendRootPage(
@@ -296,9 +265,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('Template with Partial Override', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fallbacksForPartialRootPathAreAppendedToPartialRootPath(): void
     {
         $this->setUpFrontendRootPage(
@@ -311,9 +278,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('Template with Partial Override', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function formatOverridesDefaultHtmlSuffix(): void
     {
         $this->setUpFrontendRootPage(
@@ -326,9 +291,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('FoobarXML', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stdWrapIsAppliedOnOptionFormat(): void
     {
         $this->setUpFrontendRootPage(
@@ -341,9 +304,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('FoobarXML', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function settingsAreAssignedToTheView(): void
     {
         $this->setUpFrontendRootPage(
@@ -356,9 +317,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('I am coming from the settings', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionForReservedVariableNameData(): void
     {
         $this->setUpFrontendRootPage(
@@ -372,9 +331,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         $this->executeFrontendSubRequest((new InternalRequest())->withPageId(self::ROOT_PAGE_ID));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderThrowsExceptionForReservedVariableNameCurrent(): void
     {
         $this->setUpFrontendRootPage(
@@ -388,9 +345,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         $this->executeFrontendSubRequest((new InternalRequest())->withPageId(self::ROOT_PAGE_ID));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function cObjectIsAppliedOnVariables(): void
     {
         $this->setUpFrontendRootPage(
@@ -403,9 +358,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('I am coming from the variables', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function contentObjectRendererDataIsAvailableInView(): void
     {
         $this->setUpFrontendRootPage(
@@ -418,9 +371,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('FluidTemplateContentObjectTest', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderAssignsContentObjectRendererCurrentValueToView(): void
     {
         $this->setUpFrontendRootPage(
@@ -433,9 +384,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('My current value', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function stdWrapIsAppliedOnOverallFluidTemplate(): void
     {
         $this->setUpFrontendRootPage(
@@ -448,9 +397,7 @@ final class FluidTemplateContentObjectTest extends FunctionalTestCase
         self::assertStringContainsString('1+1=2', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderFluidTemplateAssetsIntoPageRendererRendersAndAttachesAssets(): void
     {
         $this->setUpFrontendRootPage(
diff --git a/typo3/sysext/frontend/Tests/Functional/Controller/ShowImageControllerTest.php b/typo3/sysext/frontend/Tests/Functional/Controller/ShowImageControllerTest.php
index 5360815c8fd9..c3ee8eca9b5b 100644
--- a/typo3/sysext/frontend/Tests/Functional/Controller/ShowImageControllerTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Controller/ShowImageControllerTest.php
@@ -18,6 +18,8 @@ declare(strict_types=1);
 namespace TYPO3\CMS\Frontend\Tests\Functional\Controller;
 
 use Masterminds\HTML5;
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use PHPUnit\Framework\MockObject\MockObject;
 use Psr\Http\Message\ServerRequestInterface;
 use TYPO3\CMS\Core\Resource\FileInterface;
@@ -84,10 +86,10 @@ final class ShowImageControllerTest extends FunctionalTestCase
     }
 
     /**
-     * @test
      * @param array<string, int|string> $queryParams
-     * @dataProvider contentIsGeneratedForLocalFilesDataProvider
      */
+    #[DataProvider('contentIsGeneratedForLocalFilesDataProvider')]
+    #[Test]
     public function contentIsGeneratedForLocalFiles(int $fileId, array $queryParams): void
     {
         $storageDriver = 'Local';
diff --git a/typo3/sysext/frontend/Tests/Functional/Controller/TypoScriptFrontendControllerTest.php b/typo3/sysext/frontend/Tests/Functional/Controller/TypoScriptFrontendControllerTest.php
index 1bc59226c828..d2b08fc358f6 100644
--- a/typo3/sysext/frontend/Tests/Functional/Controller/TypoScriptFrontendControllerTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Controller/TypoScriptFrontendControllerTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\Controller;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\Internal\TypoScriptInstruction;
@@ -46,9 +48,7 @@ final class TypoScriptFrontendControllerTest extends FunctionalTestCase
         ],
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function headerAndFooterMarkersAreReplacedDuringIntProcessing(): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/LiveDefaultPages.csv');
@@ -77,9 +77,7 @@ final class TypoScriptFrontendControllerTest extends FunctionalTestCase
         self::assertStringContainsString('footerDataFromUserInt', $body);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function jsIncludesWithUserIntIsRendered(): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/LiveDefaultPages.csv');
@@ -119,9 +117,7 @@ final class TypoScriptFrontendControllerTest extends FunctionalTestCase
 alert(yes);', $body);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizationReturnsUnchangedStringIfNotLocallangLabel(): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/LiveDefaultPages.csv');
@@ -140,9 +136,7 @@ alert(yes);', $body);
         self::assertStringContainsString('notprefixedWithLLL', $body);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function localizationReturnsLocalizedStringWithLocallangLabel(): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/LiveDefaultPages.csv');
@@ -179,10 +173,8 @@ alert(yes);', $body);
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider mountPointParameterContainsOnlyValidMPValuesDataProvider
-     */
+    #[Test]
+    #[DataProvider('mountPointParameterContainsOnlyValidMPValuesDataProvider')]
     public function mountPointParameterContainsOnlyValidMPValues(string $inputMp, string $expected): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/LiveDefaultPages.csv');
@@ -373,10 +365,8 @@ alert(yes);', $body);
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getFromCacheSetsConfigRootlineToLocalRootlineDataProvider
-     */
+    #[DataProvider('getFromCacheSetsConfigRootlineToLocalRootlineDataProvider')]
+    #[Test]
     public function getFromCacheSetsConfigRootlineToLocalRootline(int $pid, array $expectedRootLine, array $expectedConfigRootLine, bool $nocache): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/LiveDefaultPages.csv');
@@ -401,9 +391,7 @@ alert(yes);', $body);
         self::assertSame($expectedConfigRootLine, $GLOBALS['TSFE']->tmpl->rootLine);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function applicationConsidersTrueConditionVerdict(): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/LiveDefaultPages.csv');
@@ -421,9 +409,7 @@ alert(yes);', $body);
         self::assertStringContainsString('https-condition-on', (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function applicationConsidersFalseConditionVerdictToElseBranch(): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/LiveDefaultPages.csv');
diff --git a/typo3/sysext/frontend/Tests/Functional/Imaging/GifBuilderTest.php b/typo3/sysext/frontend/Tests/Functional/Imaging/GifBuilderTest.php
index 066612bc31c2..729768b2feea 100644
--- a/typo3/sysext/frontend/Tests/Functional/Imaging/GifBuilderTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Imaging/GifBuilderTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\Imaging;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -58,9 +59,7 @@ final class GifBuilderTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function buildSimpleGifBuilderImageInComposerMode(): void
     {
         $this->simulateCliRequestInComposerMode();
@@ -78,9 +77,7 @@ final class GifBuilderTest extends FunctionalTestCase
         self::assertFileExists(Environment::getPublicPath() . '/' . $gifFileName);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function buildImageInCommandLineInterfaceAndComposerMode(): void
     {
         $this->simulateCliRequestInComposerMode();
@@ -110,9 +107,7 @@ final class GifBuilderTest extends FunctionalTestCase
         self::assertStringStartsWith('<img src="typo3temp/assets/images/csm_kasper-skarhoj-gifbuilder_', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getImageResourceInCommandLineInterfaceAndComposerMode(): void
     {
         $this->simulateCliRequestInComposerMode();
@@ -142,9 +137,7 @@ final class GifBuilderTest extends FunctionalTestCase
         self::assertStringStartsWith('typo3temp/assets/images/csm_kasper-skarhoj-gifbuilder-imageresource_', $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function buildImageWithMaskInCommandLineInterfaceAndComposerMode(): void
     {
         $this->simulateCliRequestInComposerMode();
@@ -201,9 +194,8 @@ final class GifBuilderTest extends FunctionalTestCase
 
     /**
      * Check hashes of Images overlayed with other images are idempotent
-     *
-     * @test
      */
+    #[Test]
     public function overlayImagesHasStableHash(): void
     {
         $this->setupFullTestEnvironment();
diff --git a/typo3/sysext/frontend/Tests/Functional/Middleware/BackendUserAuthenticatorTest.php b/typo3/sysext/frontend/Tests/Functional/Middleware/BackendUserAuthenticatorTest.php
index 8937e31db19f..4d21dcc71c4d 100644
--- a/typo3/sysext/frontend/Tests/Functional/Middleware/BackendUserAuthenticatorTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Middleware/BackendUserAuthenticatorTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\Middleware;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
@@ -45,9 +46,7 @@ final class BackendUserAuthenticatorTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function nonAuthenticatedRequestDoesNotSendHeaders(): void
     {
         $response = $this->executeFrontendSubRequest((new InternalRequest())->withPageId(1));
@@ -56,9 +55,7 @@ final class BackendUserAuthenticatorTest extends FunctionalTestCase
         self::assertArrayNotHasKey('Expires', $response->getHeaders());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function authenticatedRequestIncludesInvalidCacheHeaders(): void
     {
         $response = $this->executeFrontendSubRequest(
diff --git a/typo3/sysext/frontend/Tests/Functional/Rendering/AbsoluteUriPrefixRenderingTest.php b/typo3/sysext/frontend/Tests/Functional/Rendering/AbsoluteUriPrefixRenderingTest.php
index 8da9d5f50f3a..706ae68f8be0 100644
--- a/typo3/sysext/frontend/Tests/Functional/Rendering/AbsoluteUriPrefixRenderingTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Rendering/AbsoluteUriPrefixRenderingTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\Rendering;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -206,10 +208,8 @@ final class AbsoluteUriPrefixRenderingTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider urisAreRenderedUsingForceAbsoluteUrlsDataProvider
-     */
+    #[DataProvider('urisAreRenderedUsingForceAbsoluteUrlsDataProvider')]
+    #[Test]
     public function urisAreRenderedUsingAbsRefPrefix(string $useAbsoluteUrls, string $compressorAspect, array $expectations): void
     {
         $response = $this->executeFrontendSubRequest(
diff --git a/typo3/sysext/frontend/Tests/Functional/Rendering/LocalizedSiteContentRenderingTest.php b/typo3/sysext/frontend/Tests/Functional/Rendering/LocalizedSiteContentRenderingTest.php
index 8a72391f9cea..9ba32f623dd7 100644
--- a/typo3/sysext/frontend/Tests/Functional/Rendering/LocalizedSiteContentRenderingTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Rendering/LocalizedSiteContentRenderingTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\Rendering;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Tests\Functional\DataHandling\AbstractDataHandlerActionTestCase;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
@@ -133,9 +135,8 @@ final class LocalizedSiteContentRenderingTest extends AbstractDataHandlerActionT
     /**
      * For the default language all combination of language settings should give the same result,
      * regardless of Language fallback settings, if the default language is requested then no language settings apply.
-     *
-     * @test
      */
+    #[Test]
     public function onlyEnglishContentIsRenderedForDefaultLanguage(): void
     {
         $this->writeSiteConfiguration(
@@ -285,9 +286,9 @@ final class LocalizedSiteContentRenderingTest extends AbstractDataHandlerActionT
     /**
      * Page is translated to Dutch, so changing fallbackChain does not matter currently.
      * Page title is always [DA]Page, the content language is always "1"
-     * @test
-     * @dataProvider dutchDataProvider
      */
+    #[DataProvider('dutchDataProvider')]
+    #[Test]
     public function renderingOfDutchLanguage(array $languageConfiguration, array $visibleRecords, string $fallbackType, string $fallbackChain, string $overlayType): void
     {
         $this->writeSiteConfiguration(
@@ -614,11 +615,11 @@ final class LocalizedSiteContentRenderingTest extends AbstractDataHandlerActionT
     /**
      * Page uid 89 is NOT translated to german
      *
-     * @test
-     * @dataProvider contentOnNonTranslatedPageDataProvider
      *
      * @param int $statusCode 200 or 404
      */
+    #[DataProvider('contentOnNonTranslatedPageDataProvider')]
+    #[Test]
     public function contentOnNonTranslatedPageGerman(array $languageConfiguration, array $visibleRecords, string $pageTitle, int $languageId, int $contentLanguageId, string $fallbackType, string $fallbackChain, string $overlayMode, int $statusCode = 200): void
     {
         $this->writeSiteConfiguration(
@@ -782,10 +783,9 @@ final class LocalizedSiteContentRenderingTest extends AbstractDataHandlerActionT
 
     /**
      * Page uid 89 is translated to Polish, but not all CE are translated
-     *
-     * @test
-     * @dataProvider contentOnPartiallyTranslatedPageDataProvider
      */
+    #[DataProvider('contentOnPartiallyTranslatedPageDataProvider')]
+    #[Test]
     public function contentOnPartiallyTranslatedPage(array $languageConfiguration, array $visibleHeaders, string $fallbackType, string $fallbackChain, string $overlayType): void
     {
         $this->writeSiteConfiguration(
diff --git a/typo3/sysext/frontend/Tests/Functional/Rendering/TitleTagRenderingTest.php b/typo3/sysext/frontend/Tests/Functional/Rendering/TitleTagRenderingTest.php
index 96280d39b6a0..a1d854f347ea 100644
--- a/typo3/sysext/frontend/Tests/Functional/Rendering/TitleTagRenderingTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Rendering/TitleTagRenderingTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\Rendering;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\Yaml\Yaml;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
@@ -255,10 +257,8 @@ final class TitleTagRenderingTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider titleTagDataProvider
-     */
+    #[DataProvider('titleTagDataProvider')]
+    #[Test]
     public function checkIfCorrectTitleTagIsRendered(array $pageConfig, array $expectations): void
     {
         $response = $this->executeFrontendSubRequest(
diff --git a/typo3/sysext/frontend/Tests/Functional/Rendering/UriPrefixRenderingTest.php b/typo3/sysext/frontend/Tests/Functional/Rendering/UriPrefixRenderingTest.php
index d08f603a432e..84fb19687578 100644
--- a/typo3/sysext/frontend/Tests/Functional/Rendering/UriPrefixRenderingTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Rendering/UriPrefixRenderingTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\Rendering;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -297,10 +299,8 @@ final class UriPrefixRenderingTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider urisAreRenderedUsingAbsRefPrefixDataProvider
-     */
+    #[DataProvider('urisAreRenderedUsingAbsRefPrefixDataProvider')]
+    #[Test]
     public function urisAreRenderedUsingAbsRefPrefix(string $absRefPrefixAspect, string $compressorAspect, array $expectations): void
     {
         $response = $this->executeFrontendSubRequest(
diff --git a/typo3/sysext/frontend/Tests/Functional/Request/InternalRequestDataMappingTest.php b/typo3/sysext/frontend/Tests/Functional/Request/InternalRequestDataMappingTest.php
index ceaf9ddb6f09..2b3d912adf3d 100644
--- a/typo3/sysext/frontend/Tests/Functional/Request/InternalRequestDataMappingTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Request/InternalRequestDataMappingTest.php
@@ -17,6 +17,9 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\Request;
 
+use GuzzleHttp\Psr7\Query;
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\StreamFactoryInterface;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -42,7 +45,7 @@ final class InternalRequestDataMappingTest extends FunctionalTestCase
                 'method' => 'POST',
                 'parsedBody' => ['param1' => 'value1'],
                 'queryParams' => [],
-                'body' => \GuzzleHttp\Psr7\Query::build(['param1' => 'value1']),
+                'body' => Query::build(['param1' => 'value1']),
                 'headers' => [
                     'Content-type' => [
                         'application/x-www-form-urlencoded',
@@ -61,12 +64,12 @@ final class InternalRequestDataMappingTest extends FunctionalTestCase
             'headers' => [
                 'Content-type' => 'application/x-www-form-urlencoded',
             ],
-            'body' => \GuzzleHttp\Psr7\Query::build(['param1' => 'value1']),
+            'body' => Query::build(['param1' => 'value1']),
             'expectedJsonKeyValues' => [
                 'method' => 'PATCH',
                 'parsedBody' => ['param1' => 'value1'],
                 'queryParams' => [],
-                'body' => \GuzzleHttp\Psr7\Query::build(['param1' => 'value1']),
+                'body' => Query::build(['param1' => 'value1']),
                 'headers' => [
                     'Content-type' => [
                         'application/x-www-form-urlencoded',
@@ -85,12 +88,12 @@ final class InternalRequestDataMappingTest extends FunctionalTestCase
             'headers' => [
                 'Content-type' => 'application/x-www-form-urlencoded',
             ],
-            'body' => \GuzzleHttp\Psr7\Query::build(['param1' => 'value1']),
+            'body' => Query::build(['param1' => 'value1']),
             'expectedJsonKeyValues' => [
                 'method' => 'PUT',
                 'parsedBody' => ['param1' => 'value1'],
                 'queryParams' => [],
-                'body' => \GuzzleHttp\Psr7\Query::build(['param1' => 'value1']),
+                'body' => Query::build(['param1' => 'value1']),
                 'headers' => [
                     'Content-type' => [
                         'application/x-www-form-urlencoded',
@@ -109,12 +112,12 @@ final class InternalRequestDataMappingTest extends FunctionalTestCase
             'headers' => [
                 'Content-type' => 'application/x-www-form-urlencoded',
             ],
-            'body' => \GuzzleHttp\Psr7\Query::build(['param1' => 'value1']),
+            'body' => Query::build(['param1' => 'value1']),
             'expectedJsonKeyValues' => [
                 'method' => 'DELETE',
                 'parsedBody' => ['param1' => 'value1'],
                 'queryParams' => [],
-                'body' => \GuzzleHttp\Psr7\Query::build(['param1' => 'value1']),
+                'body' => Query::build(['param1' => 'value1']),
                 'headers' => [
                     'Content-type' => [
                         'application/x-www-form-urlencoded',
@@ -138,7 +141,7 @@ final class InternalRequestDataMappingTest extends FunctionalTestCase
                 'method' => 'POST',
                 'parsedBody' => ['param1' => 'value1'],
                 'queryParams' => ['queryParam1' => 'queryValue1'],
-                'body' => \GuzzleHttp\Psr7\Query::build(['param1' => 'value1']),
+                'body' => Query::build(['param1' => 'value1']),
                 'headers' => [
                     'Content-type' => [
                         'application/x-www-form-urlencoded',
@@ -157,12 +160,12 @@ final class InternalRequestDataMappingTest extends FunctionalTestCase
             'headers' => [
                 'Content-type' => 'application/x-www-form-urlencoded',
             ],
-            'body' => \GuzzleHttp\Psr7\Query::build(['param1' => 'value1']),
+            'body' => Query::build(['param1' => 'value1']),
             'expectedJsonKeyValues' => [
                 'method' => 'PATCH',
                 'parsedBody' => ['param1' => 'value1'],
                 'queryParams' => ['queryParam1' => 'queryValue1'],
-                'body' => \GuzzleHttp\Psr7\Query::build(['param1' => 'value1']),
+                'body' => Query::build(['param1' => 'value1']),
                 'headers' => [
                     'Content-type' => [
                         'application/x-www-form-urlencoded',
@@ -181,12 +184,12 @@ final class InternalRequestDataMappingTest extends FunctionalTestCase
             'headers' => [
                 'Content-type' => 'application/x-www-form-urlencoded',
             ],
-            'body' => \GuzzleHttp\Psr7\Query::build(['param1' => 'value1']),
+            'body' => Query::build(['param1' => 'value1']),
             'expectedJsonKeyValues' => [
                 'method' => 'PUT',
                 'parsedBody' => ['param1' => 'value1'],
                 'queryParams' => ['queryParam1' => 'queryValue1'],
-                'body' => \GuzzleHttp\Psr7\Query::build(['param1' => 'value1']),
+                'body' => Query::build(['param1' => 'value1']),
                 'headers' => [
                     'Content-type' => [
                         'application/x-www-form-urlencoded',
@@ -205,12 +208,12 @@ final class InternalRequestDataMappingTest extends FunctionalTestCase
             'headers' => [
                 'Content-type' => 'application/x-www-form-urlencoded',
             ],
-            'body' => \GuzzleHttp\Psr7\Query::build(['param1' => 'value1']),
+            'body' => Query::build(['param1' => 'value1']),
             'expectedJsonKeyValues' => [
                 'method' => 'DELETE',
                 'parsedBody' => ['param1' => 'value1'],
                 'queryParams' => ['queryParam1' => 'queryValue1'],
-                'body' => \GuzzleHttp\Psr7\Query::build(['param1' => 'value1']),
+                'body' => Query::build(['param1' => 'value1']),
                 'headers' => [
                     'Content-type' => [
                         'application/x-www-form-urlencoded',
@@ -286,10 +289,9 @@ final class InternalRequestDataMappingTest extends FunctionalTestCase
     /**
      * Verify testing-framework request details are properly received
      * in the application by adding an extension with a middleware.
-     *
-     * @test
-     * @dataProvider ensureRequestMappingWorksDataProvider
      */
+    #[DataProvider('ensureRequestMappingWorksDataProvider')]
+    #[Test]
     public function ensureRequestMappingWorks(
         string $uri,
         string $method,
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EidRequestTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EidRequestTest.php
index 13e9b1445728..fd5b74ea943b 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EidRequestTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EidRequestTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerWriter;
@@ -301,10 +303,8 @@ final class EidRequestTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider ensureEidRequestsWorkDataProvider
-     */
+    #[DataProvider('ensureEidRequestsWorkDataProvider')]
+    #[Test]
     public function ensureEidRequestsWork(
         string $uri,
         int $expectedStatusCode,
@@ -334,10 +334,8 @@ final class EidRequestTest extends AbstractTestCase
         }
     }
 
-    /**
-     * @test
-     * @dataProvider ensureEidRequestsWorkDataProvider
-     */
+    #[DataProvider('ensureEidRequestsWorkDataProvider')]
+    #[Test]
     public function ensureEidRequestsWorkWithDotPhpPageTypeSuffixRoutingConfiguration(
         string $uri,
         int $expectedStatusCode,
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/DefaultExtbaseControllerTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/DefaultExtbaseControllerTest.php
index 05e6ba96c9f3..36ef85ed4890 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/DefaultExtbaseControllerTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/DefaultExtbaseControllerTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\EnhancerLinkGenerator;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 
 final class DefaultExtbaseControllerTest extends AbstractEnhancerLinkGeneratorTestCase
@@ -51,10 +53,9 @@ final class DefaultExtbaseControllerTest extends AbstractEnhancerLinkGeneratorTe
 
     /**
      * Tests whether ExtbasePluginEnhancer applies `defaultController` values correctly but keeps additional Query Parameters.
-     *
-     * @test
-     * @dataProvider defaultExtbaseControllerActionNamesAreAppliedWithAdditionalNonMappedQueryArgumentsDataProvider
      */
+    #[DataProvider('defaultExtbaseControllerActionNamesAreAppliedWithAdditionalNonMappedQueryArgumentsDataProvider')]
+    #[Test]
     public function defaultExtbaseControllerActionNamesAreAppliedWithAdditionalNonMappedQueryArguments(string $additionalParameters, string $expectation): void
     {
         $targetLanguageId = 0;
@@ -128,10 +129,9 @@ final class DefaultExtbaseControllerTest extends AbstractEnhancerLinkGeneratorTe
 
     /**
      * Tests whether ExtbasePluginEnhancer applies `defaultController` values correctly.
-     *
-     * @test
-     * @dataProvider defaultExtbaseControllerActionNamesAreAppliedDataProvider
      */
+    #[DataProvider('defaultExtbaseControllerActionNamesAreAppliedDataProvider')]
+    #[Test]
     public function defaultExtbaseControllerActionNamesAreApplied(string $additionalParameters, string $expectation): void
     {
         $targetLanguageId = 0;
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/LocaleModifierTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/LocaleModifierTest.php
index dfa4bedda919..93dceb74a010 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/LocaleModifierTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/LocaleModifierTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\EnhancerLinkGenerator;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\AspectDeclaration;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\Builder;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\LanguageContext;
@@ -101,10 +103,8 @@ final class LocaleModifierTest extends AbstractEnhancerLinkGeneratorTestCase
         return static::localeModifierDataProviderBuilder();
     }
 
-    /**
-     * @test
-     * @dataProvider localeModifierDataProvider
-     */
+    #[DataProvider('localeModifierDataProvider')]
+    #[Test]
     public function localeModifierIsApplied(TestSet $testSet): void
     {
         $builder = Builder::create();
@@ -158,10 +158,8 @@ final class LocaleModifierTest extends AbstractEnhancerLinkGeneratorTestCase
         return $testSets;
     }
 
-    /**
-     * @test
-     * @dataProvider pageTypeDecoratorIsAppliedDataProvider
-     */
+    #[DataProvider('pageTypeDecoratorIsAppliedDataProvider')]
+    #[Test]
     public function pageTypeDecoratorIsApplied(TestSet $testSet): void
     {
         parent::pageTypeDecoratorIsApplied($testSet);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/PersistedAliasMapperTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/PersistedAliasMapperTest.php
index b6957b2b6391..cf0953532295 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/PersistedAliasMapperTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/PersistedAliasMapperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\EnhancerLinkGenerator;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\AspectDeclaration;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\Builder;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\LanguageContext;
@@ -79,10 +81,8 @@ final class PersistedAliasMapperTest extends AbstractEnhancerLinkGeneratorTestCa
         return static::persistedAliasMapperDataProviderBuilder();
     }
 
-    /**
-     * @test
-     * @dataProvider persistedAliasMapperDataProvider
-     */
+    #[DataProvider('persistedAliasMapperDataProvider')]
+    #[Test]
     public function persistedAliasMapperIsApplied(TestSet $testSet): void
     {
         $builder = Builder::create();
@@ -132,10 +132,8 @@ final class PersistedAliasMapperTest extends AbstractEnhancerLinkGeneratorTestCa
         return $testSets;
     }
 
-    /**
-     * @test
-     * @dataProvider pageTypeDecoratorIsAppliedDataProvider
-     */
+    #[DataProvider('pageTypeDecoratorIsAppliedDataProvider')]
+    #[Test]
     public function pageTypeDecoratorIsApplied(TestSet $testSet): void
     {
         parent::pageTypeDecoratorIsApplied($testSet);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/PersistedPatternMapperTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/PersistedPatternMapperTest.php
index 784723903f3f..6fe7e38f1ca2 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/PersistedPatternMapperTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/PersistedPatternMapperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\EnhancerLinkGenerator;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\AspectDeclaration;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\Builder;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\LanguageContext;
@@ -97,10 +99,8 @@ final class PersistedPatternMapperTest extends AbstractEnhancerLinkGeneratorTest
         return static::persistedPatternMapperDataProviderBuilder();
     }
 
-    /**
-     * @test
-     * @dataProvider persistedPatternMapperDataProvider
-     */
+    #[DataProvider('persistedPatternMapperDataProvider')]
+    #[Test]
     public function persistedPatternMapperIsApplied(TestSet $testSet): void
     {
         $builder = Builder::create();
@@ -153,10 +153,8 @@ final class PersistedPatternMapperTest extends AbstractEnhancerLinkGeneratorTest
         return $testSets;
     }
 
-    /**
-     * @test
-     * @dataProvider pageTypeDecoratorIsAppliedDataProvider
-     */
+    #[DataProvider('pageTypeDecoratorIsAppliedDataProvider')]
+    #[Test]
     public function pageTypeDecoratorIsApplied(TestSet $testSet): void
     {
         parent::pageTypeDecoratorIsApplied($testSet);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/RouteTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/RouteTest.php
index 7af11815b679..aeea6ade7118 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/RouteTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/RouteTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\EnhancerLinkGenerator;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\ApplicableConjunction;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\AspectDeclaration;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\Builder;
@@ -113,10 +115,8 @@ final class RouteTest extends AbstractEnhancerLinkGeneratorTestCase
             ->getTargetsForDataProvider();
     }
 
-    /**
-     * @test
-     * @dataProvider routeDefaultsForSingleParameterAreConsideredDataProvider
-     */
+    #[DataProvider('routeDefaultsForSingleParameterAreConsideredDataProvider')]
+    #[Test]
     public function routeDefaultsForSingleParameterAreConsidered(TestSet $testSet): void
     {
         $this->assertGeneratedUriEquals($testSet);
@@ -207,10 +207,8 @@ final class RouteTest extends AbstractEnhancerLinkGeneratorTestCase
             ->getTargetsForDataProvider();
     }
 
-    /**
-     * @test
-     * @dataProvider routeDefaultsForMultipleParametersAreConsideredDataProvider
-     */
+    #[DataProvider('routeDefaultsForMultipleParametersAreConsideredDataProvider')]
+    #[Test]
     public function routeDefaultsForMultipleParametersAreConsidered(TestSet $testSet): void
     {
         $this->assertGeneratedUriEquals($testSet);
@@ -285,10 +283,8 @@ final class RouteTest extends AbstractEnhancerLinkGeneratorTestCase
             ->getTargetsForDataProvider();
     }
 
-    /**
-     * @test
-     * @dataProvider routeRequirementsHavingAspectsAreConsideredDataProvider
-     */
+    #[DataProvider('routeRequirementsHavingAspectsAreConsideredDataProvider')]
+    #[Test]
     public function routeRequirementsHavingAspectsAreConsidered(TestSet $testSet): void
     {
         $this->assertGeneratedUriEquals($testSet);
@@ -451,10 +447,8 @@ final class RouteTest extends AbstractEnhancerLinkGeneratorTestCase
             ->getTargetsForDataProvider();
     }
 
-    /**
-     * @test
-     * @dataProvider nestedRouteArgumentsAreConsideredDataProvider
-     */
+    #[DataProvider('nestedRouteArgumentsAreConsideredDataProvider')]
+    #[Test]
     public function nestedRouteArgumentsAreConsidered(TestSet $testSet): void
     {
         $this->assertGeneratedUriEquals($testSet);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/StaticRangeMapperTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/StaticRangeMapperTest.php
index 07e93780b4f3..8254605d000a 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/StaticRangeMapperTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/StaticRangeMapperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\EnhancerLinkGenerator;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\AspectDeclaration;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\Builder;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\LanguageContext;
@@ -89,10 +91,8 @@ final class StaticRangeMapperTest extends AbstractEnhancerLinkGeneratorTestCase
         return self::staticRangeMapperDataProviderBuilder();
     }
 
-    /**
-     * @test
-     * @dataProvider staticRangeMapperIsAppliedDataProvider
-     */
+    #[DataProvider('staticRangeMapperIsAppliedDataProvider')]
+    #[Test]
     public function staticRangeMapperIsApplied(TestSet $testSet): void
     {
         $builder = Builder::create();
@@ -142,10 +142,8 @@ final class StaticRangeMapperTest extends AbstractEnhancerLinkGeneratorTestCase
         return $testSets;
     }
 
-    /**
-     * @test
-     * @dataProvider pageTypeDecoratorIsAppliedDataProvider
-     */
+    #[DataProvider('pageTypeDecoratorIsAppliedDataProvider')]
+    #[Test]
     public function pageTypeDecoratorIsApplied(TestSet $testSet): void
     {
         parent::pageTypeDecoratorIsApplied($testSet);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/StaticValueMapperTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/StaticValueMapperTest.php
index 45c2dffe89c9..cefb74552b75 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/StaticValueMapperTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerLinkGenerator/StaticValueMapperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\EnhancerLinkGenerator;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\AspectDeclaration;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\Builder;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\LanguageContext;
@@ -105,10 +107,8 @@ final class StaticValueMapperTest extends AbstractEnhancerLinkGeneratorTestCase
         return self::staticValueMapperDataProviderBuilder();
     }
 
-    /**
-     * @test
-     * @dataProvider staticValueMapperIsAppliedDataProvider
-     */
+    #[DataProvider('staticValueMapperIsAppliedDataProvider')]
+    #[Test]
     public function staticValueMapperIsApplied(TestSet $testSet): void
     {
         $builder = Builder::create();
@@ -161,10 +161,8 @@ final class StaticValueMapperTest extends AbstractEnhancerLinkGeneratorTestCase
         return $testSets;
     }
 
-    /**
-     * @test
-     * @dataProvider pageTypeDecoratorIsAppliedDataProvider
-     */
+    #[DataProvider('pageTypeDecoratorIsAppliedDataProvider')]
+    #[Test]
     public function pageTypeDecoratorIsApplied(TestSet $testSet): void
     {
         parent::pageTypeDecoratorIsApplied($testSet);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/LocaleModifierTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/LocaleModifierTest.php
index 0bd2a627e15a..437f27adb204 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/LocaleModifierTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/LocaleModifierTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\EnhancerSiteRequest;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\AspectDeclaration;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\Builder;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\LanguageContext;
@@ -125,10 +127,8 @@ final class LocaleModifierTest extends AbstractEnhancerSiteRequestTestCase
         return self::localeModifierDataProviderBuilder();
     }
 
-    /**
-     * @test
-     * @dataProvider localeModifierIsAppliedDataProvider
-     */
+    #[DataProvider('localeModifierIsAppliedDataProvider')]
+    #[Test]
     public function localeModifierIsApplied(TestSet $testSet): void
     {
         $this->assertPageArgumentsEquals($testSet);
@@ -149,10 +149,8 @@ final class LocaleModifierTest extends AbstractEnhancerSiteRequestTestCase
         return $testSets;
     }
 
-    /**
-     * @test
-     * @dataProvider pageTypeDecoratorIsAppliedDataProvider
-     */
+    #[DataProvider('pageTypeDecoratorIsAppliedDataProvider')]
+    #[Test]
     public function pageTypeDecoratorIsApplied(TestSet $testSet): void
     {
         parent::pageTypeDecoratorIsApplied($testSet);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/PageTypeDecoratorTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/PageTypeDecoratorTest.php
index f731e79742ba..287eb6350cff 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/PageTypeDecoratorTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/PageTypeDecoratorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\EnhancerSiteRequest;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Configuration\SiteConfiguration;
 use TYPO3\CMS\Core\Site\SiteFinder;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -56,10 +58,8 @@ final class PageTypeDecoratorTest extends AbstractEnhancerSiteRequestTestCase
         return $testSets;
     }
 
-    /**
-     * @test
-     * @dataProvider pageTypeDecoratorIsAppliedDataProvider
-     */
+    #[DataProvider('pageTypeDecoratorIsAppliedDataProvider')]
+    #[Test]
     public function pageTypeDecoratorIsApplied(TestSet $testSet): void
     {
         parent::pageTypeDecoratorIsApplied($testSet);
@@ -92,10 +92,8 @@ final class PageTypeDecoratorTest extends AbstractEnhancerSiteRequestTestCase
         return $testSets;
     }
 
-    /**
-     * @test
-     * @dataProvider pageTypeDecoratorIndexCanBePartOfSlugDataProvider
-     */
+    #[DataProvider('pageTypeDecoratorIndexCanBePartOfSlugDataProvider')]
+    #[Test]
     public function pageTypeDecoratorIndexCanBePartOfSlug(TestSet $testSet): void
     {
         $builder = Builder::create();
@@ -131,9 +129,7 @@ final class PageTypeDecoratorTest extends AbstractEnhancerSiteRequestTestCase
         self::assertEquals($expectation, $pageArguments);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function unmappedPageTypeDecoratorIsAddedAsRegularQueryParam(): void
     {
         $this->mergeSiteConfiguration('archive-acme-com', [
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/PersistedAliasMapperTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/PersistedAliasMapperTest.php
index 2186a024d39a..00345f29438d 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/PersistedAliasMapperTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/PersistedAliasMapperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\EnhancerSiteRequest;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\ApplicableConjunction;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\AspectDeclaration;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\Builder;
@@ -82,10 +84,8 @@ final class PersistedAliasMapperTest extends AbstractEnhancerSiteRequestTestCase
         return self::persistedAliasMapperDataProviderBuilder();
     }
 
-    /**
-     * @test
-     * @dataProvider persistedAliasMapperIsAppliedDataProvider
-     */
+    #[DataProvider('persistedAliasMapperIsAppliedDataProvider')]
+    #[Test]
     public function persistedAliasMapperIsApplied(TestSet $testSet): void
     {
         $this->assertPageArgumentsEquals($testSet);
@@ -135,10 +135,8 @@ final class PersistedAliasMapperTest extends AbstractEnhancerSiteRequestTestCase
             ->getTargetsForDataProvider();
     }
 
-    /**
-     * @test
-     * @dataProvider fallbackValueIsResolvedDataProvider
-     */
+    #[DataProvider('fallbackValueIsResolvedDataProvider')]
+    #[Test]
     public function fallbackValueIsResolved(TestSet $testSet): void
     {
         $this->assertPageArgumentsEquals($testSet);
@@ -159,10 +157,8 @@ final class PersistedAliasMapperTest extends AbstractEnhancerSiteRequestTestCase
         return $testSets;
     }
 
-    /**
-     * @test
-     * @dataProvider pageTypeDecoratorIsAppliedDataProvider
-     */
+    #[DataProvider('pageTypeDecoratorIsAppliedDataProvider')]
+    #[Test]
     public function pageTypeDecoratorIsApplied(TestSet $testSet): void
     {
         parent::pageTypeDecoratorIsApplied($testSet);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/PersistedPatternMapperTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/PersistedPatternMapperTest.php
index 02ee10c8eecc..efde82b0b9d3 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/PersistedPatternMapperTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/PersistedPatternMapperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\EnhancerSiteRequest;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\AspectDeclaration;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\Builder;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\LanguageContext;
@@ -80,10 +82,8 @@ final class PersistedPatternMapperTest extends AbstractEnhancerSiteRequestTestCa
         return self::persistedPatternMapperDataProviderBuilder();
     }
 
-    /**
-     * @test
-     * @dataProvider persistedPatternMapperIsAppliedDataProvider
-     */
+    #[DataProvider('persistedPatternMapperIsAppliedDataProvider')]
+    #[Test]
     public function persistedPatternMapperIsApplied(TestSet $testSet): void
     {
         $this->assertPageArgumentsEquals($testSet);
@@ -104,10 +104,8 @@ final class PersistedPatternMapperTest extends AbstractEnhancerSiteRequestTestCa
         return $testSets;
     }
 
-    /**
-     * @test
-     * @dataProvider pageTypeDecoratorIsAppliedDataProvider
-     */
+    #[DataProvider('pageTypeDecoratorIsAppliedDataProvider')]
+    #[Test]
     public function pageTypeDecoratorIsApplied(TestSet $testSet): void
     {
         parent::pageTypeDecoratorIsApplied($testSet);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/RouteTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/RouteTest.php
index be795e50a572..c9e886373aa9 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/RouteTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/RouteTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\EnhancerSiteRequest;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Error\Http\PageNotFoundException;
 use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\ApplicableConjunction;
@@ -119,10 +121,8 @@ final class RouteTest extends AbstractEnhancerSiteRequestTestCase
             ->getTargetsForDataProvider();
     }
 
-    /**
-     * @test
-     * @dataProvider routeDefaultsAreConsideredDataProvider
-     */
+    #[DataProvider('routeDefaultsAreConsideredDataProvider')]
+    #[Test]
     public function routeDefaultsAreConsidered(TestSet $testSet): void
     {
         $this->assertPageArgumentsEquals($testSet);
@@ -197,10 +197,8 @@ final class RouteTest extends AbstractEnhancerSiteRequestTestCase
             ->getTargetsForDataProvider();
     }
 
-    /**
-     * @test
-     * @dataProvider routeRequirementsHavingAspectsAreConsideredDataProvider
-     */
+    #[DataProvider('routeRequirementsHavingAspectsAreConsideredDataProvider')]
+    #[Test]
     public function routeRequirementsHavingAspectsAreConsidered(TestSet $testSet): void
     {
         $this->assertPageArgumentsEquals($testSet);
@@ -301,10 +299,8 @@ final class RouteTest extends AbstractEnhancerSiteRequestTestCase
             ->getTargetsForDataProvider();
     }
 
-    /**
-     * @test
-     * @dataProvider routeRequirementsAreConsideredDataProvider
-     */
+    #[DataProvider('routeRequirementsAreConsideredDataProvider')]
+    #[Test]
     public function routeRequirementsAreConsidered(TestSet $testSet): void
     {
         $this->assertPageArgumentsEquals($testSet);
@@ -449,10 +445,8 @@ final class RouteTest extends AbstractEnhancerSiteRequestTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider routeIdentifiersAreResolvedDataProvider
-     */
+    #[DataProvider('routeIdentifiersAreResolvedDataProvider')]
+    #[Test]
     public function routeIdentifiersAreResolved(string $namespace, string $argumentName, string $queryPath, string $failureReason = null): void
     {
         $query = [];
@@ -650,10 +644,8 @@ final class RouteTest extends AbstractEnhancerSiteRequestTestCase
             ->getTargetsForDataProvider();
     }
 
-    /**
-     * @test
-     * @dataProvider nestedRouteArgumentsAreConsideredDataProvider
-     */
+    #[DataProvider('nestedRouteArgumentsAreConsideredDataProvider')]
+    #[Test]
     public function nestedRouteArgumentsAreConsidered(TestSet $testSet): void
     {
         $this->assertPageArgumentsEquals($testSet);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/StaticRangeMapperTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/StaticRangeMapperTest.php
index 3c5d8658bf16..72dac77d9910 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/StaticRangeMapperTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/StaticRangeMapperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\EnhancerSiteRequest;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\AspectDeclaration;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\Builder;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\LanguageContext;
@@ -91,10 +93,8 @@ final class StaticRangeMapperTest extends AbstractEnhancerSiteRequestTestCase
         return self::staticRangeMapperDataProviderBuilder();
     }
 
-    /**
-     * @test
-     * @dataProvider staticRangeMapperIsAppliedDataProvider
-     */
+    #[DataProvider('staticRangeMapperIsAppliedDataProvider')]
+    #[Test]
     public function staticRangeMapperIsApplied(TestSet $testSet): void
     {
         $this->assertPageArgumentsEquals($testSet);
@@ -115,10 +115,8 @@ final class StaticRangeMapperTest extends AbstractEnhancerSiteRequestTestCase
         return $testSets;
     }
 
-    /**
-     * @test
-     * @dataProvider pageTypeDecoratorIsAppliedDataProvider
-     */
+    #[DataProvider('pageTypeDecoratorIsAppliedDataProvider')]
+    #[Test]
     public function pageTypeDecoratorIsApplied(TestSet $testSet): void
     {
         parent::pageTypeDecoratorIsApplied($testSet);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/StaticValueMapperTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/StaticValueMapperTest.php
index 9a11c0783423..77bbbbfc2d1a 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/StaticValueMapperTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/EnhancerSiteRequest/StaticValueMapperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\EnhancerSiteRequest;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\AspectDeclaration;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\Builder;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder\LanguageContext;
@@ -88,10 +90,8 @@ final class StaticValueMapperTest extends AbstractEnhancerSiteRequestTestCase
         return static::staticValueMapperDataProviderBuilder();
     }
 
-    /**
-     * @test
-     * @dataProvider staticValueMapperIsAppliedDataProvider
-     */
+    #[DataProvider('staticValueMapperIsAppliedDataProvider')]
+    #[Test]
     public function staticValueMapperIsApplied(TestSet $testSet): void
     {
         $this->assertPageArgumentsEquals($testSet);
@@ -112,10 +112,8 @@ final class StaticValueMapperTest extends AbstractEnhancerSiteRequestTestCase
         return $testSets;
     }
 
-    /**
-     * @test
-     * @dataProvider pageTypeDecoratorIsAppliedDataProvider
-     */
+    #[DataProvider('pageTypeDecoratorIsAppliedDataProvider')]
+    #[Test]
     public function pageTypeDecoratorIsApplied(TestSet $testSet): void
     {
         parent::pageTypeDecoratorIsApplied($testSet);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LinkGeneratorFreeModeTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LinkGeneratorFreeModeTest.php
index d57656ac0ceb..c3dd7b99e4e4 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LinkGeneratorFreeModeTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LinkGeneratorFreeModeTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerWriter;
@@ -132,10 +134,8 @@ final class LinkGeneratorFreeModeTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%2$d->%3$d (lang:%4$d)');
     }
 
-    /**
-     * @test
-     * @dataProvider linkIsGeneratedForLanguageDataProvider
-     */
+    #[DataProvider('linkIsGeneratedForLanguageDataProvider')]
+    #[Test]
     public function linkIsGeneratedForLanguageWithLanguageProperty(string $hostPrefix, int $sourcePageId, int $targetPageId, int $targetLanguageId, string $expectation): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -176,10 +176,8 @@ final class LinkGeneratorFreeModeTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider languageMenuIsGeneratedDataProvider
-     */
+    #[DataProvider('languageMenuIsGeneratedDataProvider')]
+    #[Test]
     public function languageMenuIsGenerated(string $hostPrefix, int $sourcePageId, array $expectation): void
     {
         $response = $this->executeFrontendSubRequest(
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioATest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioATest.php
index 912b3dcc449d..4f5b33a9aebf 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioATest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioATest.php
@@ -17,6 +17,9 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\LocalizedPageRendering;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
+
 /**
  * Language container test definition
  *
@@ -81,10 +84,8 @@ final class ScenarioATest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider resolvablePagesDataProvider
-     */
+    #[DataProvider('resolvablePagesDataProvider')]
+    #[Test]
     public function resolvedPagesMatchScopes(string $url, array $scopes): void
     {
         $this->assertScopes($url, $scopes);
@@ -114,10 +115,8 @@ final class ScenarioATest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider menuDataProvider
-     */
+    #[DataProvider('menuDataProvider')]
+    #[Test]
     public function pageMenuIsRendered(string $url, array $expectedMenu): void
     {
         $this->assertMenu($url, $expectedMenu);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioBTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioBTest.php
index fcc54ced1da6..d40a739a3cb2 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioBTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioBTest.php
@@ -17,6 +17,9 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\LocalizedPageRendering;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
+
 /**
  * Scenario prerequisites:
  *   Site configuration has localizations
@@ -86,10 +89,8 @@ final class ScenarioBTest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider resolvablePagesDataProvider
-     */
+    #[DataProvider('resolvablePagesDataProvider')]
+    #[Test]
     public function resolvedPagesMatchScopes(string $url, array $scopes): void
     {
         $this->assertScopes($url, $scopes);
@@ -104,10 +105,8 @@ final class ScenarioBTest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider pageNotFoundDataProvider
-     */
+    #[DataProvider('pageNotFoundDataProvider')]
+    #[Test]
     public function pageNotFound(string $url): void
     {
         $this->assertResponseStatusCode($url);
@@ -133,10 +132,8 @@ final class ScenarioBTest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider menuDataProvider
-     */
+    #[DataProvider('menuDataProvider')]
+    #[Test]
     public function pageMenuIsRendered(string $url, array $expectedMenu): void
     {
         $this->assertMenu($url, $expectedMenu);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioCTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioCTest.php
index a4e3f50dcb7b..d68301443f74 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioCTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioCTest.php
@@ -17,6 +17,9 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\LocalizedPageRendering;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
+
 /**
  * Scenario prerequisites:
  *   Site configuration has localizations
@@ -87,10 +90,8 @@ final class ScenarioCTest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider resolvablePagesDataProvider
-     */
+    #[DataProvider('resolvablePagesDataProvider')]
+    #[Test]
     public function resolvedPagesMatchScopes(string $url, array $scopes): void
     {
         $this->assertScopes($url, $scopes);
@@ -108,10 +109,8 @@ final class ScenarioCTest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider pageNotFoundDataProvider
-     */
+    #[DataProvider('pageNotFoundDataProvider')]
+    #[Test]
     public function pageNotFound(string $url): void
     {
         $this->assertResponseStatusCode($url);
@@ -149,10 +148,8 @@ final class ScenarioCTest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider menuDataProvider
-     */
+    #[DataProvider('menuDataProvider')]
+    #[Test]
     public function pageMenuIsRendered(string $url, array $expectedMenu): void
     {
         $this->assertMenu($url, $expectedMenu);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioDTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioDTest.php
index 769eed27caf4..26a1810d5b9d 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioDTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioDTest.php
@@ -17,6 +17,9 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\LocalizedPageRendering;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
+
 /**
  * Scenario prerequisites:
  *   Site configuration has localizations
@@ -92,10 +95,8 @@ final class ScenarioDTest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider resolvablePagesDataProvider
-     */
+    #[DataProvider('resolvablePagesDataProvider')]
+    #[Test]
     public function resolvedPagesMatchScopes(string $url, array $scopes): void
     {
         $this->assertScopes($url, $scopes);
@@ -116,10 +117,8 @@ final class ScenarioDTest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider pageNotFoundDataProvider
-     */
+    #[DataProvider('pageNotFoundDataProvider')]
+    #[Test]
     public function pageNotFound(string $url): void
     {
         $this->assertResponseStatusCode($url);
@@ -167,18 +166,14 @@ final class ScenarioDTest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider menuDataProvider
-     */
+    #[DataProvider('menuDataProvider')]
+    #[Test]
     public function pageMenuIsRendered(string $url, array $expectedMenu): void
     {
         $this->assertMenu($url, $expectedMenu);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function languageMenuHasLanguageShortcutsWithLanguageSpecificUrls(): void
     {
         $expectedMenu = [
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioETest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioETest.php
index 42bdcab1896a..ff9bb12819cd 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioETest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioETest.php
@@ -17,6 +17,9 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\LocalizedPageRendering;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
+
 /**
  * Scenario prerequisites:
  *   Site configuration has localizations
@@ -84,10 +87,8 @@ final class ScenarioETest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider resolvablePagesDataProvider
-     */
+    #[DataProvider('resolvablePagesDataProvider')]
+    #[Test]
     public function resolvedPagesMatchScopes(string $url, array $scopes): void
     {
         $this->assertScopes($url, $scopes);
@@ -114,10 +115,8 @@ final class ScenarioETest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider pageNotFoundDataProvider
-     */
+    #[DataProvider('pageNotFoundDataProvider')]
+    #[Test]
     public function pageNotFound(string $url): void
     {
         $this->assertResponseStatusCode($url);
@@ -152,10 +151,8 @@ final class ScenarioETest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider menuDataProvider
-     */
+    #[DataProvider('menuDataProvider')]
+    #[Test]
     public function pageMenuIsRendered(string $url, array $expectedMenu): void
     {
         $this->assertMenu($url, $expectedMenu);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioFTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioFTest.php
index 9d8dedde8031..a95be7619409 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioFTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioFTest.php
@@ -17,6 +17,9 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\LocalizedPageRendering;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
+
 /**
  * Scenario prerequisites:
  *   Site configuration has localizations
@@ -86,10 +89,8 @@ final class ScenarioFTest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider resolvablePagesDataProvider
-     */
+    #[DataProvider('resolvablePagesDataProvider')]
+    #[Test]
     public function resolvedPagesMatchScopes(string $url, array $scopes): void
     {
         $this->assertScopes($url, $scopes);
@@ -119,10 +120,8 @@ final class ScenarioFTest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider pageNotFoundDataProvider
-     */
+    #[DataProvider('pageNotFoundDataProvider')]
+    #[Test]
     public function pageNotFound(string $url): void
     {
         $this->assertResponseStatusCode($url);
@@ -158,10 +157,8 @@ final class ScenarioFTest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider menuDataProvider
-     */
+    #[DataProvider('menuDataProvider')]
+    #[Test]
     public function pageMenuIsRendered(string $url, array $expectedMenu): void
     {
         $this->assertMenu($url, $expectedMenu);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioGTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioGTest.php
index e6cb101e33ac..c860b33f8308 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioGTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/LocalizedPageRendering/ScenarioGTest.php
@@ -17,6 +17,9 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\LocalizedPageRendering;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
+
 /**
  * Scenario prerequisites:
  *   Site configuration has localizations
@@ -67,10 +70,8 @@ final class ScenarioGTest extends AbstractLocalizedPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider menuDataProvider
-     */
+    #[DataProvider('menuDataProvider')]
+    #[Test]
     public function pageMenuIsRendered(string $url, array $expectedMenu): void
     {
         $this->assertMenu($url, $expectedMenu);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/MountPointTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/MountPointTest.php
index 191dfd93dd76..173fc195df61 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/MountPointTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/MountPointTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerWriter;
@@ -346,10 +348,8 @@ final class MountPointTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider hierarchicalMenuIsGeneratedDataProvider
-     */
+    #[DataProvider('hierarchicalMenuIsGeneratedDataProvider')]
+    #[Test]
     public function hierarchicalMenuIsGenerated(string $accessedUrl, array $expectation): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -401,10 +401,8 @@ final class MountPointTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider requestsResolvePageIdAndMountPointParameterDataProvider
-     */
+    #[DataProvider('requestsResolvePageIdAndMountPointParameterDataProvider')]
+    #[Test]
     public function requestsResolvePageIdAndMountPointParameter(string $uri, int $rootPageId, int $expectedPageId, ?string $expectedMountPointParameter): void
     {
         $this->setUpFrontendRootPage(
@@ -445,10 +443,9 @@ final class MountPointTest extends AbstractTestCase
      * This test checks for "mount_pid_ol=0", whereas mount_pid_ol=1 should trigger a redirect currently.
      * @todo: revisit the "mount_pid_ol=1" redirect, there is some truth to it, but still would
      * remove the context, which does not make sense. Should be revisited. See test above as well.
-     *
-     * @dataProvider mountPointPagesShowContentAsConfiguredDataProvider
-     * @test
      */
+    #[DataProvider('mountPointPagesShowContentAsConfiguredDataProvider')]
+    #[Test]
     public function mountPointPagesShowContentAsConfigured(string $uri, string $expected): void
     {
         $this->setUpFrontendRootPage(
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/RequestHandlerTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/RequestHandlerTest.php
index a120f696a5ce..3dfdd7a2d92a 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/RequestHandlerTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/RequestHandlerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Frontend\Cache\NonceValueSubstitution;
@@ -68,9 +69,7 @@ final class RequestHandlerTest extends AbstractTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test whether two subsequent requests have different nonce values
-     */
+    #[Test]
     public function nonceAttributesForAssetsAreUpdated(): void
     {
         $firstResponse = $this->executeFrontendSubRequest(new InternalRequest('https://website.local/welcome'));
@@ -102,9 +101,7 @@ final class RequestHandlerTest extends AbstractTestCase
         // self::assertStringStartsWith('Cached page generated', $secondResponse->getHeaderLine('X-TYPO3-Debug-Cache'));
     }
 
-    /**
-     * @test whether NonceValueSubstitution is invoked via permanent `INTincScript` instruction
-     */
+    #[Test]
     public function nonceValueSubstitutionIsInvoked(): void
     {
         $nonceValueSubstitutionMock = $this->createMock(NonceValueSubstitution::class);
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/SiteRequestTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/SiteRequestTest.php
index 84c4ec6a8271..1b1353646c4f 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/SiteRequestTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/SiteRequestTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\UriInterface;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Http\Uri;
@@ -73,10 +75,8 @@ final class SiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider shortcutsAreRedirectedDataProvider
-     */
+    #[DataProvider('shortcutsAreRedirectedDataProvider')]
+    #[Test]
     public function shortcutsAreRedirectedToFirstSubPage(string $uri): void
     {
         $this->writeSiteConfiguration(
@@ -95,10 +95,8 @@ final class SiteRequestTest extends AbstractTestCase
         self::assertSame($expectedHeaders, $response->getHeaders());
     }
 
-    /**
-     * @test
-     * @dataProvider shortcutsAreRedirectedDataProvider
-     */
+    #[DataProvider('shortcutsAreRedirectedDataProvider')]
+    #[Test]
     public function shortcutsAreRedirectedAndRenderFirstSubPage(string $uri): void
     {
         $this->writeSiteConfiguration(
@@ -166,10 +164,8 @@ final class SiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider pageIsRenderedWithPathsDataProvider
-     */
+    #[DataProvider('pageIsRenderedWithPathsDataProvider')]
+    #[Test]
     public function pageIsRenderedWithPaths(string $uri, string $expectedPageTitle): void
     {
         $this->writeSiteConfiguration(
@@ -230,10 +226,8 @@ final class SiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider pageIsRenderedWithPathsAndChineseDefaultLanguageDataProvider
-     */
+    #[DataProvider('pageIsRenderedWithPathsAndChineseDefaultLanguageDataProvider')]
+    #[Test]
     public function pageIsRenderedWithPathsAndChineseDefaultLanguage(string $uri, string $expectedPageTitle): void
     {
         $this->writeSiteConfiguration(
@@ -268,10 +262,8 @@ final class SiteRequestTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider pageIsRenderedWithPathsAndChineseBaseDataProvider
-     */
+    #[DataProvider('pageIsRenderedWithPathsAndChineseBaseDataProvider')]
+    #[Test]
     public function pageIsRenderedWithPathsAndChineseBase(string $uri, string $expectedPageTitle): void
     {
         $this->writeSiteConfiguration(
@@ -333,10 +325,8 @@ final class SiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider pageIsRenderedWithDomainsDataProvider
-     */
+    #[DataProvider('pageIsRenderedWithDomainsDataProvider')]
+    #[Test]
     public function pageIsRenderedWithDomains(string $uri, string $expectedPageTitle): void
     {
         $this->writeSiteConfiguration(
@@ -406,10 +396,8 @@ final class SiteRequestTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%1$s (user:%2$s)');
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageIsRenderedDataProvider
-     */
+    #[DataProvider('restrictedPageIsRenderedDataProvider')]
+    #[Test]
     public function restrictedPageIsRendered(string $uri, int $frontendUserId, string $expectedPageTitle): void
     {
         $this->writeSiteConfiguration(
@@ -458,10 +446,8 @@ final class SiteRequestTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%1$s (user:%2$s)');
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
-     */
+    #[DataProvider('restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
+    #[Test]
     public function restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithoutHavingErrorHandling(string $uri, int $frontendUserId): void
     {
         $this->writeSiteConfiguration(
@@ -488,10 +474,10 @@ final class SiteRequestTest extends AbstractTestCase
     }
 
     /**
-     * @test
-     * @dataProvider restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
      * @todo Response body cannot be asserted since PageContentErrorHandler::handlePageError executes request via HTTP (not internally)
      */
+    #[DataProvider('restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
+    #[Test]
     public function restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPageErrorHandling(string $uri, int $frontendUserId): void
     {
         self::markTestSkipped('Skipped until PageContentErrorHandler::handlePageError does not use HTTP anymore');
@@ -514,10 +500,8 @@ final class SiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
-     */
+    #[DataProvider('restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
+    #[Test]
     public function restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPhpErrorHandling(string $uri, int $frontendUserId): void
     {
         $this->writeSiteConfiguration(
@@ -555,10 +539,8 @@ final class SiteRequestTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%1$s (user:%2$s)');
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageWithParentSysFolderIsRenderedDataProvider
-     */
+    #[DataProvider('restrictedPageWithParentSysFolderIsRenderedDataProvider')]
+    #[Test]
     public function restrictedPageWithParentSysFolderIsRendered(string $uri, int $frontendUserId, string $expectedPageTitle): void
     {
         $this->writeSiteConfiguration(
@@ -599,10 +581,8 @@ final class SiteRequestTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%1$s (user:%2$s)');
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
-     */
+    #[DataProvider('restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
+    #[Test]
     public function restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingFluidErrorHandling(string $uri, int $frontendUserId): void
     {
         $this->writeSiteConfiguration(
@@ -635,10 +615,10 @@ final class SiteRequestTest extends AbstractTestCase
     }
 
     /**
-     * @test
-     * @dataProvider restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
      * @todo Response body cannot be asserted since PageContentErrorHandler::handlePageError executes request via HTTP (not internally)
      */
+    #[DataProvider('restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
+    #[Test]
     public function restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPageErrorHandling(string $uri, int $frontendUserId): void
     {
         self::markTestSkipped('Skipped until PageContentErrorHandler::handlePageError does not use HTTP anymore');
@@ -661,10 +641,8 @@ final class SiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
-     */
+    #[DataProvider('restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
+    #[Test]
     public function restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPhpErrorHandling(string $uri, int $frontendUserId): void
     {
         $this->writeSiteConfiguration(
@@ -705,10 +683,8 @@ final class SiteRequestTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%1$s (user:%2$s)');
     }
 
-    /**
-     * @test
-     * @dataProvider hiddenPageSends404ResponseRegardlessOfVisitorGroupDataProvider
-     */
+    #[DataProvider('hiddenPageSends404ResponseRegardlessOfVisitorGroupDataProvider')]
+    #[Test]
     public function hiddenPageSends404ResponseRegardlessOfVisitorGroup(string $uri, int $frontendUserId): void
     {
         $this->writeSiteConfiguration(
@@ -756,10 +732,8 @@ final class SiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider pageRenderingStopsWithInvalidCacheHashDataProvider
-     */
+    #[DataProvider('pageRenderingStopsWithInvalidCacheHashDataProvider')]
+    #[Test]
     public function pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingFluidErrorHandling(string $uri): void
     {
         $this->writeSiteConfiguration(
@@ -785,10 +759,10 @@ final class SiteRequestTest extends AbstractTestCase
     }
 
     /**
-     * @test
-     * @dataProvider pageRenderingStopsWithInvalidCacheHashDataProvider
      * @todo Response body cannot be asserted since PageContentErrorHandler::handlePageError executes request via HTTP (not internally)
      */
+    #[DataProvider('pageRenderingStopsWithInvalidCacheHashDataProvider')]
+    #[Test]
     public function pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingPageErrorHandling(string $uri): void
     {
         self::markTestSkipped('Skipped until PageContentErrorHandler::handlePageError does not use HTTP anymore');
@@ -808,10 +782,8 @@ final class SiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider pageRenderingStopsWithInvalidCacheHashDataProvider
-     */
+    #[DataProvider('pageRenderingStopsWithInvalidCacheHashDataProvider')]
+    #[Test]
     public function pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingPhpErrorHandling(string $uri): void
     {
         $this->writeSiteConfiguration(
@@ -862,10 +834,8 @@ final class SiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider pageIsRenderedWithValidCacheHashDataProvider
-     */
+    #[DataProvider('pageIsRenderedWithValidCacheHashDataProvider')]
+    #[Test]
     public function pageIsRenderedWithValidCacheHash($uri): void
     {
         $this->writeSiteConfiguration(
@@ -902,10 +872,8 @@ final class SiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider checkIfIndexPhpReturnsShortcutRedirectWithPageIdAndTypeNumProvidedDataProvider
-     */
+    #[DataProvider('checkIfIndexPhpReturnsShortcutRedirectWithPageIdAndTypeNumProvidedDataProvider')]
+    #[Test]
     public function checkIfIndexPhpReturnsShortcutRedirectWithPageIdAndTypeNumProvided(string $uri)
     {
         $this->writeSiteConfiguration(
@@ -975,10 +943,8 @@ final class SiteRequestTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider crossSiteShortcutsAreRedirectedDataProvider
-     */
+    #[DataProvider('crossSiteShortcutsAreRedirectedDataProvider')]
+    #[Test]
     public function crossSiteShortcutsAreRedirected(string $uri, int $expectedStatusCode, array $expectedHeaders): void
     {
         $this->writeSiteConfiguration(
@@ -1023,10 +989,8 @@ final class SiteRequestTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider crossSiteShortcutsWithWrongSiteHostSendsPageNotFoundWithoutHavingErrorHandlingDataProvider
-     */
+    #[DataProvider('crossSiteShortcutsWithWrongSiteHostSendsPageNotFoundWithoutHavingErrorHandlingDataProvider')]
+    #[Test]
     public function crossSiteShortcutsWithWrongSiteHostSendsPageNotFoundWithoutHavingErrorHandling(string $uri): void
     {
         $this->writeSiteConfiguration(
@@ -1084,10 +1048,8 @@ final class SiteRequestTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getUrisWithInvalidLegacyQueryParameters
-     */
+    #[DataProvider('getUrisWithInvalidLegacyQueryParameters')]
+    #[Test]
     public function requestWithInvalidLegacyQueryParametersDisplayPageNotFoundPage(UriInterface $uri): void
     {
         $this->writeSiteConfiguration(
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugLinkGeneratorTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugLinkGeneratorTest.php
index 16418efd09cb..b68c634402f5 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugLinkGeneratorTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugLinkGeneratorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Domain\Repository\PageRepository;
@@ -125,10 +127,8 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%2$d->%3$d');
     }
 
-    /**
-     * @test
-     * @dataProvider linkIsGeneratedDataProvider
-     */
+    #[DataProvider('linkIsGeneratedDataProvider')]
+    #[Test]
     public function linkIsGenerated(string $hostPrefix, int $sourcePageId, int $targetPageId, string $expectation): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -187,10 +187,8 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider linkIsGeneratedFromMountPointDataProvider
-     */
+    #[DataProvider('linkIsGeneratedFromMountPointDataProvider')]
+    #[Test]
     public function linkIsGeneratedFromMountPoint(string $hostPrefix, array $pageMount, int $sourcePageId, int $targetPageId, string $expectation): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -250,10 +248,8 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%2$d->%3$d (lang:%4$d)');
     }
 
-    /**
-     * @test
-     * @dataProvider linkIsGeneratedForLanguageDataProvider
-     */
+    #[DataProvider('linkIsGeneratedForLanguageDataProvider')]
+    #[Test]
     public function linkIsGeneratedForLanguageWithLanguageProperty(string $hostPrefix, int $sourcePageId, int $targetPageId, int $targetLanguageId, string $expectation): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -304,10 +300,8 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider linkIsGeneratedWithQueryParametersDataProvider
-     */
+    #[DataProvider('linkIsGeneratedWithQueryParametersDataProvider')]
+    #[Test]
     public function linkIsGeneratedWithQueryParameters(string $hostPrefix, int $sourcePageId, int $targetPageId, string $expectation): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -358,10 +352,8 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%2$d->%3$d (user:%4$d)');
     }
 
-    /**
-     * @test
-     * @dataProvider linkIsGeneratedForRestrictedPageDataProvider
-     */
+    #[DataProvider('linkIsGeneratedForRestrictedPageDataProvider')]
+    #[Test]
     public function linkIsGeneratedForRestrictedPage(string $hostPrefix, int $sourcePageId, int $targetPageId, int $frontendUserId, string $expectation): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -413,10 +405,8 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%2$d->%3$d (via: %4$d, user:%5$d)');
     }
 
-    /**
-     * @test
-     * @dataProvider linkIsGeneratedForRestrictedPageUsingLoginPageDataProvider
-     */
+    #[DataProvider('linkIsGeneratedForRestrictedPageUsingLoginPageDataProvider')]
+    #[Test]
     public function linkIsGeneratedForRestrictedPageUsingLoginPage(string $hostPrefix, int $sourcePageId, int $targetPageId, int $loginPageId, int $frontendUserId, string $expectation): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -462,10 +452,8 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%2$d->%3$d (language: %4$d)');
     }
 
-    /**
-     * @test
-     * @dataProvider linkIsGeneratedForRestrictedPageForGuestsUsingTypolinkLinkAccessRestrictedPagesDataProvider
-     */
+    #[DataProvider('linkIsGeneratedForRestrictedPageForGuestsUsingTypolinkLinkAccessRestrictedPagesDataProvider')]
+    #[Test]
     public function linkIsGeneratedForRestrictedPageForGuestsUsingTypolinkLinkAccessRestrictedPages(string $hostPrefix, int $sourcePageId, int $targetPageId, int $languageId, string $expectation): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -510,10 +498,8 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%2$d->%3$d (resolve:%4$d, be_user:%5$d)');
     }
 
-    /**
-     * @test
-     * @dataProvider linkIsGeneratedForPageVersionDataProvider
-     */
+    #[DataProvider('linkIsGeneratedForPageVersionDataProvider')]
+    #[Test]
     public function linkIsGeneratedForPageVersion(string $hostPrefix, int $sourcePageId, int $targetPageId, bool $resolveVersion, int $backendUserId, string $expectation): void
     {
         $workspaceId = 1;
@@ -699,10 +685,8 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider hierarchicalMenuIsGeneratedDataProvider
-     */
+    #[DataProvider('hierarchicalMenuIsGeneratedDataProvider')]
+    #[Test]
     public function hierarchicalMenuIsGenerated(string $hostPrefix, int $sourcePageId, array $expectation): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -725,9 +709,7 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
         self::assertSame($expectation, $json);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hierarchicalMenuDoesNotShowHiddenPagesAsSubMenu(): void
     {
         $expectation = [
@@ -847,10 +829,8 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider hierarchicalMenuSetsActiveStateProperlyDataProvider
-     */
+    #[DataProvider('hierarchicalMenuSetsActiveStateProperlyDataProvider')]
+    #[Test]
     public function hierarchicalMenuSetsActiveStateProperly(string $hostPrefix, int $sourcePageId, string $menuPageIds, array $expectation, int $languageId = 0): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -913,10 +893,9 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
 
     /**
      * Checks that excludeUidList checks against translated pages and default-language page IDs.
-     *
-     * @test
-     * @dataProvider hierarchicalMenuAlwaysResolvesToDefaultLanguageDataProvider
      */
+    #[DataProvider('hierarchicalMenuAlwaysResolvesToDefaultLanguageDataProvider')]
+    #[Test]
     public function hierarchicalMenuAlwaysResolvesToDefaultLanguage(int $languageId, string $excludedUidList, int $expectedMenuItems): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -1065,10 +1044,8 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider directoryMenuIsGeneratedDataProvider
-     */
+    #[DataProvider('directoryMenuIsGeneratedDataProvider')]
+    #[Test]
     public function directoryMenuIsGenerated(string $hostPrefix, int $sourcePageId, int $directoryMenuParentPage, int $backendUserId, int $workspaceId, array $expectation): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -1154,10 +1131,8 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider directoryMenuToAccessRestrictedPagesIsGeneratedDataProvider
-     */
+    #[DataProvider('directoryMenuToAccessRestrictedPagesIsGeneratedDataProvider')]
+    #[Test]
     public function directoryMenuToAccessRestrictedPagesIsGenerated(string $hostPrefix, int $sourcePageId, int $directoryMenuParentPage, int $loginPageId, int $backendUserId, int $workspaceId, array $expectation): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -1286,10 +1261,8 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider listMenuIsGeneratedDataProvider
-     */
+    #[DataProvider('listMenuIsGeneratedDataProvider')]
+    #[Test]
     public function listMenuIsGenerated(string $hostPrefix, int $sourcePageId, array $menuPageIds, int $backendUserId, int $workspaceId, array $additionalMenuConfiguration, array $expectation): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -1364,10 +1337,8 @@ final class SlugLinkGeneratorTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider languageMenuIsGeneratedDataProvider
-     */
+    #[DataProvider('languageMenuIsGeneratedDataProvider')]
+    #[Test]
     public function languageMenuIsGenerated(string $hostPrefix, int $sourcePageId, array $expectation): void
     {
         $response = $this->executeFrontendSubRequest(
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteRequestAllowInsecureSiteResolutionByQueryParametersDisabledTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteRequestAllowInsecureSiteResolutionByQueryParametersDisabledTest.php
index 19acf4c21991..4d7cc0c20bf7 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteRequestAllowInsecureSiteResolutionByQueryParametersDisabledTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteRequestAllowInsecureSiteResolutionByQueryParametersDisabledTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerWriter;
@@ -87,10 +89,8 @@ final class SlugSiteRequestAllowInsecureSiteResolutionByQueryParametersDisabledT
         yield 'invalid cross-site request *not* denied' => ['https://website.local/?id=3000&L=0', 404];
     }
 
-    /**
-     * @test
-     * @dataProvider siteWithPageIdRequestsAreCorrectlyHandledDataProvider
-     */
+    #[DataProvider('siteWithPageIdRequestsAreCorrectlyHandledDataProvider')]
+    #[Test]
     public function siteWithPageIdRequestsAreCorrectlyHandled(string $uri, int $expectation): void
     {
         $this->writeSiteConfiguration(
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteRequestAllowInsecureSiteResolutionByQueryParametersEnabledTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteRequestAllowInsecureSiteResolutionByQueryParametersEnabledTest.php
index baa159fb892f..09d38cbe701b 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteRequestAllowInsecureSiteResolutionByQueryParametersEnabledTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteRequestAllowInsecureSiteResolutionByQueryParametersEnabledTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerWriter;
@@ -89,10 +91,8 @@ final class SlugSiteRequestAllowInsecureSiteResolutionByQueryParametersEnabledTe
         yield 'invalid cross-site request *not* denied' => ['https://website.local/?id=3000&L=0', 200];
     }
 
-    /**
-     * @test
-     * @dataProvider siteWithPageIdRequestsAreCorrectlyHandledDataProvider
-     */
+    #[DataProvider('siteWithPageIdRequestsAreCorrectlyHandledDataProvider')]
+    #[Test]
     public function siteWithPageIdRequestsAreCorrectlyHandled(string $uri, int $expectation): void
     {
         $this->writeSiteConfiguration(
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteRequestTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteRequestTest.php
index 32357b5cf688..c27bd28a4b90 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteRequestTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteRequestTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\UriInterface;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Http\Uri;
@@ -83,10 +85,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider requestsAreRedirectedWithoutHavingDefaultSiteLanguageDataProvider
-     */
+    #[DataProvider('requestsAreRedirectedWithoutHavingDefaultSiteLanguageDataProvider')]
+    #[Test]
     public function requestsAreRedirectedWithoutHavingDefaultSiteLanguage(string $uri): void
     {
         $this->writeSiteConfiguration(
@@ -118,10 +118,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider shortcutsAreRedirectedDataProvider
-     */
+    #[DataProvider('shortcutsAreRedirectedDataProvider')]
+    #[Test]
     public function shortcutsAreRedirectedToDefaultSiteLanguage(string $uri): void
     {
         $this->writeSiteConfiguration(
@@ -142,10 +140,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         self::assertSame($expectedHeaders, $response->getHeaders());
     }
 
-    /**
-     * @test
-     * @dataProvider shortcutsAreRedirectedDataProvider
-     */
+    #[DataProvider('shortcutsAreRedirectedDataProvider')]
+    #[Test]
     public function shortcutsAreRedirectedAndRenderFirstSubPage(string $uri): void
     {
         $this->writeSiteConfiguration(
@@ -191,10 +187,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider shortcutsAreRedirectedDataProviderWithChineseCharacterInBase
-     */
+    #[DataProvider('shortcutsAreRedirectedDataProviderWithChineseCharacterInBase')]
+    #[Test]
     public function shortcutsAreRedirectedToDefaultSiteLanguageWithChineseCharacterInBase(string $uri): void
     {
         $this->writeSiteConfiguration(
@@ -217,10 +211,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         self::assertSame($expectedHeaders, $response->getHeaders());
     }
 
-    /**
-     * @test
-     * @dataProvider shortcutsAreRedirectedDataProviderWithChineseCharacterInBase
-     */
+    #[DataProvider('shortcutsAreRedirectedDataProviderWithChineseCharacterInBase')]
+    #[Test]
     public function shortcutsAreRedirectedAndRenderFirstSubPageWithChineseCharacterInBase(string $uri): void
     {
         $this->writeSiteConfiguration(
@@ -253,9 +245,7 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function invalidSiteResultsInNotFoundResponse(): void
     {
         $this->writeSiteConfiguration(
@@ -284,10 +274,9 @@ final class SlugSiteRequestTest extends AbstractTestCase
      * For variants, please see `SlugSiteRequestAllowInsecureSiteResolutionByQueryParametersEnabledTest`
      * and `SlugSiteRequestAllowInsecureSiteResolutionByQueryParametersDisabledTest` which had to be placed
      * in separate test class files, due to hard limitations of the TYPO3 Testing Framework.
-     *
-     * @test
-     * @dataProvider siteWithPageIdRequestsAreCorrectlyHandledDataProvider
      */
+    #[DataProvider('siteWithPageIdRequestsAreCorrectlyHandledDataProvider')]
+    #[Test]
     public function siteWithPageIdRequestsAreCorrectlyHandled(string $uri, int $expectation): void
     {
         $this->writeSiteConfiguration(
@@ -303,9 +292,7 @@ final class SlugSiteRequestTest extends AbstractTestCase
         self::assertSame($expectation, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function invalidSlugOutsideSiteLanguageResultsInNotFoundResponse(): void
     {
         $this->writeSiteConfiguration(
@@ -330,9 +317,7 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function invalidSlugInsideSiteLanguageResultsInNotFoundResponse(): void
     {
         $this->writeSiteConfiguration(
@@ -357,9 +342,7 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function unconfiguredTypeNumResultsIn500Error(): void
     {
         $this->writeSiteConfiguration(
@@ -409,10 +392,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider pageIsRenderedWithPathsDataProvider
-     */
+    #[DataProvider('pageIsRenderedWithPathsDataProvider')]
+    #[Test]
     public function pageIsRenderedWithPaths(string $uri, string $expectedPageTitle): void
     {
         $this->writeSiteConfiguration(
@@ -463,10 +444,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider pageIsRenderedWithPathsAndChineseDefaultLanguageDataProvider
-     */
+    #[DataProvider('pageIsRenderedWithPathsAndChineseDefaultLanguageDataProvider')]
+    #[Test]
     public function pageIsRenderedWithPathsAndChineseDefaultLanguage(string $uri, string $expectedPageTitle): void
     {
         $this->writeSiteConfiguration(
@@ -520,10 +499,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider pageIsRenderedWithDomainsDataProvider
-     */
+    #[DataProvider('pageIsRenderedWithDomainsDataProvider')]
+    #[Test]
     public function pageIsRenderedWithDomains(string $uri, string $expectedPageTitle): void
     {
         $this->writeSiteConfiguration(
@@ -552,9 +529,7 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageWithTrailingSlashSlugIsRenderedIfRequestedWithSlash(): void
     {
         $uri = 'https://website.us/features/frontend-editing/';
@@ -575,9 +550,7 @@ final class SlugSiteRequestTest extends AbstractTestCase
         self::assertSame('EN: Frontend Editing', $responseStructure->getScopePath('page/title'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageWithTrailingSlashSlugIsRenderedIfRequestedWithoutSlash(): void
     {
         $uri = 'https://website.us/features/frontend-editing';
@@ -598,9 +571,7 @@ final class SlugSiteRequestTest extends AbstractTestCase
         self::assertSame('EN: Frontend Editing', $responseStructure->getScopePath('page/title'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageWithoutTrailingSlashSlugIsRenderedIfRequestedWithSlash(): void
     {
         $uri = 'https://website.us/features/';
@@ -621,9 +592,7 @@ final class SlugSiteRequestTest extends AbstractTestCase
         self::assertSame('EN: Features', $responseStructure->getScopePath('page/title'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageWithoutTrailingSlashSlugIsRenderedIfRequestedWithoutSlash(): void
     {
         $uri = 'https://website.us/features';
@@ -668,10 +637,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%1$s (user:%2$s)');
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageIsRenderedDataProvider
-     */
+    #[DataProvider('restrictedPageIsRenderedDataProvider')]
+    #[Test]
     public function restrictedPageIsRendered(string $uri, int $frontendUserId, string $expectedPageTitle): void
     {
         $this->writeSiteConfiguration(
@@ -706,10 +673,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%1$s (user:%2$s)');
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageWithParentSysFolderIsRenderedDataProvider
-     */
+    #[DataProvider('restrictedPageWithParentSysFolderIsRenderedDataProvider')]
+    #[Test]
     public function restrictedPageWithParentSysFolderIsRendered(string $uri, int $frontendUserId, string $expectedPageTitle): void
     {
         $this->writeSiteConfiguration(
@@ -755,10 +720,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%1$s (user:%2$s)');
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
-     */
+    #[DataProvider('restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
+    #[Test]
     public function restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithoutHavingErrorHandling(string $uri, int $frontendUserId): void
     {
         $this->writeSiteConfiguration(
@@ -784,10 +747,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
-     */
+    #[DataProvider('restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
+    #[Test]
     public function restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithHavingFluidErrorHandling(string $uri, int $frontendUserId): void
     {
         $this->writeSiteConfiguration(
@@ -819,10 +780,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
-     */
+    #[DataProvider('restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
+    #[Test]
     public function restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPageErrorHandling(string $uri, int $frontendUserId): void
     {
         $this->writeSiteConfiguration(
@@ -851,10 +810,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
-     */
+    #[DataProvider('restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
+    #[Test]
     public function restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPhpErrorHandling(string $uri, int $frontendUserId): void
     {
         $this->writeSiteConfiguration(
@@ -898,10 +855,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%1$s (user:%2$s)');
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
-     */
+    #[DataProvider('restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
+    #[Test]
     public function restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithoutHavingErrorHandling(string $uri, int $frontendUserId): void
     {
         $this->writeSiteConfiguration(
@@ -927,10 +882,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
-     */
+    #[DataProvider('restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
+    #[Test]
     public function restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingFluidErrorHandling(string $uri, int $frontendUserId): void
     {
         $this->writeSiteConfiguration(
@@ -962,10 +915,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
-     */
+    #[DataProvider('restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
+    #[Test]
     public function restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPageErrorHandling(string $uri, int $frontendUserId): void
     {
         $this->writeSiteConfiguration(
@@ -994,10 +945,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
-     */
+    #[DataProvider('restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
+    #[Test]
     public function restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPhpErrorHandling(string $uri, int $frontendUserId): void
     {
         $this->writeSiteConfiguration(
@@ -1038,10 +987,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%1$s (user:%2$s)');
     }
 
-    /**
-     * @test
-     * @dataProvider hiddenPageSends404ResponseRegardlessOfVisitorGroupDataProvider
-     */
+    #[DataProvider('hiddenPageSends404ResponseRegardlessOfVisitorGroupDataProvider')]
+    #[Test]
     public function hiddenPageSends404ResponseRegardlessOfVisitorGroup(string $uri, int $frontendUserId): void
     {
         $this->writeSiteConfiguration(
@@ -1088,10 +1035,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider pageRenderingStopsWithInvalidCacheHashDataProvider
-     */
+    #[DataProvider('pageRenderingStopsWithInvalidCacheHashDataProvider')]
+    #[Test]
     public function pageRequestNotFoundInvalidCacheHashWithoutHavingErrorHandling(string $uri): void
     {
         $this->writeSiteConfiguration(
@@ -1103,10 +1048,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         self::assertSame(404, $response->getStatusCode());
     }
 
-    /**
-     * @test
-     * @dataProvider pageRenderingStopsWithInvalidCacheHashDataProvider
-     */
+    #[DataProvider('pageRenderingStopsWithInvalidCacheHashDataProvider')]
+    #[Test]
     public function pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingFluidErrorHandling(string $uri): void
     {
         $this->writeSiteConfiguration(
@@ -1131,10 +1074,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider pageRenderingStopsWithInvalidCacheHashDataProvider
-     */
+    #[DataProvider('pageRenderingStopsWithInvalidCacheHashDataProvider')]
+    #[Test]
     public function pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingPageErrorHandling(string $uri): void
     {
         $this->writeSiteConfiguration(
@@ -1156,10 +1097,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider pageRenderingStopsWithInvalidCacheHashDataProvider
-     */
+    #[DataProvider('pageRenderingStopsWithInvalidCacheHashDataProvider')]
+    #[Test]
     public function pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingPhpErrorHandling(string $uri): void
     {
         $this->writeSiteConfiguration(
@@ -1208,10 +1147,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider pageIsRenderedWithValidCacheHashDataProvider
-     */
+    #[DataProvider('pageIsRenderedWithValidCacheHashDataProvider')]
+    #[Test]
     public function pageIsRenderedWithValidCacheHash($uri): void
     {
         $this->writeSiteConfiguration(
@@ -1249,10 +1186,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider crossSiteShortcutsAreRedirectedDataProvider
-     */
+    #[DataProvider('crossSiteShortcutsAreRedirectedDataProvider')]
+    #[Test]
     public function crossSiteShortcutsAreRedirected(string $uri, int $expectedStatusCode, array $expectedHeaders): void
     {
         $this->writeSiteConfiguration(
@@ -1323,10 +1258,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider pageIsRenderedForVersionedPageDataProvider
-     */
+    #[DataProvider('pageIsRenderedForVersionedPageDataProvider')]
+    #[Test]
     public function pageIsRenderedForVersionedPage(string $url, ?string $expectedPageTitle, ?int $expectedPageId, int $workspaceId, int $backendUserId, int $expectedStatusCode): void
     {
         $this->writeSiteConfiguration(
@@ -1896,9 +1829,9 @@ final class SlugSiteRequestTest extends AbstractTestCase
 
     /**
      * @link https://forge.typo3.org/issues/96010
-     * @test
-     * @dataProvider defaultLanguagePageNotResolvedForSiteLanguageBaseIfLanguagePageExistsDataProvider
      */
+    #[DataProvider('defaultLanguagePageNotResolvedForSiteLanguageBaseIfLanguagePageExistsDataProvider')]
+    #[Test]
     public function defaultLanguagePageNotResolvedForSiteLanguageBaseIfLanguagePageExists(string $uri, array $recordUpdates, array $fallbackIdentifiers, string $fallbackType, int $expectedStatusCode, ?string $expectedPageTitle): void
     {
         $this->writeSiteConfiguration(
@@ -2727,9 +2660,9 @@ final class SlugSiteRequestTest extends AbstractTestCase
 
     /**
      * @link https://forge.typo3.org/issues/88715
-     * @test
-     * @dataProvider defaultLanguagePageNotResolvedForSiteLanguageBaseWithNonDefaultLanguageShorterUriIfLanguagePageExistsDataProvider
      */
+    #[DataProvider('defaultLanguagePageNotResolvedForSiteLanguageBaseWithNonDefaultLanguageShorterUriIfLanguagePageExistsDataProvider')]
+    #[Test]
     public function defaultLanguagePageNotResolvedForSiteLanguageBaseWithNonDefaultLanguageShorterUriIfLanguagePageExists(string $uri, array $recordUpdates, array $fallbackIdentifiers, string $fallbackType, int $expectedStatusCode, ?string $expectedPageTitle): void
     {
         $this->writeSiteConfiguration(
@@ -2794,10 +2727,8 @@ final class SlugSiteRequestTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getUrisWithInvalidLegacyQueryParameters
-     */
+    #[DataProvider('getUrisWithInvalidLegacyQueryParameters')]
+    #[Test]
     public function requestWithInvalidLegacyQueryParametersDisplayPageNotFoundPage(UriInterface $uri): void
     {
         $this->writeSiteConfiguration(
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteWithoutRequiredCHashRequestTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteWithoutRequiredCHashRequestTest.php
index 095f820ec04c..b4c10f11c3ba 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteWithoutRequiredCHashRequestTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/SlugSiteWithoutRequiredCHashRequestTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Utility\PermutationUtility;
 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
@@ -85,10 +87,8 @@ final class SlugSiteWithoutRequiredCHashRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider pageRenderingStopsWithInvalidCacheHashDataProvider
-     */
+    #[DataProvider('pageRenderingStopsWithInvalidCacheHashDataProvider')]
+    #[Test]
     public function pageRequestSendsNotFoundResponseWithInvalidCacheHash(string $uri): void
     {
         $this->writeSiteConfiguration(
@@ -133,10 +133,8 @@ final class SlugSiteWithoutRequiredCHashRequestTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider pageIsRenderedWithValidCacheHashDataProvider
-     */
+    #[DataProvider('pageIsRenderedWithValidCacheHashDataProvider')]
+    #[Test]
     public function pageIsRenderedWithValidCacheHash($uri): void
     {
         $this->writeSiteConfiguration(
diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/TypoLinkGeneratorTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/TypoLinkGeneratorTest.php
index 6eed91de00e1..b4a8c3e042e1 100644
--- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/TypoLinkGeneratorTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/TypoLinkGeneratorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\ResponseInterface;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Database\ConnectionPool;
@@ -213,10 +215,8 @@ final class TypoLinkGeneratorTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%1$s;');
     }
 
-    /**
-     * @test
-     * @dataProvider linkIsGeneratedDataProvider
-     */
+    #[DataProvider('linkIsGeneratedDataProvider')]
+    #[Test]
     public function linkIsGenerated(string $parameter, string $expectation): void
     {
         $response = $this->invokeTypoLink($parameter);
@@ -308,10 +308,8 @@ final class TypoLinkGeneratorTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider ATagParamsAreAddedInOrderDataProvider
-     */
+    #[DataProvider('ATagParamsAreAddedInOrderDataProvider')]
+    #[Test]
     public function ATagParamsAreAddedInOrder(array $instructions, string $globalATagParams, string $linkText, string $expectation): void
     {
         $sourcePageId = 1100;
@@ -464,20 +462,16 @@ final class TypoLinkGeneratorTest extends AbstractTestCase
         return self::keysFromTemplate($instructions, '%1$s;');
     }
 
-    /**
-     * @test
-     * @dataProvider linkIsEncodedDataProvider
-     */
+    #[DataProvider('linkIsEncodedDataProvider')]
+    #[Test]
     public function linkIsEncodedPerDefault(string $parameter, string $expectation): void
     {
         $response = $this->invokeTypoLink($parameter);
         self::assertSame($expectation, (string)$response->getBody());
     }
 
-    /**
-     * @test
-     * @dataProvider linkIsEncodedDataProvider
-     */
+    #[DataProvider('linkIsEncodedDataProvider')]
+    #[Test]
     public function linkIsEncodedHavingParseFunc(string $parameter, string $expectation): void
     {
         $response = $this->invokeTypoLink($parameter, $this->createParseFuncInstruction([
@@ -552,10 +546,8 @@ final class TypoLinkGeneratorTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider linkToPageIsProcessedDataProvider
-     */
+    #[DataProvider('linkToPageIsProcessedDataProvider')]
+    #[Test]
     public function linkToPageIsProcessed(string $parameter, string $expectation, bool $parseFuncEnabled): void
     {
         $instructions = [];
@@ -620,10 +612,8 @@ final class TypoLinkGeneratorTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider linkWithoutAnchorIsGeneratedDataProvider
-     */
+    #[DataProvider('linkWithoutAnchorIsGeneratedDataProvider')]
+    #[Test]
     public function linkWithoutAnchorIsGenerated(array $instructions, string $linkText, string $expectation): void
     {
         $sourcePageId = 1100;
diff --git a/typo3/sysext/frontend/Tests/Functional/Tca/BackendLayoutVisibleFieldsTest.php b/typo3/sysext/frontend/Tests/Functional/Tca/BackendLayoutVisibleFieldsTest.php
index e387e708c8fa..f4471cb29c91 100644
--- a/typo3/sysext/frontend/Tests/Functional/Tca/BackendLayoutVisibleFieldsTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Tca/BackendLayoutVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -32,9 +33,7 @@ final class BackendLayoutVisibleFieldsTest extends FunctionalTestCase
         'description',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function backendLayoutsFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/frontend/Tests/Functional/Tca/ContentVisibleFieldsTest.php b/typo3/sysext/frontend/Tests/Functional/Tca/ContentVisibleFieldsTest.php
index 22006865591d..115af02f82c2 100644
--- a/typo3/sysext/frontend/Tests/Functional/Tca/ContentVisibleFieldsTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Tca/ContentVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -112,9 +113,7 @@ final class ContentVisibleFieldsTest extends FunctionalTestCase
         ],
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function contentFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/frontend/Tests/Functional/Tca/FrontendGroupsVisibleFieldsTest.php b/typo3/sysext/frontend/Tests/Functional/Tca/FrontendGroupsVisibleFieldsTest.php
index 049de77968e7..8798afdc9bad 100644
--- a/typo3/sysext/frontend/Tests/Functional/Tca/FrontendGroupsVisibleFieldsTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Tca/FrontendGroupsVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -32,9 +33,7 @@ final class FrontendGroupsVisibleFieldsTest extends FunctionalTestCase
         'tx_extbase_type',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function frontendGroupsFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/frontend/Tests/Functional/Tca/FrontendUsersVisibleFieldsTest.php b/typo3/sysext/frontend/Tests/Functional/Tca/FrontendUsersVisibleFieldsTest.php
index 57f9f4d3fb7f..a736749ed8e0 100644
--- a/typo3/sysext/frontend/Tests/Functional/Tca/FrontendUsersVisibleFieldsTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Tca/FrontendUsersVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -49,9 +50,7 @@ final class FrontendUsersVisibleFieldsTest extends FunctionalTestCase
         'tx_extbase_type',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function frontendUsersFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/frontend/Tests/Functional/Tca/PagesLanguageOverlayVisibleFieldsTest.php b/typo3/sysext/frontend/Tests/Functional/Tca/PagesLanguageOverlayVisibleFieldsTest.php
index ec8afd5f67a2..cd5906465c9a 100644
--- a/typo3/sysext/frontend/Tests/Functional/Tca/PagesLanguageOverlayVisibleFieldsTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Tca/PagesLanguageOverlayVisibleFieldsTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Domain\Repository\PageRepository;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
@@ -147,10 +149,8 @@ final class PagesLanguageOverlayVisibleFieldsTest extends FunctionalTestCase
         return $pageTypes;
     }
 
-    /**
-     * @test
-     * @dataProvider pagesLanguageOverlayFormContainsExpectedFieldsDataProvider
-     */
+    #[DataProvider('pagesLanguageOverlayFormContainsExpectedFieldsDataProvider')]
+    #[Test]
     public function pagesLanguageOverlayFormContainsExpectedFields(int $doktype, array $expectedFields, array $hiddenFields): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/frontend/Tests/Functional/Tca/TemplateVisibleFieldsTest.php b/typo3/sysext/frontend/Tests/Functional/Tca/TemplateVisibleFieldsTest.php
index 0bbdb38d9ecc..6679d3120f36 100644
--- a/typo3/sysext/frontend/Tests/Functional/Tca/TemplateVisibleFieldsTest.php
+++ b/typo3/sysext/frontend/Tests/Functional/Tca/TemplateVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -40,9 +41,7 @@ final class TemplateVisibleFieldsTest extends FunctionalTestCase
         'endtime',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function templateFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/frontend/Tests/FunctionalDeprecated/Configuration/TypoScript/ConditionMatching/ConditionMatcherTest.php b/typo3/sysext/frontend/Tests/FunctionalDeprecated/Configuration/TypoScript/ConditionMatching/ConditionMatcherTest.php
index 695fd0b8e700..4b11d215e9e2 100644
--- a/typo3/sysext/frontend/Tests/FunctionalDeprecated/Configuration/TypoScript/ConditionMatching/ConditionMatcherTest.php
+++ b/typo3/sysext/frontend/Tests/FunctionalDeprecated/Configuration/TypoScript/ConditionMatching/ConditionMatcherTest.php
@@ -17,7 +17,9 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Frontend\Tests\FunctionalDeprecated\Configuration\TypoScript\ConditionMatching;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Log\NullLogger;
+use Symfony\Component\ExpressionLanguage\Node\BinaryNode;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\UserAspect;
@@ -50,9 +52,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether usergroup comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function usergroupConditionMatchesSingleGroupId(): void
     {
         $this->setupFrontendUserContext([13]);
@@ -64,9 +65,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether usergroup comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function usergroupConditionMatchesMultipleUserGroupId(): void
     {
         $this->setupFrontendUserContext([13, 14, 15]);
@@ -78,9 +78,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether usergroup comparison does not match.
-     *
-     * @test
      */
+    #[Test]
     public function usergroupConditionDoesNotMatchDefaultUserGroupIds(): void
     {
         $this->setupFrontendUserContext([0, -1]);
@@ -91,9 +90,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether checking for a user group user matches
-     *
-     * @test
      */
+    #[Test]
     public function frontendUserGroupInOperatorConditionMatchesGroupId(): void
     {
         $this->setupFrontendUserContext([13, 14, 15]);
@@ -103,9 +101,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether checking for a user group user matches
-     *
-     * @test
      */
+    #[Test]
     public function backendUserGroupInOperatorConditionMatchesGroupId(): void
     {
         $backendUser = new BackendUserAuthentication();
@@ -118,9 +115,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether user comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function loginUserConditionMatchesAnyLoggedInUser(): void
     {
         $this->setupFrontendUserContext([13]);
@@ -131,9 +127,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether user comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function loginUserConditionMatchesSingleLoggedInUser(): void
     {
         $this->setupFrontendUserContext([13, 14, 15]);
@@ -145,9 +140,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether user comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function loginUserConditionMatchesMultipleLoggedInUsers(): void
     {
         $this->setupFrontendUserContext([13, 14, 15]);
@@ -158,9 +152,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether user comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function loginUserConditionDoesNotMatchIfNotUserIsLoggedId(): void
     {
         $this->setupFrontendUserContext();
@@ -174,9 +167,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether user is not logged in
-     *
-     * @test
      */
+    #[Test]
     public function loginUserConditionMatchIfUserIsNotLoggedIn(): void
     {
         $this->setupFrontendUserContext();
@@ -187,9 +179,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether checking for workspace id matches current workspace id
-     *
-     * @test
      */
+    #[Test]
     public function workspaceIdConditionMatchesCurrentWorkspaceId(): void
     {
         $this->setUpWorkspaceAspect(0);
@@ -202,9 +193,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether checking if workspace is live matches
-     *
-     * @test
      */
+    #[Test]
     public function workspaceIsLiveMatchesCorrectWorkspaceState(): void
     {
         $this->setUpWorkspaceAspect(1);
@@ -218,9 +208,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether checking if workspace is offline matches
-     *
-     * @test
      */
+    #[Test]
     public function workspaceIsOfflineMatchesCorrectWorkspaceState(): void
     {
         $this->setUpWorkspaceAspect(1);
@@ -234,9 +223,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether treeLevel comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function treeLevelConditionMatchesSingleValue(): void
     {
         self::assertTrue($this->getConditionMatcher()->match('[tree.level == 2]'));
@@ -244,9 +232,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether treeLevel comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function treeLevelConditionMatchesMultipleValues(): void
     {
         self::assertTrue($this->getConditionMatcher()->match('[tree.level in [999,998,2]]'));
@@ -254,9 +241,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether treeLevel comparison matches.
-     *
-     * @test
      */
+    #[Test]
     public function treeLevelConditionDoesNotMatchFaultyValue(): void
     {
         self::assertFalse($this->getConditionMatcher()->match('[tree.level == 999]'));
@@ -264,9 +250,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether a page Id is found in the previous rootline entries.
-     *
-     * @test
      */
+    #[Test]
     public function PIDupinRootlineConditionMatchesSinglePageIdInRootline(): void
     {
         $subject = $this->getConditionMatcher();
@@ -289,9 +274,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether a page id is not found in the previous rootline entries.
-     *
-     * @test
      */
+    #[Test]
     public function PIDupinRootlineConditionDoesNotMatchLastPageIdInRootline(): void
     {
         self::assertFalse($this->getConditionMatcher()->match('[3 in tree.rootLineParentIds]'));
@@ -299,9 +283,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether a page Id is found in the previous rootline entries.
-     *
-     * @test
      */
+    #[Test]
     public function PIDupinRootlineConditionDoesNotMatchPageIdNotInRootline(): void
     {
         self::assertFalse($this->getConditionMatcher()->match('[999 in tree.rootLineParentIds]'));
@@ -309,9 +292,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether a page Id is found in all rootline entries.
-     *
-     * @test
      */
+    #[Test]
     public function PIDinRootlineConditionMatchesSinglePageIdInRootline(): void
     {
         $this->setupFrontendController(3);
@@ -319,9 +301,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether a page Id is found in all rootline entries.
-     *
-     * @test
      */
+    #[Test]
     public function PIDinRootlineConditionMatchesLastPageIdInRootline(): void
     {
         self::assertTrue($this->getConditionMatcher()->match('[3 in tree.rootLineIds]'));
@@ -329,9 +310,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether a page Id is found in all rootline entries.
-     *
-     * @test
      */
+    #[Test]
     public function PIDinRootlineConditionDoesNotMatchPageIdNotInRootline(): void
     {
         self::assertFalse($this->getConditionMatcher()->match('[999 in tree.rootLineIds]'));
@@ -340,9 +320,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
     /**
      * Tests whether the compatibility version can be evaluated.
      * (e.g. 7.9 is compatible to 7.0 but not to 15.0)
-     *
-     * @test
      */
+    #[Test]
     public function compatVersionConditionMatchesOlderRelease(): void
     {
         $subject = $this->getConditionMatcher();
@@ -354,9 +333,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
     /**
      * Tests whether the compatibility version can be evaluated.
      * (e.g. 7.9 is compatible to 7.0 but not to 15.0)
-     *
-     * @test
      */
+    #[Test]
     public function compatVersionConditionMatchesSameRelease(): void
     {
         $typo3Version = new Typo3Version();
@@ -366,9 +344,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
     /**
      * Tests whether the compatibility version can be evaluated.
      * (e.g. 7.9 is compatible to 7.0 but not to 15.0)
-     *
-     * @test
      */
+    #[Test]
     public function compatVersionConditionDoesNotMatchNewerRelease(): void
     {
         $subject = $this->getConditionMatcher();
@@ -379,9 +356,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether the generic fetching of variables works with the namespace 'TSFE'.
-     *
-     * @test
      */
+    #[Test]
     public function genericGetVariablesSucceedsWithNamespaceTSFE(): void
     {
         $GLOBALS['TSFE']->id = 1234567;
@@ -392,9 +368,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether the generic fetching of variables works with the namespace 'session'.
-     *
-     * @test
      */
+    #[Test]
     public function genericGetVariablesSucceedsWithNamespaceSession(): void
     {
         $frontendUserAuthenticationMock = $this->createMock(FrontendUserAuthentication::class);
@@ -406,9 +381,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether the generic fetching of variables works with the namespace 'ENV'.
-     *
-     * @test
      */
+    #[Test]
     public function genericGetVariablesSucceedsWithNamespaceENV(): void
     {
         $testKey = StringUtility::getUniqueId('test');
@@ -418,9 +392,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether any property of a site language matches the request
-     *
-     * @test
      */
+    #[Test]
     public function siteLanguageMatchesCondition(): void
     {
         $site = new Site('angelo', 13, [
@@ -446,9 +419,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether any property of a site language does NOT match the request
-     *
-     * @test
      */
+    #[Test]
     public function siteLanguageDoesNotMatchCondition(): void
     {
         $site = new Site('angelo', 13, [
@@ -473,9 +445,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether any property of a site matches the request
-     *
-     * @test
      */
+    #[Test]
     public function siteMatchesCondition(): void
     {
         $site = new Site('angelo', 13, ['languages' => [], 'base' => 'https://typo3.org/']);
@@ -488,9 +459,8 @@ final class ConditionMatcherTest extends FunctionalTestCase
 
     /**
      * Tests whether any property of a site that does NOT match the request
-     *
-     * @test
      */
+    #[Test]
     public function siteDoesNotMatchCondition(): void
     {
         $site = new Site('angelo', 13, [
@@ -514,11 +484,11 @@ final class ConditionMatcherTest extends FunctionalTestCase
     }
 
     /**
-     * @test
      * @todo: It would be good to have another FE related test that actively sets up a page tree and uses a
      *        condition like "[tree.pagelayout == "pagets__simple"]" to make sure the full FE processing chain
      *        including TS parsing kicks in properly.
      */
+    #[Test]
     public function pageLayoutIsResolvedCorrectlyFromBackendLayoutNextLevel(): void
     {
         $fullRootLine = [
@@ -544,11 +514,11 @@ final class ConditionMatcherTest extends FunctionalTestCase
     }
 
     /**
-     * @test
      * @todo: It would be good to have another FE related test that actively sets up a page tree and uses a
      *        condition like "[tree.pagelayout == "pagets__simple"]" to make sure the full FE processing chain
      *        including TS parsing kicks in properly.
      */
+    #[Test]
     public function pageLayoutIsResolvedCorrectlyFromBackendLayout(): void
     {
         $GLOBALS['TSFE']->page = [
@@ -641,7 +611,7 @@ final class ConditionMatcherTest extends FunctionalTestCase
         // Symfony 7 dropped the `inArray` method with 7.0.0 from the BinaryNode, so we can use it as a check here for
         // the version and avoid to deal with composer version information here.
         return method_exists(
-            \Symfony\Component\ExpressionLanguage\Node\BinaryNode::class,
+            BinaryNode::class,
             'inArray'
         ) === false;
     }
diff --git a/typo3/sysext/impexp/Tests/Functional/Command/ExportCommandTest.php b/typo3/sysext/impexp/Tests/Functional/Command/ExportCommandTest.php
index f3a9d5edb524..2237f8b7b77a 100644
--- a/typo3/sysext/impexp/Tests/Functional/Command/ExportCommandTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Command/ExportCommandTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Impexp\Tests\Functional\Command;
 
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\Console\Tester\CommandTester;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Impexp\Command\ExportCommand;
@@ -25,9 +26,7 @@ use TYPO3\CMS\Impexp\Tests\Functional\AbstractImportExportTestCase;
 
 final class ExportCommandTest extends AbstractImportExportTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function exportCommandRequiresNoArguments(): void
     {
         $exportMock = $this->getAccessibleMock(Export::class, ['setMetaData']);
@@ -37,9 +36,7 @@ final class ExportCommandTest extends AbstractImportExportTestCase
         self::assertEquals(0, $tester->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exportCommandSavesExportWithGivenFileName(): void
     {
         $fileName = 'empty_export';
@@ -56,9 +53,7 @@ final class ExportCommandTest extends AbstractImportExportTestCase
         self::assertXmlFileEqualsXmlFile(__DIR__ . '/../Fixtures/XmlExports/empty.xml', $filePath);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exportCommandPassesArgumentsToExportObject(): void
     {
         $input = [
diff --git a/typo3/sysext/impexp/Tests/Functional/Command/ImportCommandTest.php b/typo3/sysext/impexp/Tests/Functional/Command/ImportCommandTest.php
index ad49c00731fc..3e0f3453ea23 100644
--- a/typo3/sysext/impexp/Tests/Functional/Command/ImportCommandTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Command/ImportCommandTest.php
@@ -17,6 +17,9 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Impexp\Tests\Functional\Command;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
+use Symfony\Component\Console\Exception\RuntimeException;
 use Symfony\Component\Console\Output\Output;
 use Symfony\Component\Console\Tester\CommandTester;
 use TYPO3\CMS\Impexp\Command\ImportCommand;
@@ -25,20 +28,16 @@ use TYPO3\CMS\Impexp\Tests\Functional\AbstractImportExportTestCase;
 
 final class ImportCommandTest extends AbstractImportExportTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function importCommandRequiresFileArgument(): void
     {
-        $this->expectException(\Symfony\Component\Console\Exception\RuntimeException::class);
+        $this->expectException(RuntimeException::class);
         $this->expectExceptionMessage('Not enough arguments (missing: "file")');
         $tester = new CommandTester(new ImportCommand(new Import()));
         $tester->execute([], []);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importCommandRequiresFileArgumentOnly(): void
     {
         $filePath = 'EXT:impexp/Tests/Functional/Fixtures/XmlImports/sys_news.xml';
@@ -47,9 +46,7 @@ final class ImportCommandTest extends AbstractImportExportTestCase
         self::assertEquals(0, $tester->getStatusCode());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importCommandPassesArgumentsToImportObject(): void
     {
         $input = [
@@ -133,10 +130,8 @@ final class ImportCommandTest extends AbstractImportExportTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider importCommandFailsDataProvider
-     */
+    #[DataProvider('importCommandFailsDataProvider')]
+    #[Test]
     public function importCommandFails(array $input, string $expected): void
     {
         $tester = new CommandTester(new ImportCommand(new Import()));
diff --git a/typo3/sysext/impexp/Tests/Functional/Export/ExportPageTreeViewTest.php b/typo3/sysext/impexp/Tests/Functional/Export/ExportPageTreeViewTest.php
index e4c942a88bce..89b42f5d9b49 100644
--- a/typo3/sysext/impexp/Tests/Functional/Export/ExportPageTreeViewTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Export/ExportPageTreeViewTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Impexp\Tests\Functional\Export;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Impexp\Export;
 use TYPO3\CMS\Impexp\Tests\Functional\AbstractImportExportTestCase;
@@ -38,10 +40,8 @@ final class ExportPageTreeViewTest extends AbstractImportExportTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider printTreeSucceedsDataProvider
-     */
+    #[DataProvider('printTreeSucceedsDataProvider')]
+    #[Test]
     public function printTreeSucceeds(int $pid, int $levels, int $expectedTreeItemsCount): void
     {
         // @todo: This test needs an overhaul.
diff --git a/typo3/sysext/impexp/Tests/Functional/Export/IrreTutorialRecordsTest.php b/typo3/sysext/impexp/Tests/Functional/Export/IrreTutorialRecordsTest.php
index b5d0f79f6fe9..4a9f76ba1ac8 100644
--- a/typo3/sysext/impexp/Tests/Functional/Export/IrreTutorialRecordsTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Export/IrreTutorialRecordsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Impexp\Tests\Functional\Export;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Impexp\Export;
 use TYPO3\CMS\Impexp\Tests\Functional\AbstractImportExportTestCase;
 
@@ -31,9 +32,7 @@ final class IrreTutorialRecordsTest extends AbstractImportExportTestCase
         'typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_irre_mnattributesimple',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exportIrreRecords(): void
     {
         $recordTypesIncludeFields = include __DIR__ . '/../Fixtures/IrreRecordsIncludeFields.php';
diff --git a/typo3/sysext/impexp/Tests/Functional/Export/MultilingualPagesAndTtContentTest.php b/typo3/sysext/impexp/Tests/Functional/Export/MultilingualPagesAndTtContentTest.php
index 02013651cfb3..cdd718b79af2 100644
--- a/typo3/sysext/impexp/Tests/Functional/Export/MultilingualPagesAndTtContentTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Export/MultilingualPagesAndTtContentTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Impexp\Tests\Functional\Export;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Impexp\Export;
 use TYPO3\CMS\Impexp\Tests\Functional\AbstractImportExportTestCase;
 
@@ -62,9 +63,7 @@ final class MultilingualPagesAndTtContentTest extends AbstractImportExportTestCa
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/tt_content-multilingual.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exportMultilingualPagesAndRelatedTtContent(): void
     {
         $subject = $this->getAccessibleMock(Export::class, ['setMetaData']);
@@ -83,9 +82,7 @@ final class MultilingualPagesAndTtContentTest extends AbstractImportExportTestCa
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exportSingleLanguagePageAndRelatedTtContent(): void
     {
         $subject = $this->getAccessibleMock(Export::class, ['setMetaData']);
@@ -113,9 +110,7 @@ final class MultilingualPagesAndTtContentTest extends AbstractImportExportTestCa
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exportOnlySingleLanguagePageAndRelatedTtContent(): void
     {
         $subject = $this->getAccessibleMock(Export::class, ['setMetaData']);
diff --git a/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentTest.php b/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentTest.php
index 72c8238b872c..2dd302ff77bd 100644
--- a/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Impexp\Tests\Functional\Export;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Impexp\Export;
 use TYPO3\CMS\Impexp\Tests\Functional\AbstractImportExportTestCase;
 
@@ -74,9 +75,7 @@ final class PagesAndTtContentTest extends AbstractImportExportTestCase
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/sys_file-export-pages-and-tt-content.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exportPagesAndRelatedTtContent(): void
     {
         $subject = $this->getAccessibleMock(Export::class, ['setMetaData']);
@@ -96,9 +95,7 @@ final class PagesAndTtContentTest extends AbstractImportExportTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exportPagesAndRelatedTtContentWithComplexConfiguration(): void
     {
         $subject = $this->getAccessibleMock(Export::class, ['setMetaData']);
diff --git a/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithImagesTest.php b/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithImagesTest.php
index ad4b10efbf3d..0ba0a3b48f04 100644
--- a/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithImagesTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithImagesTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Impexp\Tests\Functional\Export;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Impexp\Export;
 use TYPO3\CMS\Impexp\Tests\Functional\AbstractImportExportTestCase;
 
@@ -37,9 +38,7 @@ final class PagesAndTtContentWithImagesTest extends AbstractImportExportTestCase
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/sys_file_storage.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exportPagesAndRelatedTtContentWithImages(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/sys_file.csv');
@@ -57,9 +56,7 @@ final class PagesAndTtContentWithImagesTest extends AbstractImportExportTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exportPagesAndRelatedTtContentWithImagesFromCorruptSysFileRecord(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/sys_file_corrupt.csv');
@@ -82,9 +79,7 @@ final class PagesAndTtContentWithImagesTest extends AbstractImportExportTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exportPagesAndRelatedTtContentWithImagesButNotIncluded(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/sys_file.csv');
@@ -104,9 +99,7 @@ final class PagesAndTtContentWithImagesTest extends AbstractImportExportTestCase
         self::assertFileEquals(__DIR__ . '/../Fixtures/Folders/fileadmin/user_upload/typo3_image2.jpg', $temporaryFilesDirectory . '/' . 'da9acdf1e105784a57bbffec9520969578287797');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exportPagesAndRelatedTtContentWithImagesButNotIncludedAndInvalidHash(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/sys_file_invalid_hash.csv');
diff --git a/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithRelationsAndSoftrefsTest.php b/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithRelationsAndSoftrefsTest.php
index 691405ccae55..54ba8e327cae 100644
--- a/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithRelationsAndSoftrefsTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithRelationsAndSoftrefsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Impexp\Tests\Functional\Export;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Impexp\Export;
 use TYPO3\CMS\Impexp\Tests\Functional\AbstractImportExportTestCase;
 
@@ -63,9 +64,7 @@ final class PagesAndTtContentWithRelationsAndSoftrefsTest extends AbstractImport
         ]
     ;
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exportPagesAndRelatedTtContentWithFlexFormRelation(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/pages.csv');
@@ -107,9 +106,7 @@ final class PagesAndTtContentWithRelationsAndSoftrefsTest extends AbstractImport
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exportPagesAndRelatedTtContentWithSoftrefs(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/pages.csv');
@@ -152,9 +149,7 @@ final class PagesAndTtContentWithRelationsAndSoftrefsTest extends AbstractImport
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function exportPagesAndRelatedTtContentWithFlexFormSoftrefs(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/pages.csv');
diff --git a/typo3/sysext/impexp/Tests/Functional/ExportTest.php b/typo3/sysext/impexp/Tests/Functional/ExportTest.php
index 403804e32808..7832a09b6a95 100644
--- a/typo3/sysext/impexp/Tests/Functional/ExportTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/ExportTest.php
@@ -15,6 +15,8 @@
 
 namespace TYPO3\CMS\Impexp\Tests\Functional;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use PHPUnit\Framework\MockObject\MockObject;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Resource\Folder;
@@ -73,9 +75,7 @@ final class ExportTest extends AbstractImportExportTestCase
         $this->exportMock = $this->getAccessibleMock(Export::class, ['setMetaData']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function creationAndDeletionOfTemporaryFolderSucceeds(): void
     {
         $temporaryFolderName = $this->exportMock->getOrCreateTemporaryFolderName();
@@ -89,9 +89,7 @@ final class ExportTest extends AbstractImportExportTestCase
         self::assertFalse(is_file($temporaryFileName));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function creationAndDeletionOfDefaultImportExportFolderSucceeds(): void
     {
         $exportFolder = $this->exportMock->getOrCreateDefaultImportExportFolder();
@@ -105,9 +103,7 @@ final class ExportTest extends AbstractImportExportTestCase
         self::assertFalse(is_file(Environment::getPublicPath() . '/' . $exportFolder->getPublicUrl() . $exportFileName));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderPreviewWithoutArgumentsReturnsBasicArray(): void
     {
         $this->exportMock->process();
@@ -120,9 +116,7 @@ final class ExportTest extends AbstractImportExportTestCase
         ], $previewData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderPreviewForExportOfPageAndRecords(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/pages.csv');
@@ -148,9 +142,7 @@ final class ExportTest extends AbstractImportExportTestCase
         self::assertEquals($renderPreviewExport, $previewData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderPreviewForExportOfPageAndRecordsWithSoftRefs(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/pages.csv');
@@ -175,9 +167,7 @@ final class ExportTest extends AbstractImportExportTestCase
         self::assertEquals($renderPreviewExport, $previewData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderPreviewForExportOfTable(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/pages.csv');
@@ -201,9 +191,7 @@ final class ExportTest extends AbstractImportExportTestCase
         self::assertEquals($renderPreviewExport, $previewData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderPreviewForExportOfRecords(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/pages.csv');
@@ -259,10 +247,9 @@ final class ExportTest extends AbstractImportExportTestCase
 
     /**
      * Temporary test until there is a complex functional test which tests addFiles() implicitly.
-     *
-     * @test
-     * @dataProvider addFilesSucceedsDataProvider
      */
+    #[DataProvider('addFilesSucceedsDataProvider')]
+    #[Test]
     public function addFilesSucceeds(array $dat, array $relations, array $expected): void
     {
         $exportMock = $this->getAccessibleMock(
@@ -279,9 +266,7 @@ final class ExportTest extends AbstractImportExportTestCase
         self::assertEquals($expected, $lines);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderSucceedsWithoutArguments(): void
     {
         $this->exportMock->process();
@@ -290,9 +275,7 @@ final class ExportTest extends AbstractImportExportTestCase
         self::assertXmlStringEqualsXmlFile(__DIR__ . '/Fixtures/XmlExports/empty.xml', $actual);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function saveXmlToFileIsDefaultAndSucceeds(): void
     {
         $this->exportMock->setExportFileName('export');
@@ -306,9 +289,7 @@ final class ExportTest extends AbstractImportExportTestCase
         self::assertXmlFileEqualsXmlFile(__DIR__ . '/Fixtures/XmlExports/empty.xml', $filePath);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function saveT3dToFileSucceeds(): void
     {
         $this->exportMock->setExportFileName('export');
@@ -327,9 +308,7 @@ final class ExportTest extends AbstractImportExportTestCase
         self::assertEquals($expected, $actual);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function saveT3dCompressedToFileSucceeds(): void
     {
         if (!function_exists('gzcompress')) {
@@ -352,9 +331,7 @@ final class ExportTest extends AbstractImportExportTestCase
         self::assertEquals($expected, $actual);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function saveToFileCleansUpTemporaryFolder(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/pages.csv');
@@ -381,9 +358,7 @@ final class ExportTest extends AbstractImportExportTestCase
         self::assertEmpty($this->exportMock->_get('temporaryFolderName'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function saveToFileCleansUpFormerExportsOfSameName(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/pages.csv');
diff --git a/typo3/sysext/impexp/Tests/Functional/Import/ImagesWithStoragesTest.php b/typo3/sysext/impexp/Tests/Functional/Import/ImagesWithStoragesTest.php
index 77727c79803d..6f84e9438491 100644
--- a/typo3/sysext/impexp/Tests/Functional/Import/ImagesWithStoragesTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Import/ImagesWithStoragesTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Impexp\Tests\Functional\Import;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Impexp\Import;
@@ -24,9 +25,7 @@ use TYPO3\CMS\Impexp\Tests\Functional\AbstractImportExportTestCase;
 
 final class ImagesWithStoragesTest extends AbstractImportExportTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function importMultipleImagesWithMultipleStorages(): void
     {
         GeneralUtility::mkdir(Environment::getPublicPath() . '/fileadmin-1');
@@ -45,9 +44,7 @@ final class ImagesWithStoragesTest extends AbstractImportExportTestCase
         self::assertFileExists(Environment::getPublicPath() . '/fileadmin-3/user_upload/typo3_image2.jpg');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importImagesWithStaticAndFallbackStorages(): void
     {
         GeneralUtility::mkdir(Environment::getPublicPath() . '/fileadmin_invalid_path');
diff --git a/typo3/sysext/impexp/Tests/Functional/Import/IrreTutorialRecordsTest.php b/typo3/sysext/impexp/Tests/Functional/Import/IrreTutorialRecordsTest.php
index 013c1cbfaaeb..2fa4aad1ff43 100644
--- a/typo3/sysext/impexp/Tests/Functional/Import/IrreTutorialRecordsTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Import/IrreTutorialRecordsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Impexp\Tests\Functional\Import;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Impexp\Import;
 use TYPO3\CMS\Impexp\Tests\Functional\AbstractImportExportTestCase;
@@ -32,9 +33,7 @@ final class IrreTutorialRecordsTest extends AbstractImportExportTestCase
         'typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_irre_mnattributesimple',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importIrreRecords(): void
     {
         $subject = GeneralUtility::makeInstance(Import::class);
diff --git a/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentTest.php b/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentTest.php
index f14ad5348f4f..28b317d99bab 100644
--- a/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Impexp\Tests\Functional\Import;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Impexp\Import;
@@ -24,9 +25,7 @@ use TYPO3\CMS\Impexp\Tests\Functional\AbstractImportExportTestCase;
 
 final class PagesAndTtContentTest extends AbstractImportExportTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContent(): void
     {
         $subject = GeneralUtility::makeInstance(Import::class);
diff --git a/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentWithImagesInEmptyDatabaseTest.php b/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentWithImagesInEmptyDatabaseTest.php
index f2efb951b8e2..5ccfac78e35f 100644
--- a/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentWithImagesInEmptyDatabaseTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentWithImagesInEmptyDatabaseTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Impexp\Tests\Functional\Import;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Impexp\Import;
@@ -24,9 +25,7 @@ use TYPO3\CMS\Impexp\Tests\Functional\AbstractImportExportTestCase;
 
 final class PagesAndTtContentWithImagesInEmptyDatabaseTest extends AbstractImportExportTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentWithImagesOnCaseSensitiveFilesystems(): void
     {
         $subject = GeneralUtility::makeInstance(Import::class);
@@ -49,9 +48,7 @@ final class PagesAndTtContentWithImagesInEmptyDatabaseTest extends AbstractImpor
         self::assertFileEquals(__DIR__ . '/../Fixtures/Folders/fileadmin/user_upload/typo3_image2.jpg', Environment::getPublicPath() . '/fileadmin/user_upload/typo3_image2.jpg');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentWithImagesOnCaseInsensitiveFilesystems(): void
     {
         $subject = GeneralUtility::makeInstance(Import::class);
@@ -74,9 +71,7 @@ final class PagesAndTtContentWithImagesInEmptyDatabaseTest extends AbstractImpor
         self::assertFileEquals(__DIR__ . '/../Fixtures/Folders/fileadmin/user_upload/typo3_image2.jpg', Environment::getPublicPath() . '/fileadmin/user_upload/typo3_image2.jpg');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseSensitiveFilesystems(): void
     {
         $subject = GeneralUtility::makeInstance(Import::class);
@@ -99,9 +94,7 @@ final class PagesAndTtContentWithImagesInEmptyDatabaseTest extends AbstractImpor
         self::assertFileEquals(__DIR__ . '/../Fixtures/Folders/fileadmin/user_upload/typo3_image2.jpg', Environment::getPublicPath() . '/fileadmin/user_upload/typo3_image2.jpg');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseInsensitiveFilesystems(): void
     {
         $subject = GeneralUtility::makeInstance(Import::class);
@@ -124,9 +117,7 @@ final class PagesAndTtContentWithImagesInEmptyDatabaseTest extends AbstractImpor
         self::assertFileEquals(__DIR__ . '/../Fixtures/Folders/fileadmin/user_upload/typo3_image2.jpg', Environment::getPublicPath() . '/fileadmin/user_upload/typo3_image2.jpg');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentWithImagesWithSpacesInPath(): void
     {
         $subject = GeneralUtility::makeInstance(Import::class);
@@ -147,9 +138,7 @@ final class PagesAndTtContentWithImagesInEmptyDatabaseTest extends AbstractImpor
         self::assertFileEquals(__DIR__ . '/../Fixtures/Folders/fileadmin/user_upload/typo3_image3.jpg', Environment::getPublicPath() . '/fileadmin/user_upload/folder_with_spaces/typo3_image3.jpg');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentWithImagesButNotIncluded(): void
     {
         $subject = GeneralUtility::makeInstance(Import::class);
@@ -169,9 +158,7 @@ final class PagesAndTtContentWithImagesInEmptyDatabaseTest extends AbstractImpor
         self::assertFileEquals(__DIR__ . '/../Fixtures/Folders/fileadmin/user_upload/typo3_image2.jpg', Environment::getPublicPath() . '/fileadmin/user_upload/typo3_image2.jpg');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentWithImageWithForcedUids(): void
     {
         $subject = GeneralUtility::makeInstance(Import::class);
@@ -200,9 +187,7 @@ final class PagesAndTtContentWithImagesInEmptyDatabaseTest extends AbstractImpor
         self::assertSame($expectedErrors, $errors);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentWithImagesAndNewStorage(): void
     {
         GeneralUtility::mkdir(Environment::getPublicPath() . '/fileadmin_invalid_path');
@@ -221,9 +206,7 @@ final class PagesAndTtContentWithImagesInEmptyDatabaseTest extends AbstractImpor
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentWithMissingImageRemovesSysFileReferenceToo(): void
     {
         $subject = GeneralUtility::makeInstance(Import::class);
diff --git a/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentWithImagesInFilledDatabaseTest.php b/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentWithImagesInFilledDatabaseTest.php
index 43d1baefd235..a52d7e907281 100644
--- a/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentWithImagesInFilledDatabaseTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentWithImagesInFilledDatabaseTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Impexp\Tests\Functional\Import;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Impexp\Import;
@@ -32,9 +33,7 @@ final class PagesAndTtContentWithImagesInFilledDatabaseTest extends AbstractImpo
         'typo3/sysext/impexp/Tests/Functional/Fixtures/Folders/fileadmin/user_upload/typo3_image2.jpg' => 'fileadmin/user_upload/typo3_image2.jpg',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentWithDifferentImageToExistingData(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/pages.csv');
@@ -60,9 +59,7 @@ final class PagesAndTtContentWithImagesInFilledDatabaseTest extends AbstractImpo
         self::assertFileEquals(__DIR__ . '/../Fixtures/FileAssertions/typo3_image2_01.jpg', Environment::getPublicPath() . '/fileadmin/user_upload/typo3_image2_01.jpg');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function updatePagesAndRelatedTtContentWithDifferentImageToExistingData(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/pages.csv');
@@ -97,9 +94,7 @@ final class PagesAndTtContentWithImagesInFilledDatabaseTest extends AbstractImpo
         self::assertFileEquals(__DIR__ . '/../Fixtures/FileAssertions/typo3_image2_01.jpg', Environment::getPublicPath() . '/fileadmin/user_upload/typo3_image2_01.jpg');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function updatePagesAndRelatedTtContentWithDifferentImageToExistingDataAndPagesAsNew(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/pages.csv');
@@ -138,9 +133,7 @@ final class PagesAndTtContentWithImagesInFilledDatabaseTest extends AbstractImpo
         self::assertFileEquals(__DIR__ . '/../Fixtures/FileAssertions/typo3_image2_01.jpg', Environment::getPublicPath() . '/fileadmin/user_upload/typo3_image2_01.jpg');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function updatePagesAndRelatedTtContentKeepsRelationsBetweenImportedPagesAndRecords(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/pages.csv');
@@ -174,9 +167,7 @@ final class PagesAndTtContentWithImagesInFilledDatabaseTest extends AbstractImpo
         self::assertFileEquals(__DIR__ . '/../Fixtures/Folders/fileadmin/user_upload/typo3_image2.jpg', Environment::getPublicPath() . '/fileadmin/user_upload/typo3_image2.jpg');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentWithSameImageToExistingData(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/pages.csv');
@@ -220,9 +211,8 @@ final class PagesAndTtContentWithImagesInFilledDatabaseTest extends AbstractImpo
      * Note the internal handler mixes up insert orders resulting in former tt_content:1
      * ending up as tt_content:3 and 2/3 ending up as 2/1 uid-wise ... making this issue
      * even harder to grasp.
-     *
-     * @test
      */
+    #[Test]
     public function importPagesAndTtContentWithRemappingNewSysFileEntries(): void
     {
         // Have a single sys_file entry with uid 1
@@ -247,9 +237,7 @@ final class PagesAndTtContentWithImagesInFilledDatabaseTest extends AbstractImpo
         $this->assertCSVDataSet(__DIR__ . '/../Fixtures/DatabaseAssertions/importPagesAndTtContentWithRemappingNewSysFileEntries.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importImageIntoSystemAndMatchingThePathOfTheSecondStorage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/sys_file_single_image.csv');
@@ -265,9 +253,7 @@ final class PagesAndTtContentWithImagesInFilledDatabaseTest extends AbstractImpo
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentKeepsRelationBetweenImportedFlexFormsAndPages(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/pages.csv');
@@ -313,9 +299,7 @@ final class PagesAndTtContentWithImagesInFilledDatabaseTest extends AbstractImpo
         self::assertEquals(1, $originalUidIsNotActualUid);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentKeepsRelationBetweenImportedFlexFormSoftReferenceAndRelatedRecord(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/sys_file_single_image.csv');
@@ -340,9 +324,7 @@ final class PagesAndTtContentWithImagesInFilledDatabaseTest extends AbstractImpo
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentCanKeepOriginalFlexFormSoftReference(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/sys_file_single_image.csv');
@@ -368,9 +350,7 @@ final class PagesAndTtContentWithImagesInFilledDatabaseTest extends AbstractImpo
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentCanEditFlexFormSoftReference(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/DatabaseImports/sys_file_single_image.csv');
diff --git a/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentWithRteImagesAndFileLinkTest.php b/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentWithRteImagesAndFileLinkTest.php
index a42071a8f70f..61d2103fffab 100644
--- a/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentWithRteImagesAndFileLinkTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Import/PagesAndTtContentWithRteImagesAndFileLinkTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Impexp\Tests\Functional\Import;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Impexp\Import;
@@ -28,9 +29,7 @@ final class PagesAndTtContentWithRteImagesAndFileLinkTest extends AbstractImport
         '/fileadmin/_processed_',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importPagesAndRelatedTtContentWithRteImagesAndFileLink(): void
     {
         $subject = GeneralUtility::makeInstance(Import::class);
diff --git a/typo3/sysext/impexp/Tests/Functional/ImportExportTest.php b/typo3/sysext/impexp/Tests/Functional/ImportExportTest.php
index b8a6719e0375..c2e342835d8f 100644
--- a/typo3/sysext/impexp/Tests/Functional/ImportExportTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/ImportExportTest.php
@@ -15,6 +15,7 @@
 
 namespace TYPO3\CMS\Impexp\Tests\Functional;
 
+use PHPUnit\Framework\Attributes\Test;
 use PHPUnit\Framework\MockObject\MockObject;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Impexp\Export;
@@ -40,9 +41,7 @@ final class ImportExportTest extends AbstractImportExportTestCase
         $this->exportMock = $this->getAccessibleMock(Export::class, ['setMetaData']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importExportPingPongSucceeds(): void
     {
         $recordTypesIncludeFields = include __DIR__ . '/Fixtures/IrreRecordsIncludeFields.php';
diff --git a/typo3/sysext/impexp/Tests/Functional/ImportTest.php b/typo3/sysext/impexp/Tests/Functional/ImportTest.php
index c5b1bfad5df3..e139423b43ec 100644
--- a/typo3/sysext/impexp/Tests/Functional/ImportTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/ImportTest.php
@@ -15,6 +15,8 @@
 
 namespace TYPO3\CMS\Impexp\Tests\Functional;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Impexp\Exception\LoadingFileFailedException;
 use TYPO3\CMS\Impexp\Import;
@@ -35,10 +37,8 @@ final class ImportTest extends AbstractImportExportTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider loadingFileFromWithinTypo3BaseFolderSucceedsProvider
-     */
+    #[DataProvider('loadingFileFromWithinTypo3BaseFolderSucceedsProvider')]
+    #[Test]
     public function loadingFileFromWithinTypo3BaseFolderSucceeds(string $filePath): void
     {
         $filePath = str_replace('%EnvironmentPublicPath%', Environment::getPublicPath(), $filePath);
@@ -60,10 +60,8 @@ final class ImportTest extends AbstractImportExportTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider loadingFileFailsProvider
-     */
+    #[DataProvider('loadingFileFailsProvider')]
+    #[Test]
     public function loadingFileFails(string $filePath): void
     {
         $this->expectException(LoadingFileFailedException::class);
@@ -74,9 +72,7 @@ final class ImportTest extends AbstractImportExportTestCase
         self::assertEmpty($importMock->_get('dat'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderPreviewForImportOfPageAndRecords(): void
     {
         $renderPreviewImport = include __DIR__ . '/Fixtures/ArrayAssertions/RenderPreviewImportPageAndRecords.php';
@@ -95,9 +91,7 @@ final class ImportTest extends AbstractImportExportTestCase
         self::assertEquals($renderPreviewImport, $previewData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderPreviewForImportOfPageAndRecordsByUpdate(): void
     {
         $renderPreviewImport = include __DIR__ . '/Fixtures/ArrayAssertions/RenderPreviewImportPageAndRecordsByUpdate.php';
@@ -118,9 +112,7 @@ final class ImportTest extends AbstractImportExportTestCase
         self::assertEquals($renderPreviewImport, $previewData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderPreviewForImportOfPageAndRecordsWithDiffView(): void
     {
         $renderPreviewImport = include __DIR__ . '/Fixtures/ArrayAssertions/RenderPreviewImportPageAndRecordsWithDiff.php';
@@ -142,9 +134,7 @@ final class ImportTest extends AbstractImportExportTestCase
         self::assertEquals($renderPreviewImport, $previewData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderPreviewForImportOfPageAndRecordsByUpdateWithDiffView(): void
     {
         $renderPreviewImport = include __DIR__ . '/Fixtures/ArrayAssertions/RenderPreviewImportPageAndRecordsByUpdateWithDiff.php';
@@ -167,9 +157,7 @@ final class ImportTest extends AbstractImportExportTestCase
         self::assertEquals($renderPreviewImport, $previewData);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function renderPreviewForImportOfPageAndRecordsWithSoftRefs(): void
     {
         $renderPreviewImport = include __DIR__ . '/Fixtures/ArrayAssertions/RenderPreviewImportPageAndRecordsWithSoftRefs.php';
@@ -221,10 +209,9 @@ final class ImportTest extends AbstractImportExportTestCase
 
     /**
      * Temporary test until there is a complex functional test which tests addFiles() implicitly.
-     *
-     * @test
-     * @dataProvider addFilesSucceedsDataProvider
      */
+    #[DataProvider('addFilesSucceedsDataProvider')]
+    #[Test]
     public function addFilesSucceeds(array $dat, array $relations, string $tokenID, array $expected): void
     {
         $importMock = $this->getAccessibleMock(
@@ -241,9 +228,7 @@ final class ImportTest extends AbstractImportExportTestCase
         self::assertEquals($expected, $lines);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function loadXmlSucceeds(): void
     {
         $importMock = $this->getAccessibleMock(Import::class, null);
@@ -255,9 +240,7 @@ final class ImportTest extends AbstractImportExportTestCase
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function loadT3dSucceeds(): void
     {
         $importMock = $this->getAccessibleMock(Import::class, null);
@@ -269,9 +252,7 @@ final class ImportTest extends AbstractImportExportTestCase
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function loadT3dFails(): void
     {
         $this->expectException(LoadingFileFailedException::class);
@@ -284,9 +265,7 @@ final class ImportTest extends AbstractImportExportTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function loadT3dCompressedSucceeds(): void
     {
         if (!function_exists('gzuncompress')) {
@@ -302,9 +281,7 @@ final class ImportTest extends AbstractImportExportTestCase
         self::assertTrue(true);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importDataCleansUpTemporaryFolder(): void
     {
         $fileDirectory = Environment::getVarPath() . '/transient';
diff --git a/typo3/sysext/impexp/Tests/Functional/Utility/ImportExportUtilityTest.php b/typo3/sysext/impexp/Tests/Functional/Utility/ImportExportUtilityTest.php
index aea78b895365..06233a55db0b 100644
--- a/typo3/sysext/impexp/Tests/Functional/Utility/ImportExportUtilityTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Utility/ImportExportUtilityTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Impexp\Tests\Functional\Utility;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\EventDispatcher\NoopEventDispatcher;
 use TYPO3\CMS\Impexp\Tests\Functional\AbstractImportExportTestCase;
 use TYPO3\CMS\Impexp\Utility\ImportExportUtility;
@@ -38,10 +40,8 @@ final class ImportExportUtilityTest extends AbstractImportExportTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider importFailsDataProvider
-     */
+    #[DataProvider('importFailsDataProvider')]
+    #[Test]
     public function importFails(string $filePath): void
     {
         $this->expectException(\ErrorException::class);
@@ -55,9 +55,7 @@ final class ImportExportUtilityTest extends AbstractImportExportTestCase
         $importUtilityMock->importT3DFile($filePath, 0);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function importSucceeds(): void
     {
         $filePath = 'EXT:impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent.xml';
diff --git a/typo3/sysext/indexed_search/Tests/Functional/IndexSearchRepositoryTest.php b/typo3/sysext/indexed_search/Tests/Functional/IndexSearchRepositoryTest.php
index 7466a89aa59e..28510927d7db 100644
--- a/typo3/sysext/indexed_search/Tests/Functional/IndexSearchRepositoryTest.php
+++ b/typo3/sysext/indexed_search/Tests/Functional/IndexSearchRepositoryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\IndexedSearch\Tests\Functional;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\UserAspect;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -71,9 +72,7 @@ final class IndexSearchRepositoryTest extends FunctionalTestCase
         GeneralUtility::makeInstance(Context::class)->setAspect('frontend.user', new UserAspect(null, [0, -1]));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function doSearchReturnsLoremIpsumResults(): void
     {
         $searchRepository = $this->getSearchRepository();
@@ -83,9 +82,7 @@ final class IndexSearchRepositoryTest extends FunctionalTestCase
         self::assertStringContainsStringIgnoringCase('lorem', $searchResults['resultRows'][0]['item_description']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function doSearchProperlyQuotesSearchWord(): void
     {
         $searchRepository = $this->getSearchRepository();
@@ -93,9 +90,7 @@ final class IndexSearchRepositoryTest extends FunctionalTestCase
         self::assertIsNotArray($searchResults['resultRows'] ?? false);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function doSearchReturnsLurimIpasomResultsWithMetaphoneSearch(): void
     {
         $searchRepository = $this->getSearchRepository(10);
diff --git a/typo3/sysext/indexed_search/Tests/Functional/IndexerTest.php b/typo3/sysext/indexed_search/Tests/Functional/IndexerTest.php
index ee5cfc241f5b..04752a0d78af 100644
--- a/typo3/sysext/indexed_search/Tests/Functional/IndexerTest.php
+++ b/typo3/sysext/indexed_search/Tests/Functional/IndexerTest.php
@@ -18,6 +18,7 @@ declare(strict_types=1);
 namespace TYPO3\CMS\IndexedSearch\Tests\Functional;
 
 use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\IndexedSearch\Indexer;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -27,9 +28,7 @@ final class IndexerTest extends FunctionalTestCase
         'indexed_search',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function indexerIndexesLoremIpsumContent(): void
     {
         $indexer = new Indexer();
@@ -65,9 +64,7 @@ final class IndexerTest extends FunctionalTestCase
         self::assertCSVDataSet(__DIR__ . '/Fixtures/Indexer/index_dataset.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function indexerDoesNotFailForWordsWithPhashCollision(): void
     {
         $indexer = new Indexer();
@@ -107,9 +104,7 @@ final class IndexerTest extends FunctionalTestCase
         self::assertCSVDataSet(__DIR__ . '/Fixtures/Indexer/phash_collision.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function indexerBuildsCorrectWordIndexWhenIndexingWordsTwice(): void
     {
         $indexerConfig = [
diff --git a/typo3/sysext/indexed_search/Tests/Functional/Utility/LikeWildcardTest.php b/typo3/sysext/indexed_search/Tests/Functional/Utility/LikeWildcardTest.php
index 3cc3d213db32..27fe0fb70399 100644
--- a/typo3/sysext/indexed_search/Tests/Functional/Utility/LikeWildcardTest.php
+++ b/typo3/sysext/indexed_search/Tests/Functional/Utility/LikeWildcardTest.php
@@ -19,6 +19,8 @@ namespace TYPO3\CMS\IndexedSearch\Tests\Functional\Utility;
 
 use Doctrine\DBAL\Platforms\MySQLPlatform;
 use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\IndexedSearch\Utility\LikeWildcard;
@@ -26,10 +28,8 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class LikeWildcardTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     * @dataProvider getLikeQueryPartDataProvider
-     */
+    #[DataProvider('getLikeQueryPartDataProvider')]
+    #[Test]
     public function getLikeQueryPart(string $tableName, string $fieldName, string $likeValue, LikeWildcard $subject, string $expected): void
     {
         $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($tableName);
diff --git a/typo3/sysext/install/Tests/Functional/Service/EnableFileServiceTest.php b/typo3/sysext/install/Tests/Functional/Service/EnableFileServiceTest.php
index 7bf14e625d3f..cea6cfdd2e72 100644
--- a/typo3/sysext/install/Tests/Functional/Service/EnableFileServiceTest.php
+++ b/typo3/sysext/install/Tests/Functional/Service/EnableFileServiceTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Install\Tests\Functional\Service;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Install\Service\EnableFileService;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -40,9 +41,7 @@ final class EnableFileServiceTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFirstInstallFilePathsFindsValidFiles(): void
     {
         $publicPath = Environment::getPublicPath();
@@ -61,9 +60,7 @@ final class EnableFileServiceTest extends FunctionalTestCase
         self::assertEquals([], array_diff($expected, $subject->_call('getFirstInstallFilePaths')));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getFirstInstallFilePathsReturnsEmptyArrayWithOnlyInvalidFiles(): void
     {
         $publicPath = Environment::getPublicPath();
@@ -77,9 +74,7 @@ final class EnableFileServiceTest extends FunctionalTestCase
         self::assertEquals([], array_diff([], $subject->_call('getFirstInstallFilePaths')));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeFirstInstallFileRemovesValidFiles(): void
     {
         $publicPath = Environment::getPublicPath();
@@ -96,9 +91,7 @@ final class EnableFileServiceTest extends FunctionalTestCase
         self::assertEquals(array_values($expected), array_values(scandir($publicPath)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeFirstInstallFileRemovesNoFileIfThereAreNoValidFiles(): void
     {
         $publicPath = Environment::getPublicPath();
@@ -114,9 +107,7 @@ final class EnableFileServiceTest extends FunctionalTestCase
         self::assertEquals(array_values($expected), array_values(scandir($publicPath)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeInstallToolEnableFileRemovesAllAvailableFiles(): void
     {
         $defaultLocation = Environment::getVarPath() . '/transient/' . EnableFileService::INSTALL_TOOL_ENABLE_FILE_PATH;
diff --git a/typo3/sysext/install/Tests/Functional/Service/SilentConfigurationUpgradeServiceTest.php b/typo3/sysext/install/Tests/Functional/Service/SilentConfigurationUpgradeServiceTest.php
index c12080802858..2001496dcd61 100644
--- a/typo3/sysext/install/Tests/Functional/Service/SilentConfigurationUpgradeServiceTest.php
+++ b/typo3/sysext/install/Tests/Functional/Service/SilentConfigurationUpgradeServiceTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Install\Tests\Functional\Service;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend;
 use TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend;
 use TYPO3\CMS\Core\Cache\Frontend\VariableFrontend;
@@ -48,18 +50,14 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function defaultCreatedConfigurationIsClean(): void
     {
         $subject = $this->get(SilentConfigurationUpgradeService::class);
         $subject->execute();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeObsoleteLocalConfigurationSettingsIfThereAreOldSettings(): void
     {
         $testConfig = [
@@ -83,9 +81,7 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function removeObsoleteLocalConfigurationSettingsKeepsUnaffectedSettings(): void
     {
         $testConfig = [
@@ -108,9 +104,7 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function doNotGenerateEncryptionKeyIfExists(): void
     {
         $testConfig = [
@@ -133,9 +127,7 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function generateEncryptionKeyIfNotExists(): void
     {
         $configurationManager = $this->get(ConfigurationManager::class);
@@ -248,10 +240,8 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider transferHttpSettingsIfSetDataProvider
-     */
+    #[DataProvider('transferHttpSettingsIfSetDataProvider')]
+    #[Test]
     public function transferHttpSettingsIfSet(array $currentLocalConfiguration, array $newSettings, bool $localConfigurationNeedsUpdate): void
     {
         $testConfig = [
@@ -274,9 +264,7 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function disableImageMagickDetailSettingsIfImageMagickIsDisabled(): void
     {
         $testConfig = [
@@ -301,9 +289,7 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function doNotDisableImageMagickDetailSettingsIfImageMagickIsEnabled(): void
     {
         $testConfig = [
@@ -328,9 +314,7 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function setImageMagickDetailSettings(): void
     {
         $testConfig = [
@@ -355,9 +339,7 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function doNotSetImageMagickDetailSettings(): void
     {
         $testConfig = [
@@ -411,10 +393,8 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider migratesGraphicsProcessorEffectsDataProvider
-     */
+    #[DataProvider('migratesGraphicsProcessorEffectsDataProvider')]
+    #[Test]
     public function migratesGraphicsProcessorEffects(string|int $currentValue, bool $expectedMigratedValue): void
     {
         $testConfig = [
@@ -439,9 +419,7 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function migrateExistingLangDebug(): void
     {
         $testConfig = [
@@ -466,9 +444,7 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function migrateCacheHashOptions(): void
     {
         $testConfig = [
@@ -502,9 +478,7 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function migrateVersionNumberInFilename(): void
     {
         $testConfig = [
@@ -527,9 +501,7 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function versionNumberInFilenameSetToTrueStaysUntouched(): void
     {
         $testConfig = [
@@ -552,9 +524,7 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function migrateSaltedPasswordsSettingsRemovesExtensionsConfigAndSetsNothingElseIfArgon2iIsAvailable(): void
     {
         $testConfig = [
@@ -580,9 +550,7 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function migrateSaltedPasswordsSetsSpecificHashMethodIfArgon2idAndArgon2iIsNotAvailable(): void
     {
         $argon2idBeMock = $this->createMock(Argon2idPasswordHash::class);
@@ -623,9 +591,7 @@ final class SilentConfigurationUpgradeServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function migrateCachingFrameworkCachesMigratesData(): void
     {
         $testConfig = [
diff --git a/typo3/sysext/install/Tests/Functional/Service/Typo3tempFileServiceTest.php b/typo3/sysext/install/Tests/Functional/Service/Typo3tempFileServiceTest.php
index 3315ce288f2d..81ad389bb17c 100644
--- a/typo3/sysext/install/Tests/Functional/Service/Typo3tempFileServiceTest.php
+++ b/typo3/sysext/install/Tests/Functional/Service/Typo3tempFileServiceTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Install\Tests\Functional\Service;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Resource\ProcessedFileRepository;
 use TYPO3\CMS\Core\Resource\StorageRepository;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -44,9 +45,7 @@ final class Typo3tempFileServiceTest extends FunctionalTestCase
         unset($this->directoryName, $this->directoryPath);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function clearAssetsFolderDetectsNonExistingFolder(): void
     {
         $this->expectException(\RuntimeException::class);
@@ -58,9 +57,7 @@ final class Typo3tempFileServiceTest extends FunctionalTestCase
         $subject->clearAssetsFolder('/typo3temp/assets/' . $this->directoryName);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function clearAssetsFolderClearsFolder(): void
     {
         GeneralUtility::mkdir_deep($this->directoryPath . '/a/b');
diff --git a/typo3/sysext/install/Tests/Functional/Service/WebServerConfigurationFileServiceTest.php b/typo3/sysext/install/Tests/Functional/Service/WebServerConfigurationFileServiceTest.php
index d8d463df6a53..6f0c3c7a5c6a 100644
--- a/typo3/sysext/install/Tests/Functional/Service/WebServerConfigurationFileServiceTest.php
+++ b/typo3/sysext/install/Tests/Functional/Service/WebServerConfigurationFileServiceTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Install\Tests\Functional\Service;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Install\Service\WebServerConfigurationFileService;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -26,15 +28,14 @@ final class WebServerConfigurationFileServiceTest extends FunctionalTestCase
     protected bool $initializeDatabase = false;
 
     /**
-     * @dataProvider webServerConfigurationIsChangedDataProvider
-     * @test
-     *
      * @param string $webServer The webserver to use
      * @param string $configurationFile The file to update
      * @param bool $shouldBeChanged Whether the file should be updated
      * @param array $addedParts String parts, the file should contain after the update
      * @param array $removedParts String parts, the file should not longer contain after the update
      */
+    #[DataProvider('webServerConfigurationIsChangedDataProvider')]
+    #[Test]
     public function addWebServerSpecificBackendRoutingRewriteRulesTest(
         string $webServer,
         string $configurationFile,
diff --git a/typo3/sysext/install/Tests/Functional/Updates/BackendGroupsExplicitAllowDenyMigrationTest.php b/typo3/sysext/install/Tests/Functional/Updates/BackendGroupsExplicitAllowDenyMigrationTest.php
index 9203aa8b963e..65606bc8fa87 100644
--- a/typo3/sysext/install/Tests/Functional/Updates/BackendGroupsExplicitAllowDenyMigrationTest.php
+++ b/typo3/sysext/install/Tests/Functional/Updates/BackendGroupsExplicitAllowDenyMigrationTest.php
@@ -17,15 +17,14 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Install\Tests\Functional\Updates;
 
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\Console\Output\OutputInterface;
 use TYPO3\CMS\Install\Updates\BackendGroupsExplicitAllowDenyMigration;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class BackendGroupsExplicitAllowDenyMigrationTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function backendGroupsRowsAreUpdated(): void
     {
         $outputMock = $this->getMockBuilder(OutputInterface::class)->getMock();
diff --git a/typo3/sysext/install/Tests/Functional/Updates/BackendModulePermissionMigrationTest.php b/typo3/sysext/install/Tests/Functional/Updates/BackendModulePermissionMigrationTest.php
index 556c53f647f4..6a47c14f4dc9 100644
--- a/typo3/sysext/install/Tests/Functional/Updates/BackendModulePermissionMigrationTest.php
+++ b/typo3/sysext/install/Tests/Functional/Updates/BackendModulePermissionMigrationTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Install\Tests\Functional\Updates;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Install\Updates\BackendModulePermissionMigration;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -30,9 +31,7 @@ final class BackendModulePermissionMigrationTest extends FunctionalTestCase
      */
     protected array $coreExtensionsToLoad = ['workspaces'];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function recordsUpdated(): void
     {
         $subject = new BackendModulePermissionMigration();
diff --git a/typo3/sysext/install/Tests/Functional/Updates/FeLoginModeExtractionUpdateTest.php b/typo3/sysext/install/Tests/Functional/Updates/FeLoginModeExtractionUpdateTest.php
index 91a273da4841..f68bb98cbdb3 100644
--- a/typo3/sysext/install/Tests/Functional/Updates/FeLoginModeExtractionUpdateTest.php
+++ b/typo3/sysext/install/Tests/Functional/Updates/FeLoginModeExtractionUpdateTest.php
@@ -19,6 +19,8 @@ namespace TYPO3\CMS\Install\Tests\Functional\Updates;
 
 use Doctrine\DBAL\Schema\Column;
 use Doctrine\DBAL\Types\IntegerType;
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Schema\TableDiff;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -27,19 +29,15 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class FeLoginModeExtractionUpdateTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function columnDoesNotExistTest(): void
     {
         // "updateNecessary" will return FALSE since the "fe_login_mode" column is no longer defined by TYPO3
         self::assertFalse((new FeLoginModeExtractionUpdate())->updateNecessary());
     }
 
-    /**
-     * @test
-     * @dataProvider functionalityUsedTestDataProvider
-     */
+    #[DataProvider('functionalityUsedTestDataProvider')]
+    #[Test]
     public function functionalityUsedTest(string $csvDataSet, bool $updateNecessary): void
     {
         $schemaManager = GeneralUtility::makeInstance(ConnectionPool::class)
diff --git a/typo3/sysext/install/Tests/Functional/Updates/MigrateSiteSettingsConfigUpdateTest.php b/typo3/sysext/install/Tests/Functional/Updates/MigrateSiteSettingsConfigUpdateTest.php
index 21c4ef4d6b85..76e4ddba4b28 100644
--- a/typo3/sysext/install/Tests/Functional/Updates/MigrateSiteSettingsConfigUpdateTest.php
+++ b/typo3/sysext/install/Tests/Functional/Updates/MigrateSiteSettingsConfigUpdateTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Install\Tests\Functional\Updates;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Configuration\SiteConfiguration;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -25,9 +26,7 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class MigrateSiteSettingsConfigUpdateTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function upgradeSettingsUpdateWithSettings(): void
     {
         $siteconfigurationIdentifier = 'settings';
@@ -62,9 +61,7 @@ final class MigrateSiteSettingsConfigUpdateTest extends FunctionalTestCase
         self::assertFileExists($this->getSettingsFilePath($siteconfigurationIdentifier));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function upgradeSettingsUpdateWithoutSettings(): void
     {
         $siteconfigurationIdentifier = 'withoutSettings';
diff --git a/typo3/sysext/install/Tests/Functional/Updates/RowUpdater/SysRedirectRootPageMoveMigrationTest.php b/typo3/sysext/install/Tests/Functional/Updates/RowUpdater/SysRedirectRootPageMoveMigrationTest.php
index 127e11a3bb45..85c650413f8b 100644
--- a/typo3/sysext/install/Tests/Functional/Updates/RowUpdater/SysRedirectRootPageMoveMigrationTest.php
+++ b/typo3/sysext/install/Tests/Functional/Updates/RowUpdater/SysRedirectRootPageMoveMigrationTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Install\Tests\Functional\Updates\RowUpdater;
 
+use PHPUnit\Framework\Attributes\Test;
 use PHPUnit\Framework\MockObject\MockObject;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -56,9 +57,7 @@ final class SysRedirectRootPageMoveMigrationTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function siteRootPageChildrenRecordsAreMovedToSiteRootPage(): void
     {
         // Data set inspired by workspaces IRRE/CSV/Modify/DataSet/copyPage.csv
@@ -69,9 +68,7 @@ final class SysRedirectRootPageMoveMigrationTest extends FunctionalTestCase
         $this->assertCSVDataSet(__DIR__ . '/Fixtures/SysRedirectsRootPageMoveMigrationSiteRootChildrenResult.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function siteRootPageChildrenRecordsWithDisabledRedirectsAreMovedToSiteRootPage(): void
     {
         // Data set inspired by workspaces IRRE/CSV/Modify/DataSet/copyPage.csv
@@ -82,9 +79,7 @@ final class SysRedirectRootPageMoveMigrationTest extends FunctionalTestCase
         $this->assertCSVDataSet(__DIR__ . '/Fixtures/SysRedirectsRootPageMoveMigrationSiteRootChildrenWithDisabledRedirectResult.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function siteRootPageChildrenRecordsWithDeletedRedirectsAreMovedToSiteRootPage(): void
     {
         // Data set inspired by workspaces IRRE/CSV/Modify/DataSet/copyPage.csv
@@ -95,9 +90,7 @@ final class SysRedirectRootPageMoveMigrationTest extends FunctionalTestCase
         $this->assertCSVDataSet(__DIR__ . '/Fixtures/SysRedirectsRootPageMoveMigrationSiteRootChildrenWithDeletedRedirectResult.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function subPageRecordsAreMovedToPidZeroIfNoSiteConfig(): void
     {
         // Data set inspired by workspaces IRRE/CSV/Modify/DataSet/copyPage.csv
diff --git a/typo3/sysext/install/Tests/Functional/Updates/RowUpdater/WorkspaceNewPlaceholderRemovalTest.php b/typo3/sysext/install/Tests/Functional/Updates/RowUpdater/WorkspaceNewPlaceholderRemovalTest.php
index a56c821dd937..b10695e1c0e5 100644
--- a/typo3/sysext/install/Tests/Functional/Updates/RowUpdater/WorkspaceNewPlaceholderRemovalTest.php
+++ b/typo3/sysext/install/Tests/Functional/Updates/RowUpdater/WorkspaceNewPlaceholderRemovalTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Install\Tests\Functional\Updates\RowUpdater;
 
+use PHPUnit\Framework\Attributes\Test;
 use PHPUnit\Framework\MockObject\MockObject;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Install\Updates\DatabaseRowsUpdateWizard;
@@ -47,9 +48,7 @@ final class WorkspaceNewPlaceholderRemovalTest extends FunctionalTestCase
         $this->subject->_set('rowUpdater', [WorkspaceNewPlaceholderRemovalMigration::class]);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function workspaceRecordsUpdatedWithIrreCsv(): void
     {
         // Data set inspired by workspaces IRRE/CSV/Modify/DataSet/copyPage.csv
@@ -58,9 +57,7 @@ final class WorkspaceNewPlaceholderRemovalTest extends FunctionalTestCase
         $this->assertCSVDataSet(__DIR__ . '/Fixtures/WorkspaceNewPlaceholderRemovalIrreCsvResult.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function workspaceRecordsUpdatedWithIrreForeignField(): void
     {
         // Data set inspired by workspaces IRRE/ForeignField/Modify/DataSet/copyPage.csv
@@ -69,9 +66,7 @@ final class WorkspaceNewPlaceholderRemovalTest extends FunctionalTestCase
         $this->assertCSVDataSet(__DIR__ . '/Fixtures/WorkspaceNewPlaceholderRemovalIrreForeignFieldResult.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function workspaceRecordsUpdatedWithManyToMany(): void
     {
         // Data set inspired by workspaces ManyToMany/Modify/DataSet/copyPage.csv
diff --git a/typo3/sysext/install/Tests/Functional/Updates/ShortcutRecordsMigrationTest.php b/typo3/sysext/install/Tests/Functional/Updates/ShortcutRecordsMigrationTest.php
index 88b3069a780d..cdd3f1f5cac0 100644
--- a/typo3/sysext/install/Tests/Functional/Updates/ShortcutRecordsMigrationTest.php
+++ b/typo3/sysext/install/Tests/Functional/Updates/ShortcutRecordsMigrationTest.php
@@ -20,6 +20,7 @@ namespace TYPO3\CMS\Install\Tests\Functional\Updates;
 use Doctrine\DBAL\Schema\Column;
 use Doctrine\DBAL\Types\StringType;
 use Doctrine\DBAL\Types\TextType;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Schema\TableDiff;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -38,9 +39,7 @@ final class ShortcutRecordsMigrationTest extends FunctionalTestCase
     protected string $baseDataSet = __DIR__ . '/Fixtures/ShortcutsBase.csv';
     protected string $resultDataSet = __DIR__ . '/Fixtures/ShortcutsMigratedToRoutes.csv';
 
-    /**
-     * @test
-     */
+    #[Test]
     public function shortcutRecordsUpdated(): void
     {
         $subject = new ShortcutRecordsMigration();
diff --git a/typo3/sysext/install/Tests/Functional/Updates/SysFileCollectionIdentifierMigrationTest.php b/typo3/sysext/install/Tests/Functional/Updates/SysFileCollectionIdentifierMigrationTest.php
index 36dabb85d589..04ffe563c30d 100644
--- a/typo3/sysext/install/Tests/Functional/Updates/SysFileCollectionIdentifierMigrationTest.php
+++ b/typo3/sysext/install/Tests/Functional/Updates/SysFileCollectionIdentifierMigrationTest.php
@@ -20,6 +20,7 @@ namespace TYPO3\CMS\Install\Tests\Functional\Updates;
 use Doctrine\DBAL\Schema\Column;
 use Doctrine\DBAL\Types\IntegerType;
 use Doctrine\DBAL\Types\StringType;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Schema\TableDiff;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -33,9 +34,7 @@ final class SysFileCollectionIdentifierMigrationTest extends FunctionalTestCase
     protected string $baseDataSet = __DIR__ . '/Fixtures/FileCollectionBase.csv';
     protected string $resultDataSet = __DIR__ . '/Fixtures/FileCollectionMigrated.csv';
 
-    /**
-     * @test
-     */
+    #[Test]
     public function sysFileCollectionRecordsUpdated(): void
     {
         $subject = new SysFileCollectionIdentifierMigration();
diff --git a/typo3/sysext/install/Tests/Functional/Updates/SysFileMountIdentifierMigrationTest.php b/typo3/sysext/install/Tests/Functional/Updates/SysFileMountIdentifierMigrationTest.php
index 5e9e2ccab8db..f7e42425fae0 100644
--- a/typo3/sysext/install/Tests/Functional/Updates/SysFileMountIdentifierMigrationTest.php
+++ b/typo3/sysext/install/Tests/Functional/Updates/SysFileMountIdentifierMigrationTest.php
@@ -20,6 +20,7 @@ namespace TYPO3\CMS\Install\Tests\Functional\Updates;
 use Doctrine\DBAL\Schema\Column;
 use Doctrine\DBAL\Types\IntegerType;
 use Doctrine\DBAL\Types\StringType;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Schema\TableDiff;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -33,9 +34,7 @@ final class SysFileMountIdentifierMigrationTest extends FunctionalTestCase
     protected string $baseDataSet = __DIR__ . '/Fixtures/FilemountsBase.csv';
     protected string $resultDataSet = __DIR__ . '/Fixtures/FilemountsMigrated.csv';
 
-    /**
-     * @test
-     */
+    #[Test]
     public function sysFileMountRecordsUpdated(): void
     {
         $subject = new SysFileMountIdentifierMigration();
diff --git a/typo3/sysext/install/Tests/Functional/Updates/SysLogSerializationUpdateTest.php b/typo3/sysext/install/Tests/Functional/Updates/SysLogSerializationUpdateTest.php
index 64ea0a70166b..a55ecc7d0be2 100644
--- a/typo3/sysext/install/Tests/Functional/Updates/SysLogSerializationUpdateTest.php
+++ b/typo3/sysext/install/Tests/Functional/Updates/SysLogSerializationUpdateTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Install\Tests\Functional\Updates;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Install\Updates\SysLogSerializationUpdate;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -25,9 +26,7 @@ final class SysLogSerializationUpdateTest extends FunctionalTestCase
     protected string $baseDataSet = __DIR__ . '/Fixtures/SysLogSerializationBase.csv';
     protected string $resultDataSet = __DIR__ . '/Fixtures/SysLogSerializationFinished.csv';
 
-    /**
-     * @test
-     */
+    #[Test]
     public function sysLogEntriesAreUpdated(): void
     {
         $subject = new SysLogSerializationUpdate();
diff --git a/typo3/sysext/install/Tests/Functional/UpgradeAnalysis/DocumentationFileTest.php b/typo3/sysext/install/Tests/Functional/UpgradeAnalysis/DocumentationFileTest.php
index 022bbaa073a2..7d2ff4d2cb55 100644
--- a/typo3/sysext/install/Tests/Functional/UpgradeAnalysis/DocumentationFileTest.php
+++ b/typo3/sysext/install/Tests/Functional/UpgradeAnalysis/DocumentationFileTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Install\Tests\Functional\UpgradeAnalysis;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\VersionNumberUtility;
@@ -91,10 +93,8 @@ final class DocumentationFileTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider invalidDirProvider
-     */
+    #[DataProvider('invalidDirProvider')]
+    #[Test]
     public function findDocumentationFilesThrowsExceptionIfPathIsNotInGivenChangelogDir(string $path): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -114,10 +114,8 @@ final class DocumentationFileTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider invalidFilesProvider
-     */
+    #[DataProvider('invalidFilesProvider')]
+    #[Test]
     public function getListEntryThrowsExceptionForFilesNotBelongToChangelogDir(string $path): void
     {
         $this->expectException(\InvalidArgumentException::class);
@@ -126,9 +124,7 @@ final class DocumentationFileTest extends FunctionalTestCase
         $subject->getListEntry($path);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findDocumentationFilesReturnsArrayOfFilesForTheLastThreeMajorVersions(): void
     {
         $currentVersion = (int)explode('.', VersionNumberUtility::getNumericTypo3Version())[0];
@@ -141,9 +137,7 @@ final class DocumentationFileTest extends FunctionalTestCase
         self::assertEquals($expected, $subject->findDocumentationDirectories(Environment::getPublicPath() . '/Changelog'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findDocumentsRespectsFilesWithSameIssueNumber(): void
     {
         $currentVersion = (int)explode('.', VersionNumberUtility::getNumericTypo3Version())[0];
@@ -151,9 +145,7 @@ final class DocumentationFileTest extends FunctionalTestCase
         self::assertCount(2, $subject->findDocumentationFiles(Environment::getPublicPath() . '/Changelog/' . $currentVersion . '.0'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function extractingTagsProvidesTagsAsDesired(): void
     {
         $expected = [
diff --git a/typo3/sysext/install/Tests/Functional/ViewHelpers/Format/PhpErrorCodeViewHelperTest.php b/typo3/sysext/install/Tests/Functional/ViewHelpers/Format/PhpErrorCodeViewHelperTest.php
index 7acc1776eca1..dc949df9c8af 100644
--- a/typo3/sysext/install/Tests/Functional/ViewHelpers/Format/PhpErrorCodeViewHelperTest.php
+++ b/typo3/sysext/install/Tests/Functional/ViewHelpers/Format/PhpErrorCodeViewHelperTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Install\Tests\Functional\ViewHelpers\Format;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
 use TYPO3\CMS\Install\ViewHelpers\Format\PhpErrorCodeViewHelper;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -48,10 +50,8 @@ final class PhpErrorCodeViewHelperTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider errorCodesDataProvider
-     */
+    #[DataProvider('errorCodesDataProvider')]
+    #[Test]
     public function renderPhpCodesCorrectly(int $errorCode, string $expected): void
     {
         // Happy little hack for VH tests in install tool: ViewHelperResolver
diff --git a/typo3/sysext/linkvalidator/Tests/Functional/EventListener/CheckBrokenRteLinkEventListenerTest.php b/typo3/sysext/linkvalidator/Tests/Functional/EventListener/CheckBrokenRteLinkEventListenerTest.php
index bd34f6a4ab2c..eb28cd4b75cf 100644
--- a/typo3/sysext/linkvalidator/Tests/Functional/EventListener/CheckBrokenRteLinkEventListenerTest.php
+++ b/typo3/sysext/linkvalidator/Tests/Functional/EventListener/CheckBrokenRteLinkEventListenerTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Linkvalidator\Tests\Functional\EventListener;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Html\Event\BrokenLinkAnalysisEvent;
 use TYPO3\CMS\Linkvalidator\EventListener\CheckBrokenRteLinkEventListener;
 use TYPO3\CMS\Linkvalidator\Repository\BrokenLinkRepository;
@@ -34,10 +36,8 @@ final class CheckBrokenRteLinkEventListenerTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider checkPageLinkTestDataProvider
-     */
+    #[DataProvider('checkPageLinkTestDataProvider')]
+    #[Test]
     public function checkPageLinkTest(string $linkType, array $linkData, bool $isMarkedAsBroken): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/pages.csv');
diff --git a/typo3/sysext/linkvalidator/Tests/Functional/LinkAnalyzerTest.php b/typo3/sysext/linkvalidator/Tests/Functional/LinkAnalyzerTest.php
index 18eb12c5d9b5..9adb013e7b70 100644
--- a/typo3/sysext/linkvalidator/Tests/Functional/LinkAnalyzerTest.php
+++ b/typo3/sysext/linkvalidator/Tests/Functional/LinkAnalyzerTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Linkvalidator\Tests\Functional;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Linkvalidator\LinkAnalyzer;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -81,10 +83,8 @@ final class LinkAnalyzerTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider findAllBrokenLinksDataProvider
-     */
+    #[DataProvider('findAllBrokenLinksDataProvider')]
+    #[Test]
     public function getLinkStatisticsFindAllBrokenLinks(string $inputFile, array $pidList, string $expectedOutputFile): void
     {
         $tsConfig = [
@@ -133,10 +133,8 @@ final class LinkAnalyzerTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider findFindOnlyFileBrokenLinksDataProvider
-     */
+    #[DataProvider('findFindOnlyFileBrokenLinksDataProvider')]
+    #[Test]
     public function getLinkStatisticsFindOnlyFileBrokenLinks(string $inputFile, array $pidList, string $expectedOutputFile): void
     {
         $tsConfig = [
@@ -185,10 +183,8 @@ final class LinkAnalyzerTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider findFindOnlyPageBrokenLinksDataProvider
-     */
+    #[DataProvider('findFindOnlyPageBrokenLinksDataProvider')]
+    #[Test]
     public function getLinkStatisticsFindOnlyPageBrokenLinks(string $inputFile, array $pidList, string $expectedOutputFile): void
     {
         $tsConfig = [
@@ -237,10 +233,8 @@ final class LinkAnalyzerTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider findFindOnlyExternalBrokenLinksDataProvider
-     */
+    #[DataProvider('findFindOnlyExternalBrokenLinksDataProvider')]
+    #[Test]
     public function getLinkStatisticsFindOnlyExternalBrokenLinksInBodytext(string $inputFile, array $pidList, string $expectedOutputFile): void
     {
         $tsConfig = [
@@ -277,10 +271,8 @@ final class LinkAnalyzerTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getLinkStatisticsFindOnlyExternalBrokenLinksInBodytextWithHugeListOfPageIdsDataProvider
-     */
+    #[DataProvider('getLinkStatisticsFindOnlyExternalBrokenLinksInBodytextWithHugeListOfPageIdsDataProvider')]
+    #[Test]
     public function getLinkStatisticsFindOnlyExternalBrokenLinksInBodytextWithHugeListOfPageIds(string $inputFile, array $pidList, string $expectedOutputFile): void
     {
         $tsConfig = [
diff --git a/typo3/sysext/linkvalidator/Tests/Functional/Repository/BrokenLinkRepositoryTest.php b/typo3/sysext/linkvalidator/Tests/Functional/Repository/BrokenLinkRepositoryTest.php
index 7939ad78da25..3c2c3ad5d4c4 100644
--- a/typo3/sysext/linkvalidator/Tests/Functional/Repository/BrokenLinkRepositoryTest.php
+++ b/typo3/sysext/linkvalidator/Tests/Functional/Repository/BrokenLinkRepositoryTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Linkvalidator\Tests\Functional\Repository;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Linkvalidator\LinkAnalyzer;
 use TYPO3\CMS\Linkvalidator\Repository\BrokenLinkRepository;
@@ -147,10 +149,8 @@ final class BrokenLinkRepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getLinkCountsForPagesAndLinktypesReturnsCorrectCountForUserDataProvider
-     */
+    #[DataProvider('getLinkCountsForPagesAndLinktypesReturnsCorrectCountForUserDataProvider')]
+    #[Test]
     public function getLinkCountsForPagesAndLinktypesReturnsCorrectCountForUser(
         array $beuser,
         string $inputFile,
@@ -242,10 +242,8 @@ final class BrokenLinkRepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getAllBrokenLinksForPagesReturnsCorrectCountForUserDataProvider
-     */
+    #[DataProvider('getAllBrokenLinksForPagesReturnsCorrectCountForUserDataProvider')]
+    #[Test]
     public function getAllBrokenLinksForPagesReturnsCorrectCountForUser(
         array $beuser,
         string $inputFile,
@@ -513,10 +511,8 @@ final class BrokenLinkRepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getAllBrokenLinksForPagesReturnsCorrectValuesForUserDataProvider
-     */
+    #[DataProvider('getAllBrokenLinksForPagesReturnsCorrectValuesForUserDataProvider')]
+    #[Test]
     public function getAllBrokenLinksForPagesReturnsCorrectValuesForUser(
         array $beuser,
         string $inputFile,
@@ -643,10 +639,8 @@ final class BrokenLinkRepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getAllBrokenLinksForPagesRespectsGivenLanguagesDataProvider
-     */
+    #[DataProvider('getAllBrokenLinksForPagesRespectsGivenLanguagesDataProvider')]
+    #[Test]
     public function getAllBrokenLinksForPagesRespectsGivenLanguages(
         array $beuser,
         string $inputFile,
diff --git a/typo3/sysext/linkvalidator/Tests/Functional/Repository/PagesRepositoryTest.php b/typo3/sysext/linkvalidator/Tests/Functional/Repository/PagesRepositoryTest.php
index 6a53af1cd048..6eb754f834f9 100644
--- a/typo3/sysext/linkvalidator/Tests/Functional/Repository/PagesRepositoryTest.php
+++ b/typo3/sysext/linkvalidator/Tests/Functional/Repository/PagesRepositoryTest.php
@@ -17,14 +17,13 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Linkvalidator\Tests\Functional\Repository;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Linkvalidator\Repository\PagesRepository;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class PagesRepositoryTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function doesRootLineContainHiddenPagesReturnsCorrectResultWith(): void
     {
         $pageInfo = [
@@ -40,9 +39,7 @@ final class PagesRepositoryTest extends FunctionalTestCase
         self::assertTrue($result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function doesRootLineContainHiddenPagesReturnsCorrectResultWithout(): void
     {
         $pageInfo = [
diff --git a/typo3/sysext/lowlevel/Tests/Functional/Clean/CleanUpLocalProcessedFilesTest.php b/typo3/sysext/lowlevel/Tests/Functional/Clean/CleanUpLocalProcessedFilesTest.php
index 33bcd8fdea7d..8f4de84acf82 100644
--- a/typo3/sysext/lowlevel/Tests/Functional/Clean/CleanUpLocalProcessedFilesTest.php
+++ b/typo3/sysext/lowlevel/Tests/Functional/Clean/CleanUpLocalProcessedFilesTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Lowlevel\Tests\Functional\Clean;
 
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\Console\Helper\HelperSet;
 use Symfony\Component\Console\Helper\QuestionHelper;
 use Symfony\Component\Console\Output\OutputInterface;
@@ -90,9 +91,7 @@ final class CleanUpLocalProcessedFilesTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function databaseRecordForMissingFileIsDeleted(): void
     {
         $this->commandTester->execute(['--force' => true]);
@@ -100,9 +99,7 @@ final class CleanUpLocalProcessedFilesTest extends FunctionalTestCase
         $this->assertCSVDataSet(__DIR__ . '/../Fixtures/Modify/oneDeleted.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function fileForMissingReferenceIsDeleted(): void
     {
         $this->commandTester->execute(['--force' => true]);
@@ -114,9 +111,7 @@ final class CleanUpLocalProcessedFilesTest extends FunctionalTestCase
         self::assertFileExists(GeneralUtility::getFileAbsFileName('fileadmin/image.png'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function dryRunReallyDoesNothing(): void
     {
         $this->commandTester->execute(
@@ -134,9 +129,7 @@ final class CleanUpLocalProcessedFilesTest extends FunctionalTestCase
         self::assertFileExists(GeneralUtility::getFileAbsFileName('fileadmin/image.png'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function confirmDeleteYes(): void
     {
         $this->commandTester->setInputs(['yes']);
@@ -153,9 +146,7 @@ final class CleanUpLocalProcessedFilesTest extends FunctionalTestCase
         self::assertStringContainsString('Deleted 4 processed files', $output);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function confirmDeleteNo(): void
     {
         $this->commandTester->setInputs(['no']);
diff --git a/typo3/sysext/lowlevel/Tests/Functional/ConfigurationModuleProvider/GlobalVariableProviderTest.php b/typo3/sysext/lowlevel/Tests/Functional/ConfigurationModuleProvider/GlobalVariableProviderTest.php
index 92dca91aba8a..46ca58992536 100644
--- a/typo3/sysext/lowlevel/Tests/Functional/ConfigurationModuleProvider/GlobalVariableProviderTest.php
+++ b/typo3/sysext/lowlevel/Tests/Functional/ConfigurationModuleProvider/GlobalVariableProviderTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Lowlevel\Tests\Functional\ConfigurationModuleProvider;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Core\EventDispatcher\ListenerProvider;
@@ -26,9 +27,7 @@ use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
 final class GlobalVariableProviderTest extends FunctionalTestCase
 {
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyBlindedConfigurationOptionsEventIsTriggered(): void
     {
         $modifyBlindedConfigurationOptionsEvent = null;
diff --git a/typo3/sysext/lowlevel/Tests/Functional/Controller/DatabaseIntegrityControllerTest.php b/typo3/sysext/lowlevel/Tests/Functional/Controller/DatabaseIntegrityControllerTest.php
index f81c31132f19..183cbf26b279 100644
--- a/typo3/sysext/lowlevel/Tests/Functional/Controller/DatabaseIntegrityControllerTest.php
+++ b/typo3/sysext/lowlevel/Tests/Functional/Controller/DatabaseIntegrityControllerTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Lowlevel\Tests\Functional\Controller;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Imaging\Icon;
@@ -36,9 +38,7 @@ final class DatabaseIntegrityControllerTest extends FunctionalTestCase
         $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->create('default');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTreeListReturnsIngoingIdIfDepthIsZero(): void
     {
         $id = 1;
@@ -48,9 +48,7 @@ final class DatabaseIntegrityControllerTest extends FunctionalTestCase
         self::assertEquals($id, $treeList);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTreeListReturnsIngoingIdIfIdIsZero(): void
     {
         $id = 0;
@@ -60,9 +58,7 @@ final class DatabaseIntegrityControllerTest extends FunctionalTestCase
         self::assertEquals($id, $treeList);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTreeListReturnsPositiveIngoingIdIfIdIsNegative(): void
     {
         $id = -1;
@@ -72,9 +68,7 @@ final class DatabaseIntegrityControllerTest extends FunctionalTestCase
         self::assertEquals(1, $treeList);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTreeListReturnsEmptyStringIfIdAndDepthAreZeroAndBeginDoesNotEqualZero(): void
     {
         $id = 0;
@@ -85,9 +79,7 @@ final class DatabaseIntegrityControllerTest extends FunctionalTestCase
         self::assertSame('', $treeList);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTreeListReturnsIncomingIdIfNoSubPageRecordsOfThatIdExist(): void
     {
         $id = 1;
@@ -97,9 +89,7 @@ final class DatabaseIntegrityControllerTest extends FunctionalTestCase
         self::assertEquals($id, $treeList);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTreeListRespectsPermClauses(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/TestGetPageTreeStraightTreeSet.csv');
@@ -136,10 +126,8 @@ final class DatabaseIntegrityControllerTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider dataForGetTreeListReturnsListOfIdsWithBeginSetToZero
-     */
+    #[DataProvider('dataForGetTreeListReturnsListOfIdsWithBeginSetToZero')]
+    #[Test]
     public function getTreeListReturnsListOfIdsWithBeginSetToZero(int $id, int $depth, string $expectation): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/TestGetPageTreeStraightTreeSet.csv');
@@ -174,10 +162,8 @@ final class DatabaseIntegrityControllerTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider dataForGetTreeListReturnsListOfIdsWithBeginSetToMinusOne
-     */
+    #[DataProvider('dataForGetTreeListReturnsListOfIdsWithBeginSetToMinusOne')]
+    #[Test]
     public function getTreeListReturnsListOfIdsWithBeginSetToMinusOne(int $id, int $depth, string $expectation): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/TestGetPageTreeStraightTreeSet.csv');
@@ -186,9 +172,7 @@ final class DatabaseIntegrityControllerTest extends FunctionalTestCase
         self::assertSame($expectation, $treeList);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTreeListReturnsListOfPageIdsOfABranchedTreeWithBeginSetToZero(): void
     {
         $id = 1;
@@ -199,9 +183,7 @@ final class DatabaseIntegrityControllerTest extends FunctionalTestCase
         self::assertSame('1,2,3,4,5', $treeList);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTreeListReturnsListOfPageIdsOfABranchedTreeWithBeginSetToOne(): void
     {
         $id = 1;
@@ -213,9 +195,7 @@ final class DatabaseIntegrityControllerTest extends FunctionalTestCase
         self::assertSame('2,3,4,5', $treeList);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getTreeListReturnsListOfPageIdsOfABranchedTreeWithBeginSetToTwo(): void
     {
         $id = 1;
@@ -270,10 +250,8 @@ final class DatabaseIntegrityControllerTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider getQueryWithIdOrDateDataProvider
-     */
+    #[DataProvider('getQueryWithIdOrDateDataProvider')]
+    #[Test]
     public function getQueryWithIdOrDate(mixed $inputValue, mixed $inputValue1, string $expected, int $comparison = 64): void
     {
         $GLOBALS['TCA'] = [
@@ -338,10 +316,8 @@ final class DatabaseIntegrityControllerTest extends FunctionalTestCase
         return $dataSet;
     }
 
-    /**
-     * @test
-     * @dataProvider arbitraryDataIsEscapedDataProvider
-     */
+    #[DataProvider('arbitraryDataIsEscapedDataProvider')]
+    #[Test]
     public function arbitraryDataIsEscaped(string $injector, array $settings): void
     {
         $databasePlatform = GeneralUtility::makeInstance(ConnectionPool::class)
diff --git a/typo3/sysext/reactions/Tests/Functional/Reaction/CreateRecordReactionTest.php b/typo3/sysext/reactions/Tests/Functional/Reaction/CreateRecordReactionTest.php
index 4a0224c4a887..ce97988903f5 100644
--- a/typo3/sysext/reactions/Tests/Functional/Reaction/CreateRecordReactionTest.php
+++ b/typo3/sysext/reactions/Tests/Functional/Reaction/CreateRecordReactionTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Reactions\Tests\Functional\Reaction;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\ServerRequestInterface;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Database\ConnectionPool;
@@ -44,9 +46,7 @@ final class CreateRecordReactionTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/ReactionsRepositoryTest_reactions.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function reactWorksForAValidRequest(): void
     {
         $reactionRecord = (new ReactionRepository())->getReactionRecordByIdentifier('visual-reaction-uuid');
@@ -72,9 +72,7 @@ final class CreateRecordReactionTest extends FunctionalTestCase
         self::assertCount(1, $this->getTestPages());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function reactFailsOnInvalidTable(): void
     {
         $reactionRecord = (new ReactionRepository())->getReactionRecordByIdentifier('invalid-table');
@@ -87,9 +85,7 @@ final class CreateRecordReactionTest extends FunctionalTestCase
         self::assertEquals('Invalid argument "table_name"', json_decode((string)$response->getBody(), true)['error']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function reactFailsOnInvalidFields(): void
     {
         $reactionRecord = (new ReactionRepository())->getReactionRecordByIdentifier('invalid-fields');
@@ -301,10 +297,8 @@ final class CreateRecordReactionTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider replacePlaceHolderDataProvider
-     * @test
-     */
+    #[DataProvider('replacePlaceHolderDataProvider')]
+    #[Test]
     public function replacePlaceHolders(mixed $value, array $payload, string $expected): void
     {
         $subject = GeneralUtility::makeInstance(CreateRecordReaction::class);
diff --git a/typo3/sysext/reactions/Tests/Functional/ReactionRegistryTest.php b/typo3/sysext/reactions/Tests/Functional/ReactionRegistryTest.php
index 1457796511b7..a8f3a6f3c3bf 100644
--- a/typo3/sysext/reactions/Tests/Functional/ReactionRegistryTest.php
+++ b/typo3/sysext/reactions/Tests/Functional/ReactionRegistryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Reactions\Tests\Functional;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Reactions\Reaction\CreateRecordReaction;
 use TYPO3\CMS\Reactions\ReactionRegistry;
@@ -37,9 +38,7 @@ final class ReactionRegistryTest extends FunctionalTestCase
         $this->subject = new ReactionRegistry($reactions);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getAvailableReactionTypes(): void
     {
         $types = iterator_to_array($this->subject->getAvailableReactionTypes()->getIterator());
@@ -47,9 +46,7 @@ final class ReactionRegistryTest extends FunctionalTestCase
         self::assertCount(1, $types);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReactionByType(): void
     {
         self::assertInstanceOf(CreateRecordReaction::class, $this->subject->getReactionByType(CreateRecordReaction::getType()));
diff --git a/typo3/sysext/reactions/Tests/Functional/Repository/ReactionsRepositoryTest.php b/typo3/sysext/reactions/Tests/Functional/Repository/ReactionsRepositoryTest.php
index c7f4ad8b6443..c9535279d2d7 100644
--- a/typo3/sysext/reactions/Tests/Functional/Repository/ReactionsRepositoryTest.php
+++ b/typo3/sysext/reactions/Tests/Functional/Repository/ReactionsRepositoryTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Reactions\Tests\Functional\Repository;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Reactions\Repository\ReactionDemand;
 use TYPO3\CMS\Reactions\Repository\ReactionRepository;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -55,10 +57,8 @@ final class ReactionsRepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider demandProvider
-     * @test
-     */
+    #[DataProvider('demandProvider')]
+    #[Test]
     public function findByDemandWorks(ReactionDemand $demand, int $resultCount): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/ReactionsRepositoryTest_reactions.csv');
@@ -66,9 +66,7 @@ final class ReactionsRepositoryTest extends FunctionalTestCase
         self::assertCount($resultCount, $results);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function findAllWorks(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/ReactionsRepositoryTest_reactions.csv');
@@ -76,9 +74,7 @@ final class ReactionsRepositoryTest extends FunctionalTestCase
         self::assertCount(4, $results);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getReactionRecordsWithoutDemand(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/ReactionsRepositoryTest_reactions.csv');
diff --git a/typo3/sysext/recycler/Tests/Functional/Recycle/Pages/AdminRecycleTest.php b/typo3/sysext/recycler/Tests/Functional/Recycle/Pages/AdminRecycleTest.php
index 88c37b5bef1a..b7b0b33b2ebf 100644
--- a/typo3/sysext/recycler/Tests/Functional/Recycle/Pages/AdminRecycleTest.php
+++ b/typo3/sysext/recycler/Tests/Functional/Recycle/Pages/AdminRecycleTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Recycler\Tests\Functional\Recycle\Pages;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Recycler\Tests\Functional\Recycle\AbstractRecycleTestCase;
 
@@ -33,9 +34,7 @@ final class AdminRecycleTest extends AbstractRecycleTestCase
         Bootstrap::initializeLanguageObject();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function retrieveDeletedPagesNoRecursion(): void
     {
         $deletedPages = $this->getDeletedPages(1, 0);
@@ -46,9 +45,7 @@ final class AdminRecycleTest extends AbstractRecycleTestCase
         self::assertSame(3, (int)$deletedPages['pages'][0]['uid']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function retrieveDeletedPagesOneLevelRecursion(): void
     {
         $deletedPages = $this->getDeletedPages(1, 1);
diff --git a/typo3/sysext/recycler/Tests/Functional/Recycle/Pages/UserRecycleTest.php b/typo3/sysext/recycler/Tests/Functional/Recycle/Pages/UserRecycleTest.php
index c48660e66219..8d93821f2a12 100644
--- a/typo3/sysext/recycler/Tests/Functional/Recycle/Pages/UserRecycleTest.php
+++ b/typo3/sysext/recycler/Tests/Functional/Recycle/Pages/UserRecycleTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Recycler\Tests\Functional\Recycle\Pages;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Recycler\Tests\Functional\Recycle\AbstractRecycleTestCase;
 
@@ -33,9 +34,7 @@ final class UserRecycleTest extends AbstractRecycleTestCase
         Bootstrap::initializeLanguageObject();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function retrieveDeletedPagesNoRecursion(): void
     {
         $deletedPages = $this->getDeletedPages(1, 0);
@@ -46,9 +45,7 @@ final class UserRecycleTest extends AbstractRecycleTestCase
         self::assertSame(3, (int)$deletedPages['pages'][0]['uid']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function retrieveDeletedPagesOneLevelRecursion(): void
     {
         $deletedPages = $this->getDeletedPages(1, 1);
@@ -59,18 +56,14 @@ final class UserRecycleTest extends AbstractRecycleTestCase
         self::assertSame(3, (int)$deletedPages['pages'][0]['uid']);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canNotRetrieveDeletedPagesOutsideWebmount(): void
     {
         $deletedPages = $this->getDeletedPages(6, 0);
         self::assertCount(0, $deletedPages);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function canNotRetrieveDeletedWithNoAccess(): void
     {
         $deletedPages = $this->getDeletedPages(7, 0);
diff --git a/typo3/sysext/recycler/Tests/Functional/Task/CleanerFieldProviderTest.php b/typo3/sysext/recycler/Tests/Functional/Task/CleanerFieldProviderTest.php
index ab423617d479..cc41817f3c5e 100644
--- a/typo3/sysext/recycler/Tests/Functional/Task/CleanerFieldProviderTest.php
+++ b/typo3/sysext/recycler/Tests/Functional/Task/CleanerFieldProviderTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Recycler\Tests\Functional\Task;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Messaging\FlashMessageService;
 use TYPO3\CMS\Recycler\Task\CleanerFieldProvider;
@@ -40,10 +42,8 @@ final class CleanerFieldProviderTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider validateAdditionalFieldsLogsPeriodErrorDataProvider
-     */
+    #[DataProvider('validateAdditionalFieldsLogsPeriodErrorDataProvider')]
+    #[Test]
     public function validateAdditionalFieldsLogsPeriodError(mixed $period): void
     {
         $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->create('default');
@@ -66,10 +66,8 @@ final class CleanerFieldProviderTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider validateAdditionalFieldsDataProvider
-     */
+    #[DataProvider('validateAdditionalFieldsDataProvider')]
+    #[Test]
     public function validateAdditionalFieldsLogsTableError(mixed $table): void
     {
         $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->create('default');
@@ -82,9 +80,7 @@ final class CleanerFieldProviderTest extends FunctionalTestCase
         self::assertFalse($this->get(FlashMessageService::class)->getMessageQueueByIdentifier()->isEmpty());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function validateAdditionalFieldsIsTrueIfValid(): void
     {
         $submittedData = [
@@ -96,9 +92,7 @@ final class CleanerFieldProviderTest extends FunctionalTestCase
         self::assertTrue($subject->validateAdditionalFields($submittedData, $this->get(SchedulerModuleController::class)));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function saveAdditionalFieldsSavesFields(): void
     {
         $submittedData = [
diff --git a/typo3/sysext/recycler/Tests/Functional/Task/CleanerTaskTest.php b/typo3/sysext/recycler/Tests/Functional/Task/CleanerTaskTest.php
index b123a08b1c97..3f74347f698f 100644
--- a/typo3/sysext/recycler/Tests/Functional/Task/CleanerTaskTest.php
+++ b/typo3/sysext/recycler/Tests/Functional/Task/CleanerTaskTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Recycler\Tests\Functional\Task;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Recycler\Task\CleanerTask;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
 
@@ -24,9 +25,7 @@ final class CleanerTaskTest extends FunctionalTestCase
 {
     protected array $coreExtensionsToLoad = ['recycler', 'scheduler'];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function taskRemovesDeletedPages(): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/Fixtures/pages.csv');
@@ -37,9 +36,7 @@ final class CleanerTaskTest extends FunctionalTestCase
         self::assertTrue($result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function taskRemovesOnlyPagesLongerDeletedThanPeriod(): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/Fixtures/pages.csv');
@@ -59,9 +56,7 @@ final class CleanerTaskTest extends FunctionalTestCase
         self::assertTrue($result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function taskFailsOnError(): void
     {
         $subject = new CleanerTask();
diff --git a/typo3/sysext/redirects/Tests/Functional/Controller/ManagementControllerTest.php b/typo3/sysext/redirects/Tests/Functional/Controller/ManagementControllerTest.php
index 3ba1c4e77124..810587eae860 100644
--- a/typo3/sysext/redirects/Tests/Functional/Controller/ManagementControllerTest.php
+++ b/typo3/sysext/redirects/Tests/Functional/Controller/ManagementControllerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Redirects\Tests\Functional\Controller;
 
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Backend\Routing\Route;
 use TYPO3\CMS\Core\Core\Bootstrap;
@@ -46,9 +47,7 @@ final class ManagementControllerTest extends FunctionalTestCase
         $this->normalizedParams = new NormalizedParams([], [], '', '');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyRedirectManagementControllerViewDataEventIsTriggered(): void
     {
         $request = (new ServerRequest('https://www.example.com/', 'GET'))
diff --git a/typo3/sysext/redirects/Tests/Functional/EventListener/AddPageTypeZeroSourceTest.php b/typo3/sysext/redirects/Tests/Functional/EventListener/AddPageTypeZeroSourceTest.php
index 9ed4c2dc8683..c6add9614f44 100644
--- a/typo3/sysext/redirects/Tests/Functional/EventListener/AddPageTypeZeroSourceTest.php
+++ b/typo3/sysext/redirects/Tests/Functional/EventListener/AddPageTypeZeroSourceTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Redirects\Tests\Functional\EventListener;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Core\Configuration\SiteConfiguration;
@@ -38,9 +39,7 @@ final class AddPageTypeZeroSourceTest extends FunctionalTestCase
 {
     protected array $coreExtensionsToLoad = ['redirects'];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTypeSourceZeroReplacesPlainSlugReplacementSourceToAvoidDuplicates(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SimpleSiteRoot.csv');
@@ -73,9 +72,7 @@ final class AddPageTypeZeroSourceTest extends FunctionalTestCase
         self::assertSame(0, $source->getPageType());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pageTapeSourceZeroWithPageTypeSuffixRouteEnhancerIsAddedAsAdditionalSource(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SimpleSiteRootWithPage.csv');
@@ -128,9 +125,7 @@ final class AddPageTypeZeroSourceTest extends FunctionalTestCase
         self::assertSame(0, $source->getPageType());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function customPageTypeSourceCanBeAdded(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SimpleSiteRootWithPage.csv');
diff --git a/typo3/sysext/redirects/Tests/Functional/EventListener/AddPlainSlugReplacementSourceTest.php b/typo3/sysext/redirects/Tests/Functional/EventListener/AddPlainSlugReplacementSourceTest.php
index c2cbc58194ce..090b4ae1b18a 100644
--- a/typo3/sysext/redirects/Tests/Functional/EventListener/AddPlainSlugReplacementSourceTest.php
+++ b/typo3/sysext/redirects/Tests/Functional/EventListener/AddPlainSlugReplacementSourceTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Redirects\Tests\Functional\EventListener;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Core\Configuration\SiteConfiguration;
@@ -33,9 +34,7 @@ final class AddPlainSlugReplacementSourceTest extends FunctionalTestCase
 {
     protected array $coreExtensionsToLoad = ['redirects'];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function plainSlugReplacementSourceIsAdded(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SimpleSiteRoot.csv');
diff --git a/typo3/sysext/redirects/Tests/Functional/EventListener/IncrementHitCountTest.php b/typo3/sysext/redirects/Tests/Functional/EventListener/IncrementHitCountTest.php
index ea2bae697f93..6b5373607956 100644
--- a/typo3/sysext/redirects/Tests/Functional/EventListener/IncrementHitCountTest.php
+++ b/typo3/sysext/redirects/Tests/Functional/EventListener/IncrementHitCountTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Redirects\Tests\Functional\EventListener;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Http\RedirectResponse;
@@ -35,9 +36,7 @@ final class IncrementHitCountTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/Fixtures/Redirects.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hitCountIsCorrectlyIncremented(): void
     {
         $matchedRecord = BackendUtility::getRecord('sys_redirect', 12);
diff --git a/typo3/sysext/redirects/Tests/Functional/RedirectUpdate/SlugRedirectChangeItemFactoryTest.php b/typo3/sysext/redirects/Tests/Functional/RedirectUpdate/SlugRedirectChangeItemFactoryTest.php
index 93a951bc7337..e66183d1e3dc 100644
--- a/typo3/sysext/redirects/Tests/Functional/RedirectUpdate/SlugRedirectChangeItemFactoryTest.php
+++ b/typo3/sysext/redirects/Tests/Functional/RedirectUpdate/SlugRedirectChangeItemFactoryTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Redirects\Tests\Functional\RedirectUpdate;
 
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Core\Configuration\SiteConfiguration;
 use TYPO3\CMS\Core\EventDispatcher\ListenerProvider;
@@ -30,9 +31,7 @@ final class SlugRedirectChangeItemFactoryTest extends FunctionalTestCase
 {
     protected array $coreExtensionsToLoad = ['redirects'];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function returnsNullIfNoSiteConfigurationCanBeFound(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysFolderAsRootPage.csv');
@@ -41,9 +40,7 @@ final class SlugRedirectChangeItemFactoryTest extends FunctionalTestCase
         self::assertNull($changeItem);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function returnsNullIfSiteConfigurationFoundButAutoCreateRedirectsAndAutoUpdateSlugsOptionsDisabled(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysFolderAsRootPage.csv');
@@ -60,9 +57,7 @@ final class SlugRedirectChangeItemFactoryTest extends FunctionalTestCase
         self::assertNull($changeItem);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function returnsChangeItemIfSiteConfigurationFoundAndOnlyAutoCreateRedirectsEnabled(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysFolderAsRootPage.csv');
@@ -81,9 +76,7 @@ final class SlugRedirectChangeItemFactoryTest extends FunctionalTestCase
         self::assertSame(1, $changeItem->getDefaultLanguagePageId());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function returnsChangeItemIfSiteConfigurationFoundAndOnlyAutoUpdateSlugsEnabled(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysFolderAsRootPage.csv');
@@ -102,9 +95,7 @@ final class SlugRedirectChangeItemFactoryTest extends FunctionalTestCase
         self::assertSame(1, $changeItem->getDefaultLanguagePageId());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function slugRedirectChangeItemCreatedEventIsTriggered(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SysFolderAsRootPage.csv');
diff --git a/typo3/sysext/redirects/Tests/Functional/Repository/RedirectRepositoryTest.php b/typo3/sysext/redirects/Tests/Functional/Repository/RedirectRepositoryTest.php
index b04b82c3aa9e..a9597f2146d1 100644
--- a/typo3/sysext/redirects/Tests/Functional/Repository/RedirectRepositoryTest.php
+++ b/typo3/sysext/redirects/Tests/Functional/Repository/RedirectRepositoryTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Redirects\Tests\Functional\Repository;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Redirects\Repository\Demand;
@@ -84,10 +86,8 @@ final class RedirectRepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider demandProvider
-     * @test
-     */
+    #[DataProvider('demandProvider')]
+    #[Test]
     public function removeByDemandWorks(Demand $demand, int $redirectBeforeCleanup, int $redirectAfterCleanup): void
     {
         self::assertSame(0, $this->getRedirectCount());
@@ -142,10 +142,8 @@ final class RedirectRepositoryTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @dataProvider countRedirectsByDemandCountsCorrectlyDataProvider
-     * @test
-     */
+    #[DataProvider('countRedirectsByDemandCountsCorrectlyDataProvider')]
+    #[Test]
     public function countRedirectsByDemandCountsCorrectly(Demand $demand, int $expectedCount): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/RedirectRepositoryTest_redirects.csv');
diff --git a/typo3/sysext/redirects/Tests/Functional/Service/IntegrityServiceTest.php b/typo3/sysext/redirects/Tests/Functional/Service/IntegrityServiceTest.php
index b9e0427bc873..ba89d2aad3c7 100644
--- a/typo3/sysext/redirects/Tests/Functional/Service/IntegrityServiceTest.php
+++ b/typo3/sysext/redirects/Tests/Functional/Service/IntegrityServiceTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Redirects\Tests\Functional\Service;
 
+use PHPUnit\Framework\Attributes\Test;
 use PHPUnit\Framework\MockObject\MockObject;
 use TYPO3\CMS\Core\EventDispatcher\NoopEventDispatcher;
 use TYPO3\CMS\Core\LinkHandling\LinkService;
@@ -53,9 +54,8 @@ final class IntegrityServiceTest extends FunctionalTestCase
      * page WITHOUT language component (e.g.  /en, /de etc.).
      *
      * The integrity service should NOT detect this as a conflict.
-     *
-     * @test
      */
+    #[Test]
     public function sourcePathWithMatchingSlugInLocalizedPageIsNotReportedAsConflict(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/IntegrityServiceTest_sourcePathWithMatchingSlugInLocalizedPageIsNotReportedAsConflict.csv');
@@ -64,9 +64,7 @@ final class IntegrityServiceTest extends FunctionalTestCase
         $this->assertExpectedPathsFromGenerator([], $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function conflictingRedirectsAreFoundForDefinedSiteOnly(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SimplePages.csv');
@@ -106,9 +104,7 @@ final class IntegrityServiceTest extends FunctionalTestCase
         $this->assertExpectedPathsFromGenerator($expectedConflicts, $this->subject->findConflictingRedirects('simple-page'));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function conflictingRedirectsAreFoundForLocalizedPages(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/LocalizedPages.csv');
@@ -141,9 +137,7 @@ final class IntegrityServiceTest extends FunctionalTestCase
         $this->assertExpectedPathsFromGenerator($expectedConflicts, $conflicts);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function conflictingRedirectsAreFoundForAllSites(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/SimplePages.csv');
diff --git a/typo3/sysext/redirects/Tests/Functional/Service/RedirectServiceTest.php b/typo3/sysext/redirects/Tests/Functional/Service/RedirectServiceTest.php
index b61343b5f589..6c2b96de7ebf 100644
--- a/typo3/sysext/redirects/Tests/Functional/Service/RedirectServiceTest.php
+++ b/typo3/sysext/redirects/Tests/Functional/Service/RedirectServiceTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Redirects\Tests\Functional\Service;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use Psr\Log\NullLogger;
 use Symfony\Component\DependencyInjection\Container;
@@ -77,9 +79,7 @@ final class RedirectServiceTest extends FunctionalTestCase
         parent::tearDown();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function linkForRedirectToAccessRestrictedPageIsBuild(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/RedirectToAccessRestrictedPages.csv');
@@ -158,10 +158,8 @@ final class RedirectServiceTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider redirectsDataProvider
-     */
+    #[DataProvider('redirectsDataProvider')]
+    #[Test]
     public function checkReponseCodeOnRedirect($url, $statusCode, $targetUrl, $redirectUid): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/RedirectToPages.csv');
@@ -309,10 +307,8 @@ final class RedirectServiceTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider checkRegExpRedirectsDataProvider
-     */
+    #[DataProvider('checkRegExpRedirectsDataProvider')]
+    #[Test]
     public function checkRegExpRedirects(string $url, int $expectedStatusCode, string $expectedRedirectUri, int $expectedRedirectUid)
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/RedirectService_regexp.csv');
@@ -338,9 +334,9 @@ final class RedirectServiceTest extends FunctionalTestCase
     }
 
     /**
-     * @test
      * @see https://forge.typo3.org/issues/101739
      */
+    #[Test]
     public function regexpWithNoParamRegexpAndRespectingGetParameteresIssuesNotFoundStatusIfParamsAreGivenInUrl(): void
     {
         $url = 'https://acme.com/regexp-respect-get-parameter?param1=value1';
@@ -364,9 +360,9 @@ final class RedirectServiceTest extends FunctionalTestCase
     }
 
     /**
-     * @test
      * @see https://forge.typo3.org/issues/101739
      */
+    #[Test]
     public function regexpWithNoParamRegexpAndRespectingGetParameteresRedirectsIfNoParamsAreGiven(): void
     {
         $url = 'https://acme.com/regexp-respect-get-parameter';
@@ -525,10 +521,8 @@ final class RedirectServiceTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider samePathWithSameDomainT3TargetDataProvider
-     */
+    #[DataProvider('samePathWithSameDomainT3TargetDataProvider')]
+    #[Test]
     public function samePathWithSameDomainT3Target(string $url, string $baseUri, int $expectedStatusCode, ?string $expectedRedirectUri, ?int $expectedRedirectUid): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/RedirectService_samePathWithSameDomainT3Target.csv');
@@ -670,10 +664,8 @@ final class RedirectServiceTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider samePathWithSameDomainAndRelativeTargetDataProvider
-     */
+    #[DataProvider('samePathWithSameDomainAndRelativeTargetDataProvider')]
+    #[Test]
     public function samePathWithSameDomainAndRelativeTarget(string $url, string $baseUri, int $expectedStatusCode, ?string $expectedRedirectUri, ?int $expectedRedirectUid): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/RedirectService_samePathWithSameDomainAndRelativeTarget.csv');
@@ -835,10 +827,8 @@ final class RedirectServiceTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider samePathRedirectsWithExternalTargetDataProvider
-     */
+    #[DataProvider('samePathRedirectsWithExternalTargetDataProvider')]
+    #[Test]
     public function samePathRedirectsWithExternalTarget(string $url, string $baseUri, int $expectedStatusCode, ?string $expectedRedirectUri, ?int $expectedRedirectUid): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/RedirectService_samePathRedirectsWithExternalTarget.csv');
@@ -865,9 +855,7 @@ final class RedirectServiceTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function beforeRedirectMatchDomainEventIsTriggered(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/BeforeRedirectMatchDomainEventIsTriggered.csv');
@@ -956,10 +944,8 @@ final class RedirectServiceTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider regExpRedirectsWithArgumentMatchesWithSimilarRegExpWithoutQueryParamInRecordDataProvider
-     */
+    #[DataProvider('regExpRedirectsWithArgumentMatchesWithSimilarRegExpWithoutQueryParamInRecordDataProvider')]
+    #[Test]
     public function regExpRedirectsWithArgumentMatchesWithSimilarRegExpWithoutQueryParamInRecord(
         string $importDataSet,
         string $url,
diff --git a/typo3/sysext/redirects/Tests/Functional/Service/SlugServiceTest.php b/typo3/sysext/redirects/Tests/Functional/Service/SlugServiceTest.php
index 54393e0fa64f..e1f5af346f9f 100644
--- a/typo3/sysext/redirects/Tests/Functional/Service/SlugServiceTest.php
+++ b/typo3/sysext/redirects/Tests/Functional/Service/SlugServiceTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Redirects\Tests\Functional\Service;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use Psr\Log\NullLogger;
 use Symfony\Component\DependencyInjection\Container;
@@ -108,8 +109,8 @@ final class SlugServiceTest extends FunctionalTestCase
      * and all slugs of sub pages are renamed and redirects are created.
      *
      * We test here that rebuildSlugsForSlugChange works for a partial tree.
-     * @test
      */
+    #[Test]
     public function rebuildSlugsForSlugChangeRenamesSubSlugsAndCreatesRedirects(): void
     {
         $newPageSlug = '/test-new';
@@ -151,8 +152,8 @@ final class SlugServiceTest extends FunctionalTestCase
      * and all slugs of sub pages are renamed and redirects are created.
      *
      * We test here that rebuildSlugsForSlugChange works for a complete tree inclusive the root page.
-     * @test
      */
+    #[Test]
     public function rebuildSlugsForSlugChangeRenamesSubSlugsAndCreatesRedirectsForRootChange(): void
     {
         $newPageSlug = '/new-home';
@@ -200,8 +201,8 @@ final class SlugServiceTest extends FunctionalTestCase
      * and all slugs of sub pages are renamed and redirects are created.
      *
      * We test here that rebuildSlugsForSlugChange works for a setup with a base in a sub-folder.
-     * @test
      */
+    #[Test]
     public function rebuildSlugsForSlugChangeRenamesSubSlugsAndCreatesRedirectsWithSubFolderBase(): void
     {
         $newPageSlug = '/test-new';
@@ -243,8 +244,8 @@ final class SlugServiceTest extends FunctionalTestCase
      * and all slugs of sub-pages are renamed and redirects are created.
      *
      * We test here that rebuildSlugsForSlugChange works for a setup with languages.
-     * @test
      */
+    #[Test]
     public function rebuildSlugsForSlugChangeRenamesSubSlugsAndCreatesRedirectsWithLanguages(): void
     {
         $newPageSlug = '/test-new';
@@ -286,8 +287,8 @@ final class SlugServiceTest extends FunctionalTestCase
      * and all slugs of sub-pages are renamed and redirects are created.
      *
      * We test here that rebuildSlugsForSlugChange works with languages and a base in a sub-folder.
-     * @test
      */
+    #[Test]
     public function rebuildSlugsForSlugChangeRenamesSubSlugsAndCreatesRedirectsWithLanguagesInSubFolder(): void
     {
         $newPageSlug = '/test-new';
@@ -329,8 +330,8 @@ final class SlugServiceTest extends FunctionalTestCase
      * and all slugs of sub-pages are renamed and redirects are created.
      *
      * We test here that rebuildSlugsForSlugChange works with languages and a base in a sub-folder.
-     * @test
      */
+    #[Test]
     public function rebuildSlugsForSlugChangeRenamesSubSlugsAndCreatesRedirectsWithDefaultLanguageInSubFolder(): void
     {
         $newPageSlug = '/test-new';
@@ -373,8 +374,8 @@ final class SlugServiceTest extends FunctionalTestCase
      * and all slugs of sub-pages are renamed and redirects are created.
      *
      * We test here that rebuildSlugsForSlugChange works when changing a L>0 siteroot which has pid=0
-     * @test
      */
+    #[Test]
     public function rebuildSlugsForSlugChangeRenamesSubSlugsAndCreatesRedirectsWithLanguagesForSiteroot(): void
     {
         $newPageSlug = '/test-new';
@@ -409,9 +410,7 @@ final class SlugServiceTest extends FunctionalTestCase
         $this->assertSlugsAndRedirectsExists($slugs, $redirects);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function modifyAutoCreateRedirectRecordBeforePersistingIsTriggered(): void
     {
         $newPageSlug = '/test-new';
@@ -462,9 +461,7 @@ final class SlugServiceTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function afterAutoCreteRedirectHasBeenPersistedIsTriggered(): void
     {
         $newPageSlug = '/test-new';
@@ -506,9 +503,7 @@ final class SlugServiceTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function sysFolderWithSubPagesDoesNotCreateAutoRedirectForSysFolderButUpdatesSubpagesIfReasonable(): void
     {
         $newPageSlug = '/test-new';
@@ -535,9 +530,7 @@ final class SlugServiceTest extends FunctionalTestCase
         $this->assertSlugsAndRedirectsExists($slugs, $redirects);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function spacerWithSubPagesDoesNotCreateAutoRedirectForSpacerButUpdatesSubpagesIfReasonable(): void
     {
         $newPageSlug = '/test-new';
diff --git a/typo3/sysext/redirects/Tests/Functional/WebhookExecutionTest.php b/typo3/sysext/redirects/Tests/Functional/WebhookExecutionTest.php
index 0a922171427a..f52c187eac4c 100644
--- a/typo3/sysext/redirects/Tests/Functional/WebhookExecutionTest.php
+++ b/typo3/sysext/redirects/Tests/Functional/WebhookExecutionTest.php
@@ -15,6 +15,7 @@
 
 namespace TYPO3\CMS\Redirects\Tests\Functional;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use Psr\Http\Message\RequestInterface;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
@@ -40,9 +41,7 @@ final class WebhookExecutionTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/Fixtures/sys_redirect.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function matchedRedirectEmitsWebhookMessage(): void
     {
         $payloadSourceUrl = null;
diff --git a/typo3/sysext/rte_ckeditor/Tests/Functional/RecordList/Controller/BrowseLinksControllerTest.php b/typo3/sysext/rte_ckeditor/Tests/Functional/RecordList/Controller/BrowseLinksControllerTest.php
index ac6979d7ec81..ad81f9da7b2d 100644
--- a/typo3/sysext/rte_ckeditor/Tests/Functional/RecordList/Controller/BrowseLinksControllerTest.php
+++ b/typo3/sysext/rte_ckeditor/Tests/Functional/RecordList/Controller/BrowseLinksControllerTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\RteCKEditor\Tests\Functional\RecordList\Controller;
 
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Backend\Controller\Event\ModifyAllowedItemsEvent;
 use TYPO3\CMS\Backend\Controller\Event\ModifyLinkHandlersEvent;
@@ -44,9 +45,7 @@ final class BrowseLinksControllerTest extends FunctionalTestCase
         Bootstrap::initializeLanguageObject();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function linkEventsAreTriggered(): void
     {
         /** @var Container $container */
diff --git a/typo3/sysext/scheduler/Tests/Functional/Tca/TaskGroupVisibleFieldsTest.php b/typo3/sysext/scheduler/Tests/Functional/Tca/TaskGroupVisibleFieldsTest.php
index b39cb9faf222..19f65af1168c 100644
--- a/typo3/sysext/scheduler/Tests/Functional/Tca/TaskGroupVisibleFieldsTest.php
+++ b/typo3/sysext/scheduler/Tests/Functional/Tca/TaskGroupVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Scheduler\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -35,9 +36,7 @@ final class TaskGroupVisibleFieldsTest extends FunctionalTestCase
         'description',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function taskGroupFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/seo/Tests/Functional/Canonical/CanonicalGeneratorTest.php b/typo3/sysext/seo/Tests/Functional/Canonical/CanonicalGeneratorTest.php
index 786280a95f52..825a2c905da3 100644
--- a/typo3/sysext/seo/Tests/Functional/Canonical/CanonicalGeneratorTest.php
+++ b/typo3/sysext/seo/Tests/Functional/Canonical/CanonicalGeneratorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Seo\Tests\Functional\Canonical;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Core\EventDispatcher\ListenerProvider;
 use TYPO3\CMS\Core\Http\ServerRequest;
@@ -135,10 +137,8 @@ final class CanonicalGeneratorTest extends FunctionalTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider generateDataProvider
-     */
+    #[DataProvider('generateDataProvider')]
+    #[Test]
     public function generate(string $targetUri, string $expectedCanonicalUrl): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -152,9 +152,7 @@ final class CanonicalGeneratorTest extends FunctionalTestCase
         }
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function afterContentObjectRendererInitializedEventIsCalled(): void
     {
         $modifyUrlForCanonicalTagEvent = null;
diff --git a/typo3/sysext/seo/Tests/Functional/HrefLang/HrefLangGeneratorTest.php b/typo3/sysext/seo/Tests/Functional/HrefLang/HrefLangGeneratorTest.php
index 9e845ee0f060..cb4616285898 100644
--- a/typo3/sysext/seo/Tests/Functional/HrefLang/HrefLangGeneratorTest.php
+++ b/typo3/sysext/seo/Tests/Functional/HrefLang/HrefLangGeneratorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Seo\Tests\Functional\HrefLang;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait;
 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
@@ -70,10 +72,8 @@ final class HrefLangGeneratorTest extends FunctionalTestCase
         });
     }
 
-    /**
-     * @test
-     * @dataProvider checkHrefLangOutputDataProvider
-     */
+    #[DataProvider('checkHrefLangOutputDataProvider')]
+    #[Test]
     public function checkHrefLangOutput(string $url, array $expectedTags, array $notExpectedTags): void
     {
         $this->setUpFrontendRootPage(
diff --git a/typo3/sysext/seo/Tests/Functional/MetaTag/MetaTagGeneratorTest.php b/typo3/sysext/seo/Tests/Functional/MetaTag/MetaTagGeneratorTest.php
index 0c227108230d..e487e79ee482 100644
--- a/typo3/sysext/seo/Tests/Functional/MetaTag/MetaTagGeneratorTest.php
+++ b/typo3/sysext/seo/Tests/Functional/MetaTag/MetaTagGeneratorTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Seo\Tests\Functional\MetaTag;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Imaging\ImageManipulation\Area;
 use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
 use TYPO3\CMS\Core\Resource\File;
@@ -140,9 +142,9 @@ final class MetaTagGeneratorTest extends FunctionalTestCase
     /**
      * @param array{width: int, height: int} $imageDimension
      * @param array{width: int, height: int} $expectedDimension
-     * @test
-     * @dataProvider socialImageIsProcessedDataProvider
      */
+    #[DataProvider('socialImageIsProcessedDataProvider')]
+    #[Test]
     public function socialImageIsProcessed(bool $hasCrop, array $imageDimension, array $expectedDimension, string $expectedClassName): void
     {
         $fileName = sprintf('test_%dx%d.png', $imageDimension['width'], $imageDimension['height']);
diff --git a/typo3/sysext/seo/Tests/Functional/MetaTag/MetaTagTest.php b/typo3/sysext/seo/Tests/Functional/MetaTag/MetaTagTest.php
index 841893293d4b..8245e937cc15 100644
--- a/typo3/sysext/seo/Tests/Functional/MetaTag/MetaTagTest.php
+++ b/typo3/sysext/seo/Tests/Functional/MetaTag/MetaTagTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Seo\Tests\Functional\MetaTag;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 
@@ -65,10 +67,8 @@ final class MetaTagTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     * @dataProvider ensureMetaDataAreCorrectDataProvider
-     */
+    #[DataProvider('ensureMetaDataAreCorrectDataProvider')]
+    #[Test]
     public function ensureMetaDataAreCorrect(int $pageId, array $expectedMetaTags): void
     {
         $this->setUpFrontendRootPage(1, ['typo3/sysext/seo/Tests/Functional/Fixtures/page' . $pageId . '.typoscript']);
diff --git a/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapIndexTest.php b/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapIndexTest.php
index 3967f4615e4b..5e9bddb7ece8 100644
--- a/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapIndexTest.php
+++ b/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapIndexTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Seo\Tests\Functional\XmlSitemap;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 
@@ -40,9 +41,7 @@ final class XmlSitemapIndexTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function checkIfSiteMapIndexContainsPagesSitemap(): void
     {
         $this->writeSiteConfiguration(
diff --git a/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapPagesTest.php b/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapPagesTest.php
index 17f01786c69e..a95018282ed5 100644
--- a/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapPagesTest.php
+++ b/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapPagesTest.php
@@ -17,6 +17,9 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Seo\Tests\Functional\XmlSitemap;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
+
 /**
  * Contains functional tests for the XmlSitemap Index
  */
@@ -32,9 +35,9 @@ final class XmlSitemapPagesTest extends AbstractXmlSitemapPagesTestCase
 
     /**
      * @param string $urlPattern
-     * @test
-     * @dataProvider pagesToCheckDataProvider
      */
+    #[DataProvider('pagesToCheckDataProvider')]
+    #[Test]
     public function checkIfPagesSiteMapContainsExpectedEntries($urlPattern): void
     {
         $response = $this->getResponse();
@@ -49,9 +52,7 @@ final class XmlSitemapPagesTest extends AbstractXmlSitemapPagesTestCase
         self::assertMatchesRegularExpression($urlPattern, (string)$response->getBody());
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pagesSitemapDoesNotContainUrlWithCanonicalSet(): void
     {
         self::assertStringNotContainsString(
@@ -60,9 +61,7 @@ final class XmlSitemapPagesTest extends AbstractXmlSitemapPagesTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pagesSitemapDoesNotContainUrlWithNoIndexSet(): void
     {
         self::assertStringNotContainsString(
@@ -73,9 +72,8 @@ final class XmlSitemapPagesTest extends AbstractXmlSitemapPagesTestCase
 
     /**
      * Tests for exclusion depending on the l18n_cfg field
-     *
-     * @test
      */
+    #[Test]
     public function pagesSitemapInDefaultLanguageDoesNotContainSiteThatIsHiddenInDefaultLanguage(): void
     {
         self::assertStringNotContainsString(
@@ -86,9 +84,8 @@ final class XmlSitemapPagesTest extends AbstractXmlSitemapPagesTestCase
 
     /**
      * Tests for exclusion depending on the l18n_cfg field
-     *
-     * @test
      */
+    #[Test]
     public function pagesSitemapInAlternativeLanguageDoesNotContainSiteThatIsHiddenIfNotTranslated(): void
     {
         self::assertStringNotContainsString(
@@ -106,9 +103,7 @@ final class XmlSitemapPagesTest extends AbstractXmlSitemapPagesTestCase
         ];
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pagesSitemapContainsTranslatedPages(): void
     {
         self::assertEquals(
@@ -117,9 +112,7 @@ final class XmlSitemapPagesTest extends AbstractXmlSitemapPagesTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pagesSitemapDoesNotContainUntranslatedPages(): void
     {
         self::assertStringNotContainsString(
@@ -128,9 +121,7 @@ final class XmlSitemapPagesTest extends AbstractXmlSitemapPagesTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pagesSitemapRespectFallbackStrategy(): void
     {
         self::assertStringContainsString(
@@ -139,9 +130,7 @@ final class XmlSitemapPagesTest extends AbstractXmlSitemapPagesTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function pagesSitemapDoesNotContainUrlsOfExcludedPages(): void
     {
         $this->setUpFrontendRootPage(
diff --git a/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapPagesWithHideIfNotTranslatedTest.php b/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapPagesWithHideIfNotTranslatedTest.php
index 412baade8ec5..b0785f85806a 100644
--- a/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapPagesWithHideIfNotTranslatedTest.php
+++ b/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapPagesWithHideIfNotTranslatedTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Seo\Tests\Functional\XmlSitemap;
 
+use PHPUnit\Framework\Attributes\Test;
+
 /**
  * Contains functional tests for the XmlSitemap Index with
  * $GLOBALS['TYPO3_CONF_VARS']['FE']['hidePagesIfNotTranslatedByDefault'] = true
@@ -41,9 +43,8 @@ final class XmlSitemapPagesWithHideIfNotTranslatedTest extends AbstractXmlSitema
      * Page marked as "Hide page if no translation for current language exists".
      * With "hidePagesIfNotTranslatedByDefault" enabled we expect to see the page
      * because it does NOT exist in the requested language (DE).
-     *
-     * @test
      */
+    #[Test]
     public function pagesSitemapInAlternativeLanguageDoesContainSiteThatIsHiddenIfNotTranslated(): void
     {
         self::assertStringContainsString(
@@ -54,9 +55,8 @@ final class XmlSitemapPagesWithHideIfNotTranslatedTest extends AbstractXmlSitema
 
     /**
      * Behavior is not changed with "hidePagesIfNotTranslatedByDefault"
-     *
-     * @test
      */
+    #[Test]
     public function pagesSitemapContainsTranslatedPages(): void
     {
         self::assertEquals(
@@ -67,9 +67,8 @@ final class XmlSitemapPagesWithHideIfNotTranslatedTest extends AbstractXmlSitema
 
     /**
      * Behavior is not changed with "hidePagesIfNotTranslatedByDefault"
-     *
-     * @test
      */
+    #[Test]
     public function pagesSitemapDoesNotContainUntranslatedPages(): void
     {
         self::assertStringNotContainsString(
@@ -81,9 +80,8 @@ final class XmlSitemapPagesWithHideIfNotTranslatedTest extends AbstractXmlSitema
     /**
      * Fallback strategy for pages is butchered by
      * "hidePagesIfNotTranslatedByDefault" completely.
-     *
-     * @test
      */
+    #[Test]
     public function pagesSitemapDoesNotCareAboutFallbackStrategy(): void
     {
         self::assertStringNotContainsString(
diff --git a/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapRecordsTest.php b/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapRecordsTest.php
index 3b38cd9b4fa4..b94d0fe00e69 100644
--- a/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapRecordsTest.php
+++ b/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapRecordsTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Seo\Tests\Functional\XmlSitemap;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 
@@ -64,10 +66,8 @@ final class XmlSitemapRecordsTest extends AbstractTestCase
         );
     }
 
-    /**
-     * @test
-     * @dataProvider sitemapEntriesToCheck
-     */
+    #[DataProvider('sitemapEntriesToCheck')]
+    #[Test]
     public function checkIfSiteMapIndexContainsSysCategoryLinks(string $sitemap, string $host, array $expectedEntries, array $notExpectedEntries): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -156,9 +156,7 @@ final class XmlSitemapRecordsTest extends AbstractTestCase
         ];
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function checkIfSiteMapIndexContainsCustomChangeFreqAndPriorityValues(): void
     {
         $response = $this->executeFrontendSubRequest(
@@ -183,10 +181,8 @@ final class XmlSitemapRecordsTest extends AbstractTestCase
         self::assertGreaterThan(0, $response->getHeader('Content-Length')[0]);
     }
 
-    /**
-     * @test
-     * @dataProvider additionalWhereTypoScriptConfigurationsToCheck
-     */
+    #[DataProvider('additionalWhereTypoScriptConfigurationsToCheck')]
+    #[Test]
     public function checkSiteMapWithDifferentTypoScriptConfigs(string $sitemap, array $expectedEntries, array $notExpectedEntries): void
     {
         $response = $this->executeFrontendSubRequest(
diff --git a/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapXslTest.php b/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapXslTest.php
index 4ef8742af144..5047c4e0fc1e 100644
--- a/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapXslTest.php
+++ b/typo3/sysext/seo/Tests/Functional/XmlSitemap/XmlSitemapXslTest.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Seo\Tests\Functional\XmlSitemap;
 
+use PHPUnit\Framework\Attributes\DataProvider;
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase;
 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
 
@@ -44,10 +46,8 @@ final class XmlSitemapXslTest extends AbstractTestCase
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/pages-sitemap.csv');
     }
 
-    /**
-     * @test
-     * @dataProvider getXslFilePathsDataProvider
-     */
+    #[DataProvider('getXslFilePathsDataProvider')]
+    #[Test]
     public function checkIfDefaultSitemapReturnsDefaultXsl(array $typoscriptSetupFiles, string $sitemap, string $xslFilePath): void
     {
         $this->setUpFrontendRootPage(
diff --git a/typo3/sysext/sys_note/Tests/Functional/Tca/NoteVisibleFieldsTest.php b/typo3/sysext/sys_note/Tests/Functional/Tca/NoteVisibleFieldsTest.php
index 70dc2e7d195a..d8de969ac0ff 100644
--- a/typo3/sysext/sys_note/Tests/Functional/Tca/NoteVisibleFieldsTest.php
+++ b/typo3/sysext/sys_note/Tests/Functional/Tca/NoteVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\SysNote\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -35,9 +36,7 @@ final class NoteVisibleFieldsTest extends FunctionalTestCase
         'message',
     ];
 
-    /**
-     * @test
-     */
+    #[Test]
     public function noteFormContainsExpectedFields(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
diff --git a/typo3/sysext/webhooks/Tests/Functional/WebhookExecutionTest.php b/typo3/sysext/webhooks/Tests/Functional/WebhookExecutionTest.php
index 3db88c8bd86b..3a62aa61ccee 100644
--- a/typo3/sysext/webhooks/Tests/Functional/WebhookExecutionTest.php
+++ b/typo3/sysext/webhooks/Tests/Functional/WebhookExecutionTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Webhooks\Tests\Functional;
 
+use PHPUnit\Framework\Attributes\Test;
 use Psr\Http\Message\RequestInterface;
 use Symfony\Component\Yaml\Yaml;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
@@ -87,9 +88,7 @@ final class WebhookExecutionTest extends FunctionalTestCase
         };
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function requestIsSentOutForMessagesWithAGivenType(): void
     {
         $numberOfRequestsFired = 0;
@@ -106,9 +105,7 @@ final class WebhookExecutionTest extends FunctionalTestCase
         self::assertEquals(1, $numberOfRequestsFired);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function oneMessageWithMultipleRequestsIsTriggeredAndDispatched(): void
     {
         self::markTestSkipped('Fails with phpunit 10 for unknown reasons. Probably broken since ever?');
@@ -139,9 +136,7 @@ final class WebhookExecutionTest extends FunctionalTestCase
         self::assertEquals(2, $numberOfRequestsFired);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function messageWithoutConfiguredTypesDoesNotSendARequest(): void
     {
         // Just empty the table for the request, other ways are possible to do this
diff --git a/typo3/sysext/workspaces/Tests/Functional/EventListener/PageTreeItemsHighlighterTest.php b/typo3/sysext/workspaces/Tests/Functional/EventListener/PageTreeItemsHighlighterTest.php
index 294099ac357a..5a1b7c496ca4 100644
--- a/typo3/sysext/workspaces/Tests/Functional/EventListener/PageTreeItemsHighlighterTest.php
+++ b/typo3/sysext/workspaces/Tests/Functional/EventListener/PageTreeItemsHighlighterTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Workspaces\Tests\Functional\EventListener;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Controller\Event\AfterPageTreeItemsPreparedEvent;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\WorkspaceAspect;
@@ -40,9 +41,7 @@ final class PageTreeItemsHighlighterTest extends FunctionalTestCase
         Bootstrap::initializeLanguageObject();
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function classesAreAppliedToPageItems(): void
     {
         $this->setWorkspaceId(91);
diff --git a/typo3/sysext/workspaces/Tests/Functional/Hook/DataHandlerHookTest.php b/typo3/sysext/workspaces/Tests/Functional/Hook/DataHandlerHookTest.php
index 42aa5a45a17f..e094ccebef1b 100644
--- a/typo3/sysext/workspaces/Tests/Functional/Hook/DataHandlerHookTest.php
+++ b/typo3/sysext/workspaces/Tests/Functional/Hook/DataHandlerHookTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Workspaces\Tests\Functional\Hook;
 
+use PHPUnit\Framework\Attributes\Test;
 use Symfony\Component\DependencyInjection\Container;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Context\Context;
@@ -60,9 +61,7 @@ final class DataHandlerHookTest extends FunctionalTestCase
         GeneralUtility::makeInstance(Context::class)->setAspect('workspace', new WorkspaceAspect($workspaceId));
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function deletingSysWorkspaceDeletesWorkspaceRecords(): void
     {
         $this->importCSVDataSet(__DIR__ . '/DataSet/deletingSysWorkspaceDeletesWorkspaceRecords.csv');
@@ -88,9 +87,7 @@ final class DataHandlerHookTest extends FunctionalTestCase
         $this->assertCSVDataSet(__DIR__ . '/DataSet/deletingSysWorkspaceDeletesWorkspaceRecordsResult.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function flushByTagEventIsTriggered(): void
     {
         $afterRecordPublishedEvent = null;
diff --git a/typo3/sysext/workspaces/Tests/Functional/Service/WorkspaceServiceTest.php b/typo3/sysext/workspaces/Tests/Functional/Service/WorkspaceServiceTest.php
index ba273fd8b2ea..f85cae3cffeb 100644
--- a/typo3/sysext/workspaces/Tests/Functional/Service/WorkspaceServiceTest.php
+++ b/typo3/sysext/workspaces/Tests/Functional/Service/WorkspaceServiceTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Workspaces\Tests\Functional\Service;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Workspaces\Service\WorkspaceService;
 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
@@ -37,9 +38,7 @@ final class WorkspaceServiceTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_workspace.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function emptyWorkspaceReturnsEmptyArray(): void
     {
         $service = new WorkspaceService();
@@ -48,9 +47,7 @@ final class WorkspaceServiceTest extends FunctionalTestCase
         self::assertIsArray($result, 'Even the empty result from workspace 90 is supposed to be an array');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function versionsFromSpecificWorkspaceCanBeFound(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/pages.csv');
@@ -66,9 +63,7 @@ final class WorkspaceServiceTest extends FunctionalTestCase
         self::assertEquals(1, $result['pages'][0]['livepid'], 'Real pid wasn\'t resolved correctly');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function versionsCanBeFoundRecursive(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/pages.csv');
@@ -82,9 +77,7 @@ final class WorkspaceServiceTest extends FunctionalTestCase
         );
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function versionsCanBeFilteredToSpecificStage(): void
     {
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/pages.csv');
@@ -111,9 +104,7 @@ final class WorkspaceServiceTest extends FunctionalTestCase
         self::assertEquals(106, $result['pages'][1]['uid'], 'First records is supposed to have the uid 106');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movedElementsCanBeFoundAtTheirDestination(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/WorkspaceServiceTestMovedContent.csv');
@@ -130,9 +121,7 @@ final class WorkspaceServiceTest extends FunctionalTestCase
         self::assertEquals(2, $result['tt_content'][0]['livepid'], 'Wrong live-pointer found for page 3 in workspace 91');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function movedElementsCanBeFoundUsingTheirLiveUid(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/WorkspaceServiceTestMovedContent.csv');
@@ -144,9 +133,7 @@ final class WorkspaceServiceTest extends FunctionalTestCase
         self::assertEquals(103, $result['pages'][0]['uid'], 'Wrong move-to pointer found for page 3 in workspace 91');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function getPagesWithVersionsInTableReturnsPagesWithVersionsInTable(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/WorkspaceServiceTestMovedContent.csv');
@@ -166,9 +153,7 @@ final class WorkspaceServiceTest extends FunctionalTestCase
         self::assertSame($expected, $result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasPageRecordVersionsReturnsTrueForPageWithVersions(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/WorkspaceServiceTestMovedContent.csv');
@@ -177,9 +162,7 @@ final class WorkspaceServiceTest extends FunctionalTestCase
         self::assertTrue($result);
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function hasPageRecordVersionsReturnsFalseForPageWithoutVersions(): void
     {
         $this->importCSVDataSet(__DIR__ . '/Fixtures/WorkspaceServiceTestMovedContent.csv');
diff --git a/typo3/sysext/workspaces/Tests/Functional/Tca/WorkspaceStageVisibleFieldsTest.php b/typo3/sysext/workspaces/Tests/Functional/Tca/WorkspaceStageVisibleFieldsTest.php
index 25d9942a4b12..dd0204bc7330 100644
--- a/typo3/sysext/workspaces/Tests/Functional/Tca/WorkspaceStageVisibleFieldsTest.php
+++ b/typo3/sysext/workspaces/Tests/Functional/Tca/WorkspaceStageVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Workspaces\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -50,9 +51,7 @@ final class WorkspaceStageVisibleFieldsTest extends FunctionalTestCase
         $GLOBALS['LANG'] = GeneralUtility::makeInstance(LanguageServiceFactory::class)->create('default');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function workspaceStageFormContainsExpectedFields(): void
     {
         $formEngineTestService = GeneralUtility::makeInstance(FormTestService::class);
diff --git a/typo3/sysext/workspaces/Tests/Functional/Tca/WorkspaceVisibleFieldsTest.php b/typo3/sysext/workspaces/Tests/Functional/Tca/WorkspaceVisibleFieldsTest.php
index 51e04709ef86..3dca3dea72d1 100644
--- a/typo3/sysext/workspaces/Tests/Functional/Tca/WorkspaceVisibleFieldsTest.php
+++ b/typo3/sysext/workspaces/Tests/Functional/Tca/WorkspaceVisibleFieldsTest.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Workspaces\Tests\Functional\Tca;
 
+use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Backend\Tests\Functional\Form\FormTestService;
 use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -67,9 +68,7 @@ final class WorkspaceVisibleFieldsTest extends FunctionalTestCase
         $this->importCSVDataSet(__DIR__ . '/../Fixtures/sys_filemounts.csv');
     }
 
-    /**
-     * @test
-     */
+    #[Test]
     public function workspaceFormContainsExpectedFields(): void
     {
         $formEngineTestService = GeneralUtility::makeInstance(FormTestService::class);
-- 
GitLab