Thank you for all of the work you have done on Clockwork. I recently ran into an issue getting data while running pest tests. Below is a summary from Claude as to why I am not seeing anything.
============
Environment
- itsgoingd/clockwork v5.3.5
- phpunit/phpunit 12.5.33
- pestphp/pest v4
- laravel/framework v12
- PHP 8.3.32
Config
- config/clockwork.php: tests.collect → true (via CLOCKWORK_TESTS_COLLECT=true)
- CLOCKWORK_ENABLE=true
- phpunit.xml has the extension registered correctly:
Symptom
No test metadata is ever written to storage/clockwork when running tests via php artisan test, vendor/bin/pest, or vendor/bin/phpunit, despite tests.collect being enabled and no errors being reported.
Root cause (confirmed via temporary debug logging in ClockworkExtension.php)
- ClockworkExtension::bootstrap() runs, and subscribers are registered correctly.
- PassedSubscriber/FailedSubscriber/etc. do fire recordTest() for every test.
- Inside recordTest(), resolveApp($testCase) returns null on every single test, so the method returns early before ever calling isCollectingTests() or storeRequest().
- resolveApp() (in Clockwork/Support/Laravel/Tests/ClockworkExtension.php) reflects on the test case's $app property:
protected static function resolveApp($testCase)
{
$reflectionClass = new \ReflectionClass($testCase);
if ($reflectionClass->hasProperty('app')) {
$reflectionProperty = $reflectionClass->getProperty('app');
$reflectionProperty->setAccessible(true);
if ($reflectionProperty->getValue($testCase)) {
return $reflectionProperty->getValue($testCase);
}
} elseif (method_exists($testCase, 'createApplication')) {
return $testCase->createApplication();
}
}
- Laravel's Illuminate\Foundation\Testing\Concerns\InteractsWithTestCaseLifecycle::tearDownTheTestEnvironment() sets $this->app = null inside tearDown().
- In PHPUnit 12's event system, tearDown() runs before the Test\Passed (and Failed/Skipped/Errored) event is emitted (see vendor/phpunit/phpunit/src/Framework/TestCase.php around lines 621–659 — fixture teardown happens, then $emitter->testPassed(...) is dispatched).
- So by the time Clockwork's subscriber runs resolveApp(), $app has already been nulled by Laravel's own teardown, and the property check at line 102 (if ($reflectionProperty->getValue($testCase))) fails, causing a silent no-op with no error or log output.
Why this looks new: the CHANGELOG for 5.3.5 lists support for "PHPUnit 11 and Pest 3." This suggests the event-timing relative to tearDown() changed (or was already like this but tolerated differently) by PHPUnit 12, breaking the $app-via-reflection approach for PHPUnit 12 / Pest 4.
Suggested fix direction
- Capture the app instance earlier in the test lifecycle (e.g. via a PreparedSubscriber or Event\Test\Started hook, before tearDown() runs) and cache it per-test, rather than reflecting on the (possibly torn-down) test case object inside Passed/Failed/Skipped handlers.
- Alternatively, fall back to Illuminate\Foundation\Application::getInstance() if the reflected $app property is null, if the static instance is still available at that point.
Repro: any Laravel 12 + Pest 4 + PHPUnit 12 project with itsgoingd/clockwork 5.3.5, tests.collect enabled, and the extension registered in phpunit.xml — no test metadata files are ever created in storage/clockwork, and no error/warning is surfaced.
Thank you for all of the work you have done on Clockwork. I recently ran into an issue getting data while running pest tests. Below is a summary from Claude as to why I am not seeing anything.
============
Environment
Config
Symptom
No test metadata is ever written to storage/clockwork when running tests via php artisan test, vendor/bin/pest, or vendor/bin/phpunit, despite tests.collect being enabled and no errors being reported.
Root cause (confirmed via temporary debug logging in ClockworkExtension.php)
protected static function resolveApp($testCase)
{
$reflectionClass = new \ReflectionClass($testCase);
if ($reflectionClass->hasProperty('app')) {
$reflectionProperty = $reflectionClass->getProperty('app');
$reflectionProperty->setAccessible(true);
if ($reflectionProperty->getValue($testCase)) {
return $reflectionProperty->getValue($testCase);
}
} elseif (method_exists($testCase, 'createApplication')) {
return $testCase->createApplication();
}
}
Why this looks new: the CHANGELOG for 5.3.5 lists support for "PHPUnit 11 and Pest 3." This suggests the event-timing relative to tearDown() changed (or was already like this but tolerated differently) by PHPUnit 12, breaking the $app-via-reflection approach for PHPUnit 12 / Pest 4.
Suggested fix direction
Repro: any Laravel 12 + Pest 4 + PHPUnit 12 project with itsgoingd/clockwork 5.3.5, tests.collect enabled, and the extension registered in phpunit.xml — no test metadata files are ever created in storage/clockwork, and no error/warning is surfaced.