Skip to content

Fixing a bug in testing with Laravel Prompts #505

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

andrey-helldar
Copy link

@andrey-helldar andrey-helldar commented Mar 18, 2025

Description

When testing any function from Laravel Prompts in Unix that accepts a value, an error occurs.

Steps to reproduce

composer create-project --prefer-dist laravel-zero/laravel-zero movie-cli
cd movie-cli

composer require laravel/prompts

./application make:command FooCommand
./application make:test FooTest
// app/Commands/FooCommand.php
<?php

namespace App\Commands;

use Illuminate\Console\Scheduling\Schedule;
use LaravelZero\Framework\Commands\Command;

use function Laravel\Prompts\text;

class FooCommand extends Command
{
    protected $signature = 'foo';

    protected $description = 'Command description';

    public function handle(): void
    {
        $first  = text('First question');

        $this->info('First is ' . $first);
    }
}
// tests/Feature/FooTest.php
<?php

use App\Commands\FooCommand;

it('some', function () {
    test()->artisan(FooCommand::class)
    ->expectsQuestion('First question', 'qwerty')
    ->expectsOutputToContain('First is qwerty')
    ->assertSuccessful();
});
./vendor/bin/pest --filter FooTest

Results

Windows (not wsl)

$ ./vendor/bin/pest --filter FooTest

   PASS  Tests\Feature\FooTest
  ✓ it some                                  0.31s

  Tests:    1 passed (3 assertions)
  Duration: 0.42s

Any non Windows OS (include WSL)

$ ./vendor/bin/pest --filter FooTest


   FAIL  Tests\Feature\FooTest
  ⨯ it some                                                                                                                                                                       2.04s
  ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   FAILED  Tests\Feature\FooTest > it some                                                                                                                        AssertionFailedError
  Question "First question" was not asked.

  at vendor/illuminate/testing/PendingCommand.php:369
    365▕      */
    366▕     protected function verifyExpectations()
    367▕     {
    368▕         if (count($this->test->expectedQuestions)) {
  ➜ 369▕             $this->test->fail('Question "'.Arr::first($this->test->expectedQuestions)[0].'" was not asked.');
    370▕         }
    371▕
    372▕         if (count($this->test->expectedChoices) > 0) {
    373▕             foreach ($this->test->expectedChoices as $question => $answers) {

      +3 vendor frames
  4   tests/Feature/FooTest.php:9


  Tests:    1 failed (4 assertions)
  Duration: 4.11s

Reason

Because:

// config/app.php
return [
    'env' => 'development',
];
Prompt::fallbackWhen(windows_os() || $this->laravel->runningUnitTests());

public function runningUnitTests()
{
    return $this->bound('env') && $this['env'] === 'testing';
}

https://github.com/laravel/framework/blob/12.x/src/Illuminate/Console/Concerns/ConfiguresPrompts.php#L36

@owenvoke
Copy link
Member

I think that development was specifically set as the default value (and we aren't really wanting to use APP_ENV as it means that dotenv will pull this out).

However, this may be something that would be good to add into the base TestCase instead. 🤔

RE your example, I wasn't able to replicate this on macOS (I instead get a warning that no assertions were made), would you be able to provide an example repository?

@andrey-helldar
Copy link
Author

At the time the Issue was created in March 2024, the playback steps were up to date and I was able to get this error several times in a row.

Now I am getting a different error on these steps:

$ ./vendor/bin/pest --filter FooTest

   WARN  Tests\Unit\FooTest
  ! it some → This test did not perform any assertions                                                                   0.29s

  Tests:    1 risky (0 assertions)
  Duration: 0.40s

PHP Fatal error:  Uncaught Illuminate\Contracts\Container\BindingResolutionException: Target [Illuminate\Contracts\Console\Kernel] is not instantiable. in D:\domains\movie-cli\vendor\illuminate\container\Container.php:1216
Stack trace:
#0 D:\domains\movie-cli\vendor\illuminate\container\Container.php(968): Illuminate\Container\Container->notInstantiable('Illuminate\\Cont...')
#1 D:\domains\movie-cli\vendor\illuminate\container\Container.php(832): Illuminate\Container\Container->build('Illuminate\\Cont...')
#2 D:\domains\movie-cli\vendor\laravel-zero\foundation\src\Illuminate\Foundation\Application.php(1084): Illuminate\Container\Container->resolve('Illuminate\\Cont...', Array, true)
#3 D:\domains\movie-cli\vendor\illuminate\container\Container.php(763): Illuminate\Foundation\Application->resolve('Illuminate\\Cont...', Array)
#4 D:\domains\movie-cli\vendor\laravel-zero\foundation\src\Illuminate\Foundation\Application.php(1064): Illuminate\Container\Container->make('Illuminate\\Cont...', Array)
#5 D:\domains\movie-cli\vendor\illuminate\testing\PendingCommand.php(331): Illuminate\Foundation\Application->make('Illuminate\\Cont...')
#6 D:\domains\movie-cli\vendor\illuminate\testing\PendingCommand.php(534): Illuminate\Testing\PendingCommand->run()
#7 [internal function]: Illuminate\Testing\PendingCommand->__destruct()
#8 {main}
  thrown in D:\domains\movie-cli\vendor\illuminate\container\Container.php on line 1216

I need some time to identify the reasons for the failure to run the tests and update the step instructions for reproduction.

@owenvoke
Copy link
Member

For reference, tests that interact with the framework should likely be in Feature (rather than Unit).

@andrey-helldar
Copy link
Author

Feature usually contains tests that interact with the framework through API requests, and Unit usually contains tests that check the operation of any parts of the application “under the hood” (command calls, classes, integrations, etc.).

@owenvoke
Copy link
Member

owenvoke commented Jun 13, 2025

I'm more meaning that in a default Laravel Zero application, the Unit directory won't have access to command calls (or the container) as they require booting the framework (and the Unit directory doesn't use the Tests\TestCase class). However, if you're handling this in your application differently, that's all good. 👍🏻

@andrey-helldar
Copy link
Author

andrey-helldar commented Jun 14, 2025

@owenvoke you can see a repository: https://github.com/andrey-helldar/temp-laravel-zero-with-prompts

git clone git@github.com:andrey-helldar/temp-laravel-zero-with-prompts.git test-prompts && cd test-prompts
composer install
vendor/bin/pest --filter FooTest

I ran into two new problems when updating the playback steps:

Problem 1:

-it('some', fn () => test()->artisan(FooCommand::class)
-    ->expectsQuestion('First question', 'qwerty')
-    ->expectsOutputToContain('First is qwerty')
-    ->assertSuccessful()
-);
+it('some', function () {
+    test()->artisan(FooCommand::class)
+        ->expectsQuestion('First question', 'qwerty')
+        ->expectsOutputToContain('First is qwerty')
+        ->assertSuccessful();
+});

Problem 2:
When running tests, the console “hangs”. In fact, as it turned out, it waits for “there” to press Enter. So we just press Enter.

And then we get an error. There is no such error when running under Windows.

@owenvoke
Copy link
Member

Yes, can replicate the issue with that repository on macOS. 👍🏻 I'll try and look into why it hangs.

@andrey-helldar
Copy link
Author

I've tried it on the following OS:

  • Windows (not WSL) - ok
  • Windows WSL (Ubuntu 24.04) - fail
  • Ubuntu 24.04 - fail

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants