Skip to content

Run raw init test calls with --no-interaction so pest cannot hang on a TTY - #46

Merged
mathiasgrimm merged 1 commit into
mainfrom
fix/init-tests-no-interaction
Aug 2, 2026
Merged

Run raw init test calls with --no-interaction so pest cannot hang on a TTY#46
mathiasgrimm merged 1 commit into
mainfrom
fix/init-tests-no-interaction

Conversation

@mathiasgrimm

Copy link
Copy Markdown
Owner

Problem

vendor/bin/pest hangs indefinitely when run from an interactive terminal, freezing right after InfoCommandTest. A stack sample shows PHP blocked in stream_select inside Symfony's QuestionHelper.

The cause: InitCommandTest runs the command through raw Artisan::call('init'), which inherits interactivity from the suite's stdin. On a TTY, the seed confirm at InitCommand:188 (and the workflow confirm at :261) genuinely waits for keyboard input, while the prompt text is swallowed by the buffered output. The suite just looks frozen.

This never showed in CI, piped runs, or IDE runners because a non-TTY stdin makes Symfony mark the input non-interactive, so confirm() returns its default immediately. The hang is not a regression: v1.3.0 with its exact lockfile (symfony/console 7.4.14) reproduces it identically under a pseudo-TTY. It has been latent since the init command landed in 0f14150 and only bites when pest runs bare in a terminal.

Fix

Pass '--no-interaction' => true at every raw Artisan::call('init') site (34 of them), pinning those tests to the non-interactive shape they already assert. Prompt-answering coverage stays on the $this->artisan() pending-command path, which mocks the question layer and never blocks. A comment at the top of the file records the constraint for future tests.

Verification

  • vendor/bin/pest under a pseudo-TTY with an open, silent stdin (the exact repro that hung forever): 290 passed in 7.69s
  • Plain run: 290 passed
  • pint --test: clean

🤖 Generated with Claude Code

Artisan::call inherits interactivity from the suite's stdin, so running
vendor/bin/pest from a real terminal let the init seed and workflow
confirms render into the captured output and block in stream_select
waiting for an answer nobody could see. Piped and CI runs were unaffected
because Symfony marks a non-TTY stdin non-interactive and confirm()
returns its default.

Pin every raw Artisan::call('init') to the non-interactive shape those
tests already assert. Prompt-answering coverage stays on the artisan()
pending-command path, which mocks the question layer and never blocks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mathiasgrimm
mathiasgrimm merged commit ec55ec4 into main Aug 2, 2026
5 checks passed
@mathiasgrimm
mathiasgrimm deleted the fix/init-tests-no-interaction branch August 4, 2026 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant