Console 測試
簡介
除了簡化 HTTP 測試外,Laravel 還提供了一個簡單的 API 來測試應用程式的自訂命令列指令。
成功 / 失敗預期
首先,讓我們探索如何對 Artisan 命令的退出代碼進行斷言。為了完成此操作,我們將使用 artisan
方法從我們的測試中調用 Artisan 命令。然後,我們將使用 assertExitCode
方法來斷言命令以給定的退出代碼完成
1test('console command', function () {2 $this->artisan('inspire')->assertExitCode(0);3});
1/**2 * Test a console command.3 */4public function test_console_command(): void5{6 $this->artisan('inspire')->assertExitCode(0);7}
您可以使用 assertNotExitCode
方法來斷言命令沒有以給定的退出代碼退出
1$this->artisan('inspire')->assertNotExitCode(1);
當然,所有終端命令通常在成功時以狀態碼 0
退出,而在不成功時以非零退出代碼退出。因此,為了方便起見,您可以利用 assertSuccessful
和 assertFailed
斷言來斷言給定的命令是否以成功的退出代碼退出
1$this->artisan('inspire')->assertSuccessful();2 3$this->artisan('inspire')->assertFailed();
輸入 / 輸出預期
Laravel 允許您使用 expectsQuestion
方法輕鬆「模擬」使用者對控制台命令的輸入。此外,您可以使用 assertExitCode
和 expectsOutput
方法指定您期望控制台命令輸出的退出代碼和文本。例如,考慮以下控制台命令
1Artisan::command('question', function () { 2 $name = $this->ask('What is your name?'); 3 4 $language = $this->choice('Which language do you prefer?', [ 5 'PHP', 6 'Ruby', 7 'Python', 8 ]); 9 10 $this->line('Your name is '.$name.' and you prefer '.$language.'.');11});
您可以使用以下測試來測試此命令
1test('console command', function () {2 $this->artisan('question')3 ->expectsQuestion('What is your name?', 'Taylor Otwell')4 ->expectsQuestion('Which language do you prefer?', 'PHP')5 ->expectsOutput('Your name is Taylor Otwell and you prefer PHP.')6 ->doesntExpectOutput('Your name is Taylor Otwell and you prefer Ruby.')7 ->assertExitCode(0);8});
1/** 2 * Test a console command. 3 */ 4public function test_console_command(): void 5{ 6 $this->artisan('question') 7 ->expectsQuestion('What is your name?', 'Taylor Otwell') 8 ->expectsQuestion('Which language do you prefer?', 'PHP') 9 ->expectsOutput('Your name is Taylor Otwell and you prefer PHP.')10 ->doesntExpectOutput('Your name is Taylor Otwell and you prefer Ruby.')11 ->assertExitCode(0);12}
如果您正在使用 Laravel Prompts 提供的 search
或 multisearch
函數,則可以使用 expectsSearch
斷言來模擬使用者的輸入、搜尋結果和選擇
1test('console command', function () {2 $this->artisan('example')3 ->expectsSearch('What is your name?', search: 'Tay', answers: [4 'Taylor Otwell',5 'Taylor Swift',6 'Darian Taylor'7 ], answer: 'Taylor Otwell')8 ->assertExitCode(0);9});
1/** 2 * Test a console command. 3 */ 4public function test_console_command(): void 5{ 6 $this->artisan('example') 7 ->expectsSearch('What is your name?', search: 'Tay', answers: [ 8 'Taylor Otwell', 9 'Taylor Swift',10 'Darian Taylor'11 ], answer: 'Taylor Otwell')12 ->assertExitCode(0);13}
您也可以使用 doesntExpectOutput
方法斷言控制台命令未產生任何輸出
1test('console command', function () {2 $this->artisan('example')3 ->doesntExpectOutput()4 ->assertExitCode(0);5});
1/**2 * Test a console command.3 */4public function test_console_command(): void5{6 $this->artisan('example')7 ->doesntExpectOutput()8 ->assertExitCode(0);9}
expectsOutputToContain
和 doesntExpectOutputToContain
方法可用於針對輸出的一部分進行斷言
1test('console command', function () {2 $this->artisan('example')3 ->expectsOutputToContain('Taylor')4 ->assertExitCode(0);5});
1/**2 * Test a console command.3 */4public function test_console_command(): void5{6 $this->artisan('example')7 ->expectsOutputToContain('Taylor')8 ->assertExitCode(0);9}
確認預期
當編寫需要以「是」或「否」答案形式進行確認的命令時,您可以使用 expectsConfirmation
方法
1$this->artisan('module:import')2 ->expectsConfirmation('Do you really wish to run this command?', 'no')3 ->assertExitCode(1);
表格預期
如果您的命令使用 Artisan 的 table
方法顯示資訊表格,則為整個表格編寫輸出預期可能會很麻煩。相反,您可以使用 expectsTable
方法。此方法接受表格的標頭作為其第一個參數,表格的資料作為其第二個參數
1$this->artisan('users:all')2 ->expectsTable([3 'ID',4 'Email',5 ], [8 ]);
Console 事件
預設情況下,在執行應用程式的測試時,不會派發 Illuminate\Console\Events\CommandStarting
和 Illuminate\Console\Events\CommandFinished
事件。但是,您可以通過將 Illuminate\Foundation\Testing\WithConsoleEvents
trait 添加到類別中,為給定的測試類別啟用這些事件
1<?php2 3use Illuminate\Foundation\Testing\WithConsoleEvents;4 5uses(WithConsoleEvents::class);6 7// ...
1<?php 2 3namespace Tests\Feature; 4 5use Illuminate\Foundation\Testing\WithConsoleEvents; 6use Tests\TestCase; 7 8class ConsoleEventTest extends TestCase 9{10 use WithConsoleEvents;11 12 // ...13}