PHPUnit: Test Was Run in a Separate Process and Crashed in CI
PHPUnit can run a test in an isolated child process (via @runInSeparateProcess or process isolation). The child re-bootstraps and serializes global state into it. When bootstrap differs, constants are redefined, or state is non-serializable, the child crashes and the test errors out - often only in CI.
What this error means
A test using @runInSeparateProcess errors with output about the separate process, a serialization failure, or "Cannot redeclare"/constant-already-defined in the child. The same test passes when not isolated.
1) App\Tests\PaymentTest::testWebhook
This test was run in a separate process and the process crashed.
PHP Fatal error: Constant APP_BOOTED already definedCommon causes
preserveGlobalState re-runs bootstrap with side effects
With global state preserved, the child re-includes bootstrap that defines constants or boots a framework again, hitting "already defined"/"cannot redeclare".
Non-serializable state cannot cross the process boundary
Closures, resources, or objects with live connections cannot be serialized into the child, so the isolated run crashes.
How to fix it
Disable global state preservation for the isolated test
Tell PHPUnit not to serialize global state into the child so bootstrap is not double-applied.
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testWebhook(): void { /* ... */ }Guard bootstrap against re-definition
Make constant/define and framework-boot idempotent so a second include in the child is safe.
if (!defined('APP_BOOTED')) {
define('APP_BOOTED', true);
}Avoid isolation unless it is truly needed
- Use @runInSeparateProcess only for tests that mutate global/static state.
- Keep non-serializable resources out of preserved global state.
- Confirm the same bootstrap is used for the parent and child processes.
How to prevent it
- Reserve process isolation for tests that genuinely need a clean process.
- Pair @runInSeparateProcess with @preserveGlobalState disabled by default.
- Make bootstrap idempotent (guard defines and framework boot).