test: rewind output-buffer stack in tearDown to clear risky warnings

PHPUnit was flagging 18-19 tests per run as "did not close its own
output buffers". The leaks come from Blade — a @once block, a @push,
or a view that throws mid-render leaves ob_start()'ed buffers open
when the test method returns.

Capture ob_get_level() in setUp, then unwind back to that depth in
tearDown. Suite is now green AND clean: 46/46, 0 failures, 0 risky.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
ghassanandClaude Opus 4.7 committed 2026-10-21 11:58:12 +03:00
1 parent 0e8bcfd47b
commit b7f3f6989b
1 file changed
+22
+22
View File
@@ -8,6 +8,14 @@ abstract class TestCase extends BaseTestCase
{ {
use CreatesApplication; use CreatesApplication;
/** Output-buffer depth captured before each test, so tearDown can
* rewind back to it instead of leaving dangling buffers that PHPUnit
* reports as "Test code or tested code did not close its own output
* buffers". The depth leaks when a view throws mid-render — common
* with Blade's compiled files when a feature test exercises an
* error path. */
private int $preTestObLevel = 0;
/** /**
* Belt-and-braces guard against a repeat of the 2026-10-21 incident, where * Belt-and-braces guard against a repeat of the 2026-10-21 incident, where
* a test with the RefreshDatabase trait ran migrate:fresh against the * a test with the RefreshDatabase trait ran migrate:fresh against the
@@ -21,6 +29,20 @@ abstract class TestCase extends BaseTestCase
{ {
parent::setUp(); parent::setUp();
$this->assertSafeTestDatabase(); $this->assertSafeTestDatabase();
$this->preTestObLevel = ob_get_level();
}
protected function tearDown(): void
{
// Collapse any output buffers the test (or Blade view it rendered)
// left open. Without this, each view()->render() call that touches
// a Blade partial with its own @once / @push block can leave the
// buffer stack one level deep — PHPUnit reports every one of those
// tests as "risky".
while (ob_get_level() > $this->preTestObLevel) {
ob_end_clean();
}
parent::tearDown();
} }
private function assertSafeTestDatabase(): void private function assertSafeTestDatabase(): void