From b7f3f6989b07e23479812cc77e387b3752cfd0db Mon Sep 17 00:00:00 2001 From: ghassan Date: Wed, 21 Oct 2026 11:58:12 +0300 Subject: [PATCH] test: rewind output-buffer stack in tearDown to clear risky warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- tests/TestCase.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/TestCase.php b/tests/TestCase.php index dac81e1..d9b42d1 100755 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -8,6 +8,14 @@ abstract class TestCase extends BaseTestCase { 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 * a test with the RefreshDatabase trait ran migrate:fresh against the @@ -21,6 +29,20 @@ abstract class TestCase extends BaseTestCase { parent::setUp(); $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