diff --git a/docs/en/appendices/phpunit10.md b/docs/en/appendices/phpunit10.md
index a6606f000e..1fe7326b44 100644
--- a/docs/en/appendices/phpunit10.md
+++ b/docs/en/appendices/phpunit10.md
@@ -1,6 +1,17 @@
-# PHPUnit 10 Upgrade
+# PHPUnit Migration Guide
-With CakePHP 5 the minimum PHPUnit version has changed from `^8.5 || ^9.3` to `^10.1`. This introduces a few breaking changes from PHPUnit as well as from CakePHP's side.
+This guide covers the PHPUnit version requirements and migration steps for CakePHP 5.x applications.
+
+## Current Requirements
+
+CakePHP 5.x requires **PHPUnit ^11.5.3 or ^12.1.3**. This means:
+
+- PHPUnit 11.5.3+ requires **PHP 8.2** or later
+- PHPUnit 12.1.3+ requires **PHP 8.3** or later
+
+> [!NOTE]
+> PHPUnit 10 is no longer supported in CakePHP 5.x. If you are still on PHPUnit 10,
+> you must upgrade to PHPUnit 11 or 12.
## phpunit.xml adjustments
@@ -9,60 +20,131 @@ It is recommended to let PHPUnit update its configuration file via the following
vendor/bin/phpunit --migrate-configuration
> [!NOTE]
-> Make sure you are already on PHPUnit 10 via `vendor/bin/phpunit --version` before executing this command!
+> Make sure you verify your PHPUnit version via `vendor/bin/phpunit --version` before executing this command!
-With this command out of the way your `phpunit.xml` already has most of the recommended changes present.
+### Extension Configuration
-### New event system
+CakePHP's fixture extension uses PHPUnit's event system. Your `phpunit.xml` should have:
-PHPUnit 10 removed the old hook system and introduced a new [Event system](https://docs.phpunit.de/en/10.5/extending-phpunit.html#extending-the-test-runner)
-which requires the following code in your `phpunit.xml` to be adjusted from:
-
-``` php
+``` xml
-
+
```
-to:
+## Migrating from PHPUnit 10 to 11
+
+### Annotations to Attributes
+
+PHPUnit 11 deprecates docblock annotations and PHPUnit 12 removes them entirely.
+You should migrate to PHP 8 attributes:
``` php
-
-
-
+// Old way (deprecated in PHPUnit 11, removed in PHPUnit 12)
+/**
+ * @dataProvider myProvider
+ */
+public function testSomething($value): void
+{
+}
+
+// New way (required for PHPUnit 12+)
+use PHPUnit\Framework\Attributes\DataProvider;
+
+#[DataProvider('myProvider')]
+public function testSomething($value): void
+{
+}
```
-## `->withConsecutive()` has been removed
+Common attributes to use:
+
+| Old Annotation | New Attribute |
+|---------------|---------------|
+| `@test` | `#[Test]` |
+| `@dataProvider name` | `#[DataProvider('name')]` |
+| `@depends methodName` | `#[Depends('methodName')]` |
+| `@group name` | `#[Group('name')]` |
+| `@covers ClassName` | `#[CoversClass(ClassName::class)]` |
+| `@uses ClassName` | `#[UsesClass(ClassName::class)]` |
+
+Remember to import the attribute classes from `PHPUnit\Framework\Attributes`.
-You can convert the removed `->withConsecutive()` method to a
-working interim solution like you can see here:
+### Data Providers Must Be Static
+
+Data provider methods must be both `public` and `static`:
``` php
-->withConsecutive(['firstCallArg'], ['secondCallArg'])
+// Required format
+public static function myProvider(): array
+{
+ return [
+ ['value1'],
+ ['value2'],
+ ];
+}
```
-should be converted to:
+### Test Double Changes
+
+PHPUnit 11 made changes to mock object creation:
+
+- **Use `createStub()`** when you only need to stub return values and don't need
+ to verify method calls
+- **Use `createMock()`** when you need to set expectations and verify interactions
``` php
-->with(
- ...self::withConsecutive(['firstCallArg'], ['secondCallArg'])
-)
+// For isolating dependencies (no expectations)
+$stub = $this->createStub(SomeClass::class);
+$stub->method('getValue')->willReturn('test');
+
+// For testing object communication (with expectations)
+$mock = $this->createMock(SomeClass::class);
+$mock->expects($this->once())
+ ->method('doSomething')
+ ->with('argument');
```
-the static `self::withConsecutive()` method has been added via the `Cake\TestSuite\PHPUnitConsecutiveTrait`
-to the base `Cake\TestSuite\TestCase` class so you don't have to manually add that trait to your Testcase classes.
+> [!WARNING]
+> Configuring expectations (like `expects()`) on objects created with `createStub()`
+> triggers deprecation warnings in PHPUnit 11 and errors in PHPUnit 12.
+
+## Migrating from PHPUnit 11 to 12
+
+PHPUnit 12 requires **PHP 8.3** or later and enforces all deprecations from PHPUnit 11:
+
+- Docblock annotations are completely removed
+- Expectations on stubs are no longer allowed
+- Abstract class and trait mocking methods are removed
+
+Run your test suite with PHPUnit 11.5 and resolve all deprecation warnings before
+upgrading to PHPUnit 12.
+
+## CakePHP Test Utilities
-## data providers have to be static
+### withConsecutive() Replacement
-If your testcases leverage the data provider feature of PHPUnit then
-you have to adjust your data providers to be static:
+The removed `->withConsecutive()` method can be replaced using CakePHP's trait:
``` php
-public function myProvider(): array
+// Old way (removed in PHPUnit 10+)
+->withConsecutive(['firstCallArg'], ['secondCallArg'])
+
+// New way using CakePHP's trait
+->with(
+ ...self::withConsecutive(['firstCallArg'], ['secondCallArg'])
+)
```
-should be converted to:
+The static `self::withConsecutive()` method is provided via the `Cake\TestSuite\PHPUnitConsecutiveTrait`
+which is automatically included in the base `Cake\TestSuite\TestCase` class.
-``` text
-public static function myProvider(): array
-```
+## Upgrade Checklist
+
+Before upgrading PHPUnit versions, ensure:
+
+1. Your test suite runs without deprecation warnings on your current PHPUnit version
+2. All data providers are `public static` methods
+3. You're using attributes instead of annotations (required for PHPUnit 12)
+4. Mock expectations are only used with `createMock()`, not `createStub()`
+5. Run `vendor/bin/phpunit --migrate-configuration` after upgrading