メインコンテンツへスキップ
パッケージが ffmpeg や git などの外部コマンドを呼ぶと、利用アプリの環境差や失敗がそのままパッケージの挙動になります。shell_exec() や exec() を直接呼ぶのではなく、Process facade で実行し、テストでは Process::fake() で置き換えます。
このページはLaravel 13を対象に、Framework v13.42.0 の実装を確認しています。プロセスとパッケージのテストを前提とします。ここで扱う配列コマンドの照合は、Process内部で使われるSymfony Processの引数変換を前提にしています。

直接実行を避ける理由

直接の関数呼び出しは、テストで差し替えられず、タイムアウトや終了コードの扱いも呼び出し側ごとにばらつきます。Process facadeを挟むと、実行の記録、fake、タイムアウト、失敗時の例外を統一できます。

配列でコマンドを渡す

文字列のコマンドは sh の解釈を通るため、利用者の入力を含めると引用符の問題や注入の余地が生まれます。パッケージの内部では配列で引数を渡します。
PendingProcess の既定のタイムアウトは 60 秒、アイドルタイムアウトは null です。長時間の変換では timeout() で明示し、出力が止まる種類の処理では idleTimeout() を併用します。

失敗時の例外とメッセージ

ProcessResult::throw() は終了コードが成功でない場合に ProcessFailedException を投げます。メッセージには実行したコマンド、終了コード、標準出力と標準エラー出力が含まれます。
コマンドの引数に秘密情報を入れると、ProcessFailedException のメッセージに含まれて、ログや画面に出る可能性があります。トークンなどは引数にせず、env() で渡すか、コマンドの設定ファイルに書く方式を選びます。
タイムアウトは ProcessTimedOutException、アイドルタイムアウトは ProcessIdleTimedOutException で表されます。パッケージの利用者には、どの例外を投げるかと、捕まえたときに何を期待できるかを明記します。

テストでfakeする

テストでは Process::fake() で外部コマンドを置き換えます。Process::result() は標準出力、標準エラー、終了コードを指定できます。
assertRan() にクロージャを渡すと、PendingProcess の command、timeout、environment などを確認できます。配列コマンドは $process->command と完全一致で比較されるため、引数の順序や値の変更はテストで検出されます。

配列コマンドのfakeキー

Process内部では、fake() のキーを getCommandline() の結果と Str::is() で照合します。配列コマンドはシェル向けに引用符付きの文字列へ変換されるため、'ffmpeg*' のような文字列のパターンは一致しません。配列コマンドのテストでは次のいずれかを使います。

予期しない外部コマンドを防ぐ

テストで実行されるべきでない外部コマンドを検出するには、preventStrayProcesses() を使います。fakeに一致しないコマンドは RuntimeException になり、実際には起動しません。

注入されたFactoryを使う場合

パッケージのコンストラクタで Illuminate\Process\Factory を受け取る設計では、Process::fake() の状態が注入先まで届くかを確認します。Facadeは解決済みインスタンスをキャッシュし、swap() でコンテナのインスタンスを置き換えます。一方、Factory がコンテナで共有されるかは、フレームワークの明示的な登録に頼れないため、テストで実際に確認します。 注入先まで届かない場合は、テストでFactoryを明示的に差し替えるか、Process facadeを経由する設計にします。どちらの場合も、assertRan() で呼び出しが記録されたことを確認すると、差し替え漏れを検出できます。

長期保守で追加する検証

参照した一次情報

最終更新日 2026年11月13日