控制台测试
介绍
除了简化 HTTP 测试外,Laravel 还提供了一个简单的 API 来测试应用程序的自定义控制台命令。
成功/失败预期
首先,让我们探索如何对 Artisan 命令的退出代码进行断言。为此,我们将使用 artisan
方法从我们的测试中调用 Artisan 命令。然后,我们将使用 assertExitCode
方法来断言命令以给定的退出代码完成
test('console command', function () { $this->artisan('inspire')->assertExitCode(0);});
/** * Test a console command. */public function test_console_command(): void{ $this->artisan('inspire')->assertExitCode(0);}
你可以使用 assertNotExitCode
方法来断言该命令没有以给定的退出代码退出
$this->artisan('inspire')->assertNotExitCode(1);
当然,所有终端命令通常在成功时以状态代码 0
退出,而在不成功时以非零退出代码退出。因此,为了方便起见,你可以使用 assertSuccessful
和 assertFailed
断言来断言给定的命令以成功的退出代码退出或没有以成功的退出代码退出
$this->artisan('inspire')->assertSuccessful(); $this->artisan('inspire')->assertFailed();
输入/输出预期
Laravel 允许你使用 expectsQuestion
方法轻松“模拟”控制台命令的用户输入。此外,你可以使用 assertExitCode
和 expectsOutput
方法指定你希望控制台命令输出的退出代码和文本。例如,考虑以下控制台命令
Artisan::command('question', function () { $name = $this->ask('What is your name?'); $language = $this->choice('Which language do you prefer?', [ 'PHP', 'Ruby', 'Python', ]); $this->line('Your name is '.$name.' and you prefer '.$language.'.');});
你可以使用以下测试来测试此命令
test('console command', function () { $this->artisan('question') ->expectsQuestion('What is your name?', 'Taylor Otwell') ->expectsQuestion('Which language do you prefer?', 'PHP') ->expectsOutput('Your name is Taylor Otwell and you prefer PHP.') ->doesntExpectOutput('Your name is Taylor Otwell and you prefer Ruby.') ->assertExitCode(0);});
/** * Test a console command. */public function test_console_command(): void{ $this->artisan('question') ->expectsQuestion('What is your name?', 'Taylor Otwell') ->expectsQuestion('Which language do you prefer?', 'PHP') ->expectsOutput('Your name is Taylor Otwell and you prefer PHP.') ->doesntExpectOutput('Your name is Taylor Otwell and you prefer Ruby.') ->assertExitCode(0);}
如果你正在使用 Laravel Prompts 提供的 search
或 multisearch
函数,则可以使用 expectsSearch
断言来模拟用户的输入、搜索结果和选择
test('console command', function () { $this->artisan('example') ->expectsSearch('What is your name?', search: 'Tay', answers: [ 'Taylor Otwell', 'Taylor Swift', 'Darian Taylor' ], answer: 'Taylor Otwell') ->assertExitCode(0);});
/** * Test a console command. */public function test_console_command(): void{ $this->artisan('example') ->expectsSearch('What is your name?', search: 'Tay', answers: [ 'Taylor Otwell', 'Taylor Swift', 'Darian Taylor' ], answer: 'Taylor Otwell') ->assertExitCode(0);}
你还可以使用 doesntExpectOutput
方法来断言控制台命令没有生成任何输出
test('console command', function () { $this->artisan('example') ->doesntExpectOutput() ->assertExitCode(0);});
/** * Test a console command. */public function test_console_command(): void{ $this->artisan('example') ->doesntExpectOutput() ->assertExitCode(0);}
expectsOutputToContain
和 doesntExpectOutputToContain
方法可用于针对输出的一部分进行断言
test('console command', function () { $this->artisan('example') ->expectsOutputToContain('Taylor') ->assertExitCode(0);});
/** * Test a console command. */public function test_console_command(): void{ $this->artisan('example') ->expectsOutputToContain('Taylor') ->assertExitCode(0);}
确认预期
当编写一个需要以“是”或“否”答案形式确认的命令时,你可以使用 expectsConfirmation
方法
$this->artisan('module:import') ->expectsConfirmation('Do you really wish to run this command?', 'no') ->assertExitCode(1);
表格预期
如果你的命令使用 Artisan 的 table
方法显示信息表格,则为整个表格编写输出预期可能会很麻烦。相反,你可以使用 expectsTable
方法。此方法将表格的标题作为其第一个参数,将表格的数据作为其第二个参数
$this->artisan('users:all') ->expectsTable([ 'ID', 'Email', ], [ ]);
控制台事件
默认情况下,在运行应用程序的测试时,不会调度 Illuminate\Console\Events\CommandStarting
和 Illuminate\Console\Events\CommandFinished
事件。但是,你可以通过将 Illuminate\Foundation\Testing\WithConsoleEvents
特性添加到类中来为给定的测试类启用这些事件
<?php use Illuminate\Foundation\Testing\WithConsoleEvents; uses(WithConsoleEvents::class); // ...
<?php namespace Tests\Feature; use Illuminate\Foundation\Testing\WithConsoleEvents;use Tests\TestCase; class ConsoleEventTest extends TestCase{ use WithConsoleEvents; // ...}