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

Process

簡介

Laravel provides an expressive, minimal API around the Symfony Process component, allowing you to conveniently invoke external processes from your Laravel application. Laravel's process features are focused on the most common use cases and a wonderful developer experience.

呼叫 Process

若要呼叫 Process,可以使用 Process Facade 提供的 runstart 方法。run 方法會呼叫 Process,並等待該 Process 執行完畢。而 start 方法會以非同步方式執行 Process。我們將在此文件中詳細討論這兩種方法。首先,我們先來看看如何執行一個基本的同步 Process 並取得其執行結果:

1use Illuminate\Support\Facades\Process;
2 
3$result = Process::run('ls -la');
4 
5return $result->output();
1use Illuminate\Support\Facades\Process;
2 
3$result = Process::run('ls -la');
4 
5return $result->output();

當然,run 方法回傳的 Illuminate\Contracts\Process\ProcessResult 實體還包含了多種可用於檢查 Process 執行結果的實用方法:

1$result = Process::run('ls -la');
2 
3$result->successful();
4$result->failed();
5$result->exitCode();
6$result->output();
7$result->errorOutput();
1$result = Process::run('ls -la');
2 
3$result->successful();
4$result->failed();
5$result->exitCode();
6$result->output();
7$result->errorOutput();

擲回 Exception

若在取得 Process 執行結果後,希望能讓終止代碼 (Exit Code) 大於 0 的狀況 (表示執行失敗) 擲回 Illuminate\Process\Exceptions\ProcessFailedException,可以使用 throwthrowIf 方法。若 Process 並未執行失敗,則會回傳 Process 執行結果的實體:

1$result = Process::run('ls -la')->throw();
2 
3$result = Process::run('ls -la')->throwIf($condition);
1$result = Process::run('ls -la')->throw();
2 
3$result = Process::run('ls -la')->throwIf($condition);

Process 選項

當然,你可能會需要在呼叫 Process 前自訂該 Process 的行為。在 Laravel 中,可以調整許多 Process 的功能,例如工作目錄 (Working Directory)、逾時與環境變數等。

工作目錄路徑

可以使用 path 方法來指定 Process 的工作目錄。若未呼叫此方法,則該 Process 會繼承目前執行 PHP Script 的工作目錄:

1$result = Process::path(__DIR__)->run('ls -la');
1$result = Process::path(__DIR__)->run('ls -la');

輸入

可以通過 input 方法來以「標準輸入 (Standard Input)」提供輸入給 Process:

1$result = Process::input('Hello World')->run('cat');
1$result = Process::input('Hello World')->run('cat');

逾時

預設情況下,Process 會在執行超過 60 秒後擲回 Illuminate\Process\Exceptions\ProcessTimedOutException 實體。不過,可以使用 timeout 方法來自定此行為:

1$result = Process::timeout(120)->run('bash import.sh');
1$result = Process::timeout(120)->run('bash import.sh');

或者,若要完全禁用 Process 的逾時,可以呼叫 forever 方法:

1$result = Process::forever()->run('bash import.sh');
1$result = Process::forever()->run('bash import.sh');

idleTimeout 方法可用來指定 Process 在不回傳任何輸出下可執行的最大秒數:

1$result = Process::timeout(60)->idleTimeout(30)->run('bash import.sh');
1$result = Process::timeout(60)->idleTimeout(30)->run('bash import.sh');

環境變數

可以使用 env 方法來提供環境變數給 Process。被呼叫的 Process 也會繼承在系統中所定義的所有環境變數:

1$result = Process::forever()
2 ->env(['IMPORT_PATH' => __DIR__])
3 ->run('bash import.sh');
1$result = Process::forever()
2 ->env(['IMPORT_PATH' => __DIR__])
3 ->run('bash import.sh');

若想從呼叫的 Process 中移除繼承的環境變數,可以提供一個值為 false 的環境變數:

1$result = Process::forever()
2 ->env(['LOAD_PATH' => false])
3 ->run('bash import.sh');
1$result = Process::forever()
2 ->env(['LOAD_PATH' => false])
3 ->run('bash import.sh');

TTY 模式

tty 方法可用來在 Process 上啟用 TTY 模式。TTY 模式會將 Process 的 Input 與 Output 連結到你的程式的 Input 與 Output,讓你的 Process 能打開如 Vim 或 Nano 之類的 Process:

1Process::forever()->tty()->run('vim');
1Process::forever()->tty()->run('vim');

Process 的輸出

剛才提到過,可以使用 output (stdout) 與 errorOutput (stderr) 方法來在 Process 結果上取得 Process 的輸出:

1use Illuminate\Support\Facades\Process;
2 
3$result = Process::run('ls -la');
4 
5echo $result->output();
6echo $result->errorOutput();
1use Illuminate\Support\Facades\Process;
2 
3$result = Process::run('ls -la');
4 
5echo $result->output();
6echo $result->errorOutput();

不過,也可以在呼叫 run 方法時傳入一個 Closure 作為第二個引數來即時取得輸出。該 Closure 會收到兩個引數:輸出的「類型 (Type)」(stdoutstderr) 與輸出字串本身:

1$result = Process::run('ls -la', function (string $type, string $output) {
2 echo $output;
3});
1$result = Process::run('ls -la', function (string $type, string $output) {
2 echo $output;
3});

Laravel 也提供了 seeInOutputseeInErrorOutput 方法。通過這兩個方法,就可以方便地判斷給定的字串是否包含在該 Process 的輸出中:

1if (Process::run('ls -la')->seeInOutput('laravel')) {
2 // ...
3}
1if (Process::run('ls -la')->seeInOutput('laravel')) {
2 // ...
3}

關閉 Process 的輸出

若 Process 會寫入大量不必要的輸出,可以完全關閉取得輸出來減少記憶體使用。若要關閉取得輸出,請在建構 Process 時呼叫 quietly 方法:

1use Illuminate\Support\Facades\Process;
2 
3$result = Process::quietly()->run('bash import.sh');
1use Illuminate\Support\Facades\Process;
2 
3$result = Process::quietly()->run('bash import.sh');

管道

有時候,我們可能會想使用某個 Process 的輸出來作為另一個 Process 的輸入。這個動作我們一般會說是把 Process 的輸出「Pipe」到另一個 Process。Process Facade 提供的 pipe 方法能讓我們輕鬆進行此動作。pipe 方法會同步執行被 Pipe 的Process,並回傳管道中最後一個 Process 的結果:

1use Illuminate\Process\Pipe;
2use Illuminate\Support\Facades\Process;
3 
4$result = Process::pipe(function (Pipe $pipe) {
5 $pipe->command('cat example.txt');
6 $pipe->command('grep -i "laravel"');
7});
8 
9if ($result->successful()) {
10 // ...
11}
1use Illuminate\Process\Pipe;
2use Illuminate\Support\Facades\Process;
3 
4$result = Process::pipe(function (Pipe $pipe) {
5 $pipe->command('cat example.txt');
6 $pipe->command('grep -i "laravel"');
7});
8 
9if ($result->successful()) {
10 // ...
11}

若不需要為組成管道的個別 Process 進行自訂,則只需要傳入一組指令字串的陣列給 pipe 方法即可:

1$result = Process::pipe([
2 'cat example.txt',
3 'grep -i "laravel"',
4]);
1$result = Process::pipe([
2 'cat example.txt',
3 'grep -i "laravel"',
4]);

可以在呼叫 pipe 方法時傳入一個 Closure 作為第二個引數來即時取得輸出。該 Closure 會收到兩個引數:輸出的「類型 (Type)」(stdoutstderr) 與輸出字串本身:

1$result = Process::pipe(function (Pipe $pipe) {
2 $pipe->command('cat example.txt');
3 $pipe->command('grep -i "laravel"');
4}, function (string $type, string $output) {
5 echo $output;
6});
1$result = Process::pipe(function (Pipe $pipe) {
2 $pipe->command('cat example.txt');
3 $pipe->command('grep -i "laravel"');
4}, function (string $type, string $output) {
5 echo $output;
6});

Laravel 可讓你使用 as 方法來為管道中的各個 Process 指派一個字串索引鍵。該索引鍵也會傳入提供給 pipe 方法的輸出 Closure,讓你能判斷輸出屬於哪個 Process:

1$result = Process::pipe(function (Pipe $pipe) {
2 $pipe->as('first')->command('cat example.txt');
3 $pipe->as('second')->command('grep -i "laravel"');
4})->start(function (string $type, string $output, string $key) {
5 // ...
6});
1$result = Process::pipe(function (Pipe $pipe) {
2 $pipe->as('first')->command('cat example.txt');
3 $pipe->as('second')->command('grep -i "laravel"');
4})->start(function (string $type, string $output, string $key) {
5 // ...
6});

非同步的 Process

run 方法會同步呼叫 Process,而 start 方法可用來非同步地呼叫 Process。這樣一來,你的程式就可以繼續執行其他任務,並讓 Process 在背景執行。Process 被呼叫後,可以使用 running 方法來判斷該 Process 是否還在執行:

1$process = Process::timeout(120)->start('bash import.sh');
2 
3while ($process->running()) {
4 // ...
5}
6 
7$result = $process->wait();
1$process = Process::timeout(120)->start('bash import.sh');
2 
3while ($process->running()) {
4 // ...
5}
6 
7$result = $process->wait();

讀者可能已經注意到,可以通過呼叫 wait 方法來等待 Process 完成執行,然後再取得 Process 的結果實體:

1$process = Process::timeout(120)->start('bash import.sh');
2 
3// ...
4 
5$result = $process->wait();
1$process = Process::timeout(120)->start('bash import.sh');
2 
3// ...
4 
5$result = $process->wait();

Process IDs and Signals

id 方法可用來取得正在執行的 Process 由作業系統指派的 Process ID:

1$process = Process::start('bash import.sh');
2 
3return $process->id();
1$process = Process::start('bash import.sh');
2 
3return $process->id();

可以使用 signal 方法來向正在執行的 Process 傳送「訊號 (Signal)」。請參考《PHP 說明文件》以瞭解預先定義的 Signal 常數列表:

1$process->signal(SIGUSR2);
1$process->signal(SIGUSR2);

非同步 Process 的輸出

當非同步 Process 正在執行時,可以使用 outputerrorOutput 方法來取得該 Process 目前的完整輸出。而 latestOutputlatestErrorOutput 可用來存取自從上一次取得輸出後該 Process 所產生的最新輸出:

1$process = Process::timeout(120)->start('bash import.sh');
2 
3while ($process->running()) {
4 echo $process->latestOutput();
5 echo $process->latestErrorOutput();
6 
7 sleep(1);
8}
1$process = Process::timeout(120)->start('bash import.sh');
2 
3while ($process->running()) {
4 echo $process->latestOutput();
5 echo $process->latestErrorOutput();
6 
7 sleep(1);
8}

run 方法類似,start 方法也可以在呼叫時傳入一個 Closure 作為第二個引數來即時取得輸出。該 Closure 會收到兩個引數:輸出的「類型 (Type)」(stdoutstderr) 與輸出字串本身:

1$process = Process::start('bash import.sh', function (string $type, string $output) {
2 echo $output;
3});
4 
5$result = $process->wait();
1$process = Process::start('bash import.sh', function (string $type, string $output) {
2 echo $output;
3});
4 
5$result = $process->wait();

併行的 Process

Laravel 也讓管理平行的、非同步的 Process 集區 (Pool) 變的非常容易,讓你能輕鬆的同步執行多個任務。若要執行非同步 Process 集區,請執行 pool 方法。請傳入一個 Closure 給 pool 方法,該 Closure 會收到 Illumiante\Process\Pool 的實體。

在該 Closure 中,可以定義屬於該集區的 Process。使用 start 方法開始 Process 集區後,可以使用 running 方法來存取一組包含正在執行的 Process 的 Collection

1use Illuminate\Process\Pool;
2use Illuminate\Support\Facades\Process;
3 
4$pool = Process::pool(function (Pool $pool) {
5 $pool->path(__DIR__)->command('bash import-1.sh');
6 $pool->path(__DIR__)->command('bash import-2.sh');
7 $pool->path(__DIR__)->command('bash import-3.sh');
8})->start(function (string $type, string $output, int $key) {
9 // ...
10});
11 
12while ($pool->running()->isNotEmpty()) {
13 // ...
14}
15 
16$results = $pool->wait();
1use Illuminate\Process\Pool;
2use Illuminate\Support\Facades\Process;
3 
4$pool = Process::pool(function (Pool $pool) {
5 $pool->path(__DIR__)->command('bash import-1.sh');
6 $pool->path(__DIR__)->command('bash import-2.sh');
7 $pool->path(__DIR__)->command('bash import-3.sh');
8})->start(function (string $type, string $output, int $key) {
9 // ...
10});
11 
12while ($pool->running()->isNotEmpty()) {
13 // ...
14}
15 
16$results = $pool->wait();

就像這樣,可以使用 wait 方法來等待集區 Process 完成執行並解析這些 Process 的執行結果。wait 方法會回傳一個可使用陣列存取的物件 (Array Accessible Object),讓你能使用其索引鍵來存取集區中各個 Process 的 Process 執行結果實體:

1$results = $pool->wait();
2 
3echo $results[0]->output();
1$results = $pool->wait();
2 
3echo $results[0]->output();

或者,也可以使用方便的 concurrently 方法來開始一組非同步 Process 集區,並馬上開始等待其執行結果。當與 PHP 的陣列解構功能搭配使用時,使用此方法就可取得富含表達性的語法:

1[$first, $second, $third] = Process::concurrently(function (Pool $pool) {
2 $pool->path(__DIR__)->command('ls -la');
3 $pool->path(app_path())->command('ls -la');
4 $pool->path(storage_path())->command('ls -la');
5});
6 
7echo $first->output();
1[$first, $second, $third] = Process::concurrently(function (Pool $pool) {
2 $pool->path(__DIR__)->command('ls -la');
3 $pool->path(app_path())->command('ls -la');
4 $pool->path(storage_path())->command('ls -la');
5});
6 
7echo $first->output();

命名的 Pool Process

使用數字索引鍵來存取 Process 集區並不是很有表達性。因此,Laravel 可讓你使用 as 方法來為集區中的各個 Process 指派一個字串索引鍵。該索引鍵也會傳入提供給 start 方法的 Closure,讓你能判斷輸出屬於哪個 Process:

1$pool = Process::pool(function (Pool $pool) {
2 $pool->as('first')->command('bash import-1.sh');
3 $pool->as('second')->command('bash import-2.sh');
4 $pool->as('third')->command('bash import-3.sh');
5})->start(function (string $type, string $output, string $key) {
6 // ...
7});
8 
9$results = $pool->wait();
10 
11return $results['first']->output();
1$pool = Process::pool(function (Pool $pool) {
2 $pool->as('first')->command('bash import-1.sh');
3 $pool->as('second')->command('bash import-2.sh');
4 $pool->as('third')->command('bash import-3.sh');
5})->start(function (string $type, string $output, string $key) {
6 // ...
7});
8 
9$results = $pool->wait();
10 
11return $results['first']->output();

Pool Process IDs and Signals

由於 Process 集區的 running 方法提供了一組包含集區中所有已呼叫 Process 的 Collection,因此你可以輕鬆地存取集區中相應的 Process ID:

1$processIds = $pool->running()->each->id();
1$processIds = $pool->running()->each->id();

而且,也可以在 Process 集區上使用 signal 方法來方便地傳送 Signal 給集區中的每一個 Process:

1$pool->signal(SIGUSR2);
1$pool->signal(SIGUSR2);

測試

許多 Laravel 的服務都提供了能讓你輕鬆且表達性地撰寫測試的方法,而 Laravel 的 Process 服務也不例外。使用 Process Facade 的 fake 方法,能讓你指定要 Laravel 在執行 Process 時回傳一組模擬的執行結果。

模擬 Process

若要瞭解 Laravel 中模擬 Process 的功能,我們先來想像有個 Route 會呼叫一個 Process:

1use Illuminate\Support\Facades\Process;
2use Illuminate\Support\Facades\Route;
3 
4Route::get('/import', function () {
5 Process::run('bash import.sh');
6 
7 return 'Import complete!';
8});
1use Illuminate\Support\Facades\Process;
2use Illuminate\Support\Facades\Route;
3 
4Route::get('/import', function () {
5 Process::run('bash import.sh');
6 
7 return 'Import complete!';
8});

在測試此 Route 時,我們可以不帶任何引數呼叫 Process Facade 上的 fake 方法,讓 Laravel 在每一個被呼叫的 Process 上回傳一組模擬的成功 Process 執行結果。此外,我們還可以 Assert 判斷給定的 Process 是否已執行:

1<?php
2 
3use Illuminate\Process\PendingProcess;
4use Illuminate\Contracts\Process\ProcessResult;
5use Illuminate\Support\Facades\Process;
6 
7test('process is invoked', function () {
8 Process::fake();
9 
10 $response = $this->get('/import');
11 
12 // Simple process assertion...
13 Process::assertRan('bash import.sh');
14 
15 // Or, inspecting the process configuration...
16 Process::assertRan(function (PendingProcess $process, ProcessResult $result) {
17 return $process->command === 'bash import.sh' &&
18 $process->timeout === 60;
19 });
20});
1<?php
2 
3use Illuminate\Process\PendingProcess;
4use Illuminate\Contracts\Process\ProcessResult;
5use Illuminate\Support\Facades\Process;
6 
7test('process is invoked', function () {
8 Process::fake();
9 
10 $response = $this->get('/import');
11 
12 // Simple process assertion...
13 Process::assertRan('bash import.sh');
14 
15 // Or, inspecting the process configuration...
16 Process::assertRan(function (PendingProcess $process, ProcessResult $result) {
17 return $process->command === 'bash import.sh' &&
18 $process->timeout === 60;
19 });
20});
1<?php
2 
3namespace Tests\Feature;
4 
5use Illuminate\Process\PendingProcess;
6use Illuminate\Contracts\Process\ProcessResult;
7use Illuminate\Support\Facades\Process;
8use Tests\TestCase;
9 
10class ExampleTest extends TestCase
11{
12 public function test_process_is_invoked(): void
13 {
14 Process::fake();
15 
16 $response = $this->get('/import');
17 
18 // Simple process assertion...
19 Process::assertRan('bash import.sh');
20 
21 // Or, inspecting the process configuration...
22 Process::assertRan(function (PendingProcess $process, ProcessResult $result) {
23 return $process->command === 'bash import.sh' &&
24 $process->timeout === 60;
25 });
26 }
27}
1<?php
2 
3namespace Tests\Feature;
4 
5use Illuminate\Process\PendingProcess;
6use Illuminate\Contracts\Process\ProcessResult;
7use Illuminate\Support\Facades\Process;
8use Tests\TestCase;
9 
10class ExampleTest extends TestCase
11{
12 public function test_process_is_invoked(): void
13 {
14 Process::fake();
15 
16 $response = $this->get('/import');
17 
18 // Simple process assertion...
19 Process::assertRan('bash import.sh');
20 
21 // Or, inspecting the process configuration...
22 Process::assertRan(function (PendingProcess $process, ProcessResult $result) {
23 return $process->command === 'bash import.sh' &&
24 $process->timeout === 60;
25 });
26 }
27}

剛才也提到過,在 Process Facade 上呼叫 fake 方法會讓 Laravel 為每個 Process 回傳沒有輸出的 Process 執行結果。不過,你可以使用 Process Facade 的 result 方法來輕鬆地指定模擬 Process 的輸出與結束代碼 (Exit Code):

1Process::fake([
2 '*' => Process::result(
3 output: 'Test output',
4 errorOutput: 'Test error output',
5 exitCode: 1,
6 ),
7]);
1Process::fake([
2 '*' => Process::result(
3 output: 'Test output',
4 errorOutput: 'Test error output',
5 exitCode: 1,
6 ),
7]);

模擬特定的 Process

讀者可能已經在前一個例子中注意到,通過 Process Facade,就可以通過傳入一組陣列給 fake 方法來指定各個 Process 的模擬執行結果。

陣列的索引鍵代表要模擬的指令格式,以及其相應的執行結果。可使用 * 字元來作為萬用字元。沒有被模擬的 Process 指令會被實際執行。可以使用 Process Facade 的 result 方法來為這些指令建立模擬的執行結果:

1Process::fake([
2 'cat *' => Process::result(
3 output: 'Test "cat" output',
4 ),
5 'ls *' => Process::result(
6 output: 'Test "ls" output',
7 ),
8]);
1Process::fake([
2 'cat *' => Process::result(
3 output: 'Test "cat" output',
4 ),
5 'ls *' => Process::result(
6 output: 'Test "ls" output',
7 ),
8]);

若不需要自定模擬 Process 的終止代碼或錯誤輸出,那麼使用字串來指定 Process 的模擬結果可能會更方便:

1Process::fake([
2 'cat *' => 'Test "cat" output',
3 'ls *' => 'Test "ls" output',
4]);
1Process::fake([
2 'cat *' => 'Test "cat" output',
3 'ls *' => 'Test "ls" output',
4]);

模擬 Process 序列

若要測試的程式碼會以相同指令來呼叫多個 Process,則可為各個 Process 呼叫指定不同的 Process 模擬執行結果。若要為各個 Process 呼叫設定各自的執行結果,請使用 Process Facade 的 sequence 方法:

1Process::fake([
2 'ls *' => Process::sequence()
3 ->push(Process::result('First invocation'))
4 ->push(Process::result('Second invocation')),
5]);
1Process::fake([
2 'ls *' => Process::sequence()
3 ->push(Process::result('First invocation'))
4 ->push(Process::result('Second invocation')),
5]);

模擬非同步 Process 的生命週期

到目前為止,我們主要針對使用 run 方法同步呼叫的 Process 討論要如何進行模擬。不過,若要測試的程式碼中有使用 start 來非同步呼叫 Process,就需要使用更複雜的方法來模擬 Process。

舉例來說,假設有下列 Route 會觸發非同步 Process:

1use Illuminate\Support\Facades\Log;
2use Illuminate\Support\Facades\Route;
3 
4Route::get('/import', function () {
5 $process = Process::start('bash import.sh');
6 
7 while ($process->running()) {
8 Log::info($process->latestOutput());
9 Log::info($process->latestErrorOutput());
10 }
11 
12 return 'Done';
13});
1use Illuminate\Support\Facades\Log;
2use Illuminate\Support\Facades\Route;
3 
4Route::get('/import', function () {
5 $process = Process::start('bash import.sh');
6 
7 while ($process->running()) {
8 Log::info($process->latestOutput());
9 Log::info($process->latestErrorOutput());
10 }
11 
12 return 'Done';
13});

若要正確模擬此 Process,我們需要能夠描述 running 方法要回傳幾次 true。此外,我們可能還需要指定要依序回傳的多行輸出。為此,我們可以使用 Process Facade 的 describe 方法:

1Process::fake([
2 'bash import.sh' => Process::describe()
3 ->output('First line of standard output')
4 ->errorOutput('First line of error output')
5 ->output('Second line of standard output')
6 ->exitCode(0)
7 ->iterations(3),
8]);
1Process::fake([
2 'bash import.sh' => Process::describe()
3 ->output('First line of standard output')
4 ->errorOutput('First line of error output')
5 ->output('Second line of standard output')
6 ->exitCode(0)
7 ->iterations(3),
8]);

讓我們來仔細看看上面的範例。使用 outputerrorOutput 方法,我們可以指定要依序回傳的多行輸出。exitCode 方法可用來指定模擬 Process 最終的終止代碼。最後,iterations 方法可用來指定 running 方法要回傳幾次 true

可用的 Assertion

就像剛才提到過的,Laravel 為功能測試 (Feature Test) 提供了多個 Process 的 Assertion(判斷提示)。我們會在接下來的部分討論這些 Assertion。

assertRan

判斷給定 Process 是否已被呼叫:

1use Illuminate\Support\Facades\Process;
2 
3Process::assertRan('ls -la');
1use Illuminate\Support\Facades\Process;
2 
3Process::assertRan('ls -la');

也可傳入一個 Closure 給 assertRun 方法。該 Closure 會收到 Process 的實體與 Process 的執行結果,讓你能檢查 Process 上的設定。若讓該 Closure 回傳 true,則該 Assertion 就會通過 (Pass):

1Process::assertRan(fn ($process, $result) =>
2 $process->command === 'ls -la' &&
3 $process->path === __DIR__ &&
4 $process->timeout === 60
5);
1Process::assertRan(fn ($process, $result) =>
2 $process->command === 'ls -la' &&
3 $process->path === __DIR__ &&
4 $process->timeout === 60
5);

傳給 assertRun Closure 的 $processIlluminate\Process\PendingProcess 的實體,而 $resultIlluminate\Contracts\Process\ProcessResult 的實體。

assertDidntRun

判斷給定 Process 是否未被呼叫:

1use Illuminate\Support\Facades\Process;
2 
3Process::assertDidntRun('ls -la');
1use Illuminate\Support\Facades\Process;
2 
3Process::assertDidntRun('ls -la');

assertRun 方法類似,assertDidntRun 方法也可被傳入一個 Closure。傳給 assertDidntRun 的 Closure 會收到 Process 實體與 Process 的執行結果,讓你能檢查 Process 上的設定。若該 Closure 回傳 true,則該 Assertion 就會失敗 (Fail):

1Process::assertDidntRun(fn (PendingProcess $process, ProcessResult $result) =>
2 $process->command === 'ls -la'
3);
1Process::assertDidntRun(fn (PendingProcess $process, ProcessResult $result) =>
2 $process->command === 'ls -la'
3);

assertRanTimes

判斷給定 Process 是否被呼叫了給定次數:

1use Illuminate\Support\Facades\Process;
2 
3Process::assertRanTimes('ls -la', times: 3);
1use Illuminate\Support\Facades\Process;
2 
3Process::assertRanTimes('ls -la', times: 3);

也可傳入一個 Closure 給 assertRanTimes 方法。該 Closure 會收到 Process 的實體與 Process 的執行結果,讓你能檢查 Process 上的設定。若讓該 Closure 回傳 true,且該 Process 被呼叫了給定的次數,則該 Assertion 就會通過 (Pass):

1Process::assertRanTimes(function (PendingProcess $process, ProcessResult $result) {
2 return $process->command === 'ls -la';
3}, times: 3);
1Process::assertRanTimes(function (PendingProcess $process, ProcessResult $result) {
2 return $process->command === 'ls -la';
3}, times: 3);

避免漏掉的 Process

若想在個別測試或整個測試套件中,確保所有呼叫的 Process 都被模擬,則可呼叫 preventStrayProcesses 方法。呼叫該方法後,若某個 Process 沒有相對應的模擬結果,該 Process 就不會被執行,而會擲回一個 Exception:

1use Illuminate\Support\Facades\Process;
2 
3Process::preventStrayProcesses();
4 
5Process::fake([
6 'ls *' => 'Test output...',
7]);
8 
9// Fake response is returned...
10Process::run('ls -la');
11 
12// An exception is thrown...
13Process::run('bash import.sh');
1use Illuminate\Support\Facades\Process;
2 
3Process::preventStrayProcesses();
4 
5Process::fake([
6 'ls *' => 'Test output...',
7]);
8 
9// Fake response is returned...
10Process::run('ls -la');
11 
12// An exception is thrown...
13Process::run('bash import.sh');
翻譯進度
54.44% 已翻譯
更新時間:
2024年6月30日 上午8:27: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.