翻譯進度
39.62% 已翻譯
更新時間:
2024年6月30日 上午8:17:00 [世界標準時間]
翻譯人員:
幫我們翻譯此頁

主控台測試

簡介

在 Laravel 中除了能簡單地測試 HTTP 外,Laravel 還提供了一個簡單的 API 來測試專案的自訂主控台指令

預期成功 / 失敗

若要開始,讓我們先來看看如何針對 Artisan 指令的結束代碼 (Exit Code) 作 Assertion (判斷提示)。為此,我們將使用 artisan 方法來在測試中叫用 Artisan 指令。接著,我們會使用 assertExitCode 方法來判斷該指令是否以給定的結束代碼完成:

1test('console command', function () {
2 $this->artisan('inspire')->assertExitCode(0);
3});
1test('console command', function () {
2 $this->artisan('inspire')->assertExitCode(0);
3});
1/**
2 * Test a console command.
3 */
4public function test_console_command(): void
5{
6 $this->artisan('inspire')->assertExitCode(0);
7}
1/**
2 * Test a console command.
3 */
4public function test_console_command(): void
5{
6 $this->artisan('inspire')->assertExitCode(0);
7}

可以使用 assertNotExitCode 方法來判斷該指令是否不以給定結束代碼終止:

1$this->artisan('inspire')->assertNotExitCode(1);
1$this->artisan('inspire')->assertNotExitCode(1);

當然,一般來說,所有以狀態碼 0 結束的終端機指令通常都代表成功,而非 0 的結束代碼則代表不成功。因此,為了方便起見,我們可以使用 assertSuccessfulassertFailed Assertion 來判斷給定的指令是否以成功結束碼退出:

1$this->artisan('inspire')->assertSuccessful();
2 
3$this->artisan('inspire')->assertFailed();
1$this->artisan('inspire')->assertSuccessful();
2 
3$this->artisan('inspire')->assertFailed();

預期的輸入/輸出

Laravel 能讓你輕鬆地通過 expectsQuestion 方法來為主控台指令「模擬(Mock)」使用者輸入。此外,還可以通過 assertExitCodeexpectsOutput 來指定主控台預期的結束代碼與輸出文字。舉例來說,假設有下列主控台指令:

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});
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});

You may test this command with the following test:

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});
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}
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}

If you are utilizing the search or multisearch functions provided by Laravel Prompts, you may use the expectsSearch assertion to mock the user's input, search results, and selection:

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});
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}
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}

You may also assert that a console command does not generate any output using the doesntExpectOutput method:

1test('console command', function () {
2 $this->artisan('example')
3 ->doesntExpectOutput()
4 ->assertExitCode(0);
5});
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(): void
5{
6 $this->artisan('example')
7 ->doesntExpectOutput()
8 ->assertExitCode(0);
9}
1/**
2 * Test a console command.
3 */
4public function test_console_command(): void
5{
6 $this->artisan('example')
7 ->doesntExpectOutput()
8 ->assertExitCode(0);
9}

The expectsOutputToContain and doesntExpectOutputToContain methods may be used to make assertions against a portion of the output:

1test('console command', function () {
2 $this->artisan('example')
3 ->expectsOutputToContain('Taylor')
4 ->assertExitCode(0);
5});
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(): void
5{
6 $this->artisan('example')
7 ->expectsOutputToContain('Taylor')
8 ->assertExitCode(0);
9}
1/**
2 * Test a console command.
3 */
4public function test_console_command(): void
5{
6 $this->artisan('example')
7 ->expectsOutputToContain('Taylor')
8 ->assertExitCode(0);
9}

預期確認

當撰寫預期答案為「yes」或「no」確認的指令時,可以使用 expectsConfirmation 方法:

1$this->artisan('module:import')
2 ->expectsConfirmation('Do you really wish to run this command?', 'no')
3 ->assertExitCode(1);
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 ]);
1$this->artisan('users:all')
2 ->expectsTable([
3 'ID',
4 'Email',
5 ], [
8 ]);

Console 事件

預設情況下,在執行測試時,不會分派 Illuminate\Console\Events\CommandStartingIlluminate\Console\Events\CommandFinished 事件。不過,只要在測試類別中加入 Illuminate\Foundation\Testing\WithConsoleEvents Trait,就可以啟用這些測試:

1<?php
2 
3use Illuminate\Foundation\Testing\WithConsoleEvents;
4 
5uses(WithConsoleEvents::class);
6 
7// ...
1<?php
2 
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}
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}
翻譯進度
39.62% 已翻譯
更新時間:
2024年6月30日 上午8:17:00 [世界標準時間]
翻譯人員:
幫我們翻譯此頁

留言

尚無留言

“Laravel” is a Trademark of Taylor Otwell.
The source documentation is released under MIT license. See laravel/docs on GitHub for details.
The translated documentations are released under MIT license. See cornch/laravel-docs-l10n on GitHub for details.